diff --git a/e2e/client/package.json b/e2e/client/package.json index d363f7a7ff..f2684e333c 100644 --- a/e2e/client/package.json +++ b/e2e/client/package.json @@ -19,7 +19,7 @@ "server": "grunt server", "start-client-server": "http-server dist -p 9000 -s &", "stop-client-server": "fuser -k 9000/tcp", - "protractor": "node run-end-to-end-tests.js", + "protractor": "protractor protractor.conf.js", "specs--compile": "find ./specs/ -name '*.js' -type f -delete && tsc -p ./specs", "specs--watch": "find ./specs/ -name '*.js' -type f -delete && tsc -p ./specs -w", "start-test-server": "cd ../server && docker-compose build && docker-compose up -d", diff --git a/e2e/client/run-end-to-end-tests.js b/e2e/client/run-end-to-end-tests.js deleted file mode 100644 index f0045a7da1..0000000000 --- a/e2e/client/run-end-to-end-tests.js +++ /dev/null @@ -1,46 +0,0 @@ -const execSync = require('child_process').execSync; - -function ensurePackageInstalled() { - return new Promise((resolve, reject) => { - try { - require.resolve('webdriver-manager'); - resolve(); - } catch (_) { - reject('Package "webdriver-manager" was not found. Run `yarn install` to install all packages.'); - } - }); -} - -function installWebdriverDriver() { - return new Promise((resolve, reject) => { - try { - require.resolve('webdriver-manager/selenium/update-config.json'); - resolve(); - } catch (_) { - // driver not installed, installing: - - const version = execSync('$CHROME_BIN --product-version').toString(); - - if (version == null) { - return reject('To launch the test server a chrome based browser has to be installed and CHROME_BIN environment variable set.'); - } - - console.info('Installing webdriver...', version); - execSync(`npx webdriver-manager update --gecko false --standalone false --versions.chrome=${version}`); - - resolve(); - } - }); -} - -ensurePackageInstalled() - .then(installWebdriverDriver) - .then(() => { - const argumentsToForward = process.argv.slice(2).join(' '); - - execSync(`npx protractor protractor.conf.js ${argumentsToForward}`, {stdio: 'inherit'}); - }) - .catch((e) => { - console.error(e); - process.exitCode = 1; - }); \ No newline at end of file diff --git a/e2e/client/specs/archived_spec.ts b/e2e/client/specs/archived_spec.ts index 9fb56996eb..1e228eca37 100644 --- a/e2e/client/specs/archived_spec.ts +++ b/e2e/client/specs/archived_spec.ts @@ -3,6 +3,7 @@ import {globalSearch} from './helpers/search'; import {authoring} from './helpers/authoring'; import {content} from './helpers/content'; import {monitoring} from './helpers/monitoring'; +import {element, by} from 'protractor'; describe('archived', () => { beforeEach(() => { @@ -31,7 +32,7 @@ describe('archived', () => { expect(authoring.edit_correct_button.isDisplayed()).toBe(false); expect(authoring.edit_kill_button.isDisplayed()).toBe(false); expect(authoring.edit_takedown_button.isDisplayed()).toBe(false); - expect(authoring.navbarMenuBtn.isPresent()).toBe(false); + expect(element(by.css('[data-test-id="content-create"]')).isPresent()).toBe(false); expect(authoring.sendToButton.isDisplayed()).toBe(false); authoring.showInfo(); expect(authoring.isPublishedState()).toBe(true); diff --git a/e2e/client/specs/authoring_spec.ts b/e2e/client/specs/authoring_spec.ts index 8f57fc7401..83dd4f3720 100644 --- a/e2e/client/specs/authoring_spec.ts +++ b/e2e/client/specs/authoring_spec.ts @@ -64,7 +64,9 @@ describe('authoring', () => { it('authoring operations', () => { // allows to create a new empty package - monitoring.createItemAction('create_package'); + el(['content-create']).click(); + el(['content-create-dropdown', 'create-package']).click(); + expect(element(by.className('packaging-screen')).isDisplayed()).toBe(true); authoring.close(); @@ -252,7 +254,13 @@ describe('authoring', () => { authoring.writeText('z'); element(by.cssContainingText('label', 'Dateline')).click(); ctrlShiftKey('s'); - browser.wait(() => element(by.buttonText('Save')).getAttribute('disabled'), 500); + + browser.wait(ECE.attributeEquals( + element(by.buttonText('Save')), + 'disabled', + 'true', + )); + authoring.close(); monitoring.actionOnItem('Edit', 2, 0); browser.sleep(300); @@ -322,16 +330,31 @@ describe('authoring', () => { it('toggle auto spellcheck and hold changes', () => { monitoring.actionOnItem('Edit', 2, 1); - browser.sleep(300); - expect(element(by.model('spellcheckMenu.isAuto')).getAttribute('checked')).toBeTruthy(); + + browser.wait(ECE.attributeEquals( + element(by.model('spellcheckMenu.isAuto')), + 'checked', + 'true', + )); + authoring.toggleAutoSpellCheck(); - browser.sleep(300); - expect(element(by.model('spellcheckMenu.isAuto')).getAttribute('checked')).toBeFalsy(); + + browser.wait(ECE.attributeEquals( + element(by.model('spellcheckMenu.isAuto')), + 'checked', + null, + )); + authoring.close(); + monitoring.actionOnItem('Edit', 2, 2); - expect(element(by.model('spellcheckMenu.isAuto')).getAttribute('checked')).toBeFalsy(); - }); + browser.wait(ECE.attributeEquals( + element(by.model('spellcheckMenu.isAuto')), + 'checked', + null, + )); + }); it('related item widget', () => { monitoring.actionOnItem('Edit', 2, 1); authoring.writeText('something'); diff --git a/e2e/client/specs/content_profile_spec.ts b/e2e/client/specs/content_profile_spec.ts index e99710e163..f52735ada0 100644 --- a/e2e/client/specs/content_profile_spec.ts +++ b/e2e/client/specs/content_profile_spec.ts @@ -7,6 +7,7 @@ import {workspace} from './helpers/workspace'; import {authoring} from './helpers/authoring'; import {metadata} from './helpers/metadata'; import {assertToastMsg} from './helpers/utils'; +import {ECE} from '@superdesk/end-to-end-testing-helpers'; describe('Content profiles', () => { it('creates corresponding template', () => { @@ -19,7 +20,6 @@ describe('Content profiles', () => { templates.openTemplatesSettings(); expect(templates.getListCount()).toBeGreaterThan(2); templates.edit('Simple'); - expect(authoring.getAbstractFieldCount()).toEqual(0); expect(templates.getContentProfile()).toEqual('Simple'); templates.cancel(); @@ -57,7 +57,6 @@ describe('Content profiles', () => { monitoring.openMonitoring(); workspace.selectDesk('Sports Desk'); authoring.createTextItemFromTemplate('simple'); - expect(authoring.getAbstractFieldCount()).toEqual(0); // publish of the required field will fail authoring.setHeaderSluglineText('Story1 slugline'); @@ -89,12 +88,12 @@ describe('Content profiles', () => { contentProfiles.editContentFields(); - const btns = element.all(by.partialButtonText(FIELD_LABEL)); + const buttons = element.all(by.partialButtonText(FIELD_LABEL)); - expect(btns.filter((elem) => elem.isDisplayed()).count()).toBe(0); + browser.wait(ECE.hasElementCount(buttons, 0)); contentProfiles.openAddFieldDropdown(); - expect(btns.filter((elem) => elem.isDisplayed()).count()).toBe(1); + browser.wait(ECE.hasElementCount(buttons, 1)); }); }); diff --git a/e2e/client/specs/content_spec.ts b/e2e/client/specs/content_spec.ts index 7b8a5d255f..91c14a0026 100644 --- a/e2e/client/specs/content_spec.ts +++ b/e2e/client/specs/content_spec.ts @@ -7,6 +7,7 @@ import {content} from './helpers/content'; import {authoring} from './helpers/authoring'; import {multiAction} from './helpers/actions'; import {ECE, el} from '@superdesk/end-to-end-testing-helpers'; +import {TreeSelectDriver} from './helpers/tree-select-driver'; describe('content', () => { var body = element(by.tagName('body')); @@ -33,8 +34,8 @@ describe('content', () => { var embargoTime = (now.getHours() < 10 ? '0' + now.getHours() : now.getHours()) + ':' + (now.getMinutes() < 10 ? '0' + now.getMinutes() : now.getMinutes()); - element(by.model('item.embargo_date')).element(by.tagName('input')).sendKeys(embargoDate); - element(by.model('item.embargo_time')).element(by.tagName('input')).sendKeys(embargoTime); + el(['authoring', 'interactive-actions-panel', 'embargo', 'date-input']).sendKeys(embargoDate); + el(['authoring', 'interactive-actions-panel', 'embargo', 'time-input']).sendKeys(embargoTime); } it('can navigate with keyboard', () => { @@ -141,7 +142,7 @@ describe('content', () => { browser.sleep(100); - multiAction('Multiedit'); + multiAction('Multi-edit'); expect(browser.getCurrentUrl()).toMatch(/multiedit$/); expect(element.all(by.repeater('board in boards')).count()).toBe(2); }); @@ -150,8 +151,7 @@ describe('content', () => { workspace.switchToDesk('SPORTS DESK'); content.setListView(); - element(by.className('sd-create-btn')).click(); - element(by.id('create_text_article')).click(); + authoring.createTextItem(); authoring.writeText('Words'); authoring.save(); @@ -164,8 +164,8 @@ describe('content', () => { workspace.switchToDesk('SPORTS DESK'); content.setListView(); - element(by.className('sd-create-btn')).click(); - element(by.id('create_package')).click(); + el(['content-create']).click(); + el(['content-create-dropdown', 'create-package']).click(); element.all(by.model('item.headline')).first().sendKeys('Empty Package'); authoring.save(); @@ -220,10 +220,10 @@ describe('content', () => { it('can display embargo in metadata when set', () => { workspace.editItem('item3', 'SPORTS'); - authoring.sendToButton.click(); + + el(['open-send-publish-pane']).click(); setEmbargo(); - browser.sleep(100); authoring.closeSendAndPublish(); @@ -238,37 +238,46 @@ describe('content', () => { content.closePreview(); }); - it('can enable/disable send based on embargo', () => { + it('can set embargo and send', () => { // Initial steps before proceeding, to get initial state of send buttons. workspace.editItem('item3', 'SPORTS'); authoring.sendTo('Sports Desk', 'Incoming Stage'); authoring.confirmSendTo(); workspace.editItem('item3', 'SPORTS'); - authoring.sendToButton.click().then(() => { - // Initial State - expect(authoring.sendBtn.isEnabled()).toBe(false); - }); - var sidebar = element.all(by.css('.side-panel')).last(), - dropdown = sidebar.element(by.css('.dropdown--boxed .dropdown__toggle')); + el(['open-send-publish-pane']).click(); + + el(['authoring', 'interactive-actions-panel', 'tabs'], by.buttonText('Send to')).click(); + + const sendToButton = el(['authoring', 'interactive-actions-panel', 'send']); - dropdown.waitReady(); - dropdown.click(); - sidebar.element(by.buttonText('Sports Desk')).click(); + browser.wait(ECE.visibilityOf(sendToButton)); + + new TreeSelectDriver( + el(['interactive-actions-panel', 'destination-select']), + ).setValue('Sports Desk'); + + const stage = 'two'; // State after selecting different Stage in the same desk - sidebar.element(by.buttonText('two')).click(); - expect(authoring.sendBtn.isEnabled()).toBe(true); + el( + ['interactive-actions-panel', 'stage-select'], + by.cssContainingText('[data-test-id="item"]', stage), + ).click(); + + expect(sendToButton.isEnabled()).toBe(true); // State after setting Embargo setEmbargo(); browser.sleep(100); - expect(authoring.sendBtn.isEnabled()).toBe(true); + expect(sendToButton.isEnabled()).toBe(true); // State after changing Desk - dropdown.click(); - sidebar.element(by.buttonText('Politic Desk')).click(); - expect(authoring.sendBtn.isEnabled()).toBe(true); + new TreeSelectDriver( + el(['interactive-actions-panel', 'destination-select']), + ).setValue('Politic Desk'); + + expect(sendToButton.isEnabled()).toBe(true); }); }); diff --git a/e2e/client/specs/fetch_spec.ts b/e2e/client/specs/fetch_spec.ts index 7c909be33f..8d0650f671 100644 --- a/e2e/client/specs/fetch_spec.ts +++ b/e2e/client/specs/fetch_spec.ts @@ -5,7 +5,7 @@ import {content} from './helpers/content'; import {authoring} from './helpers/authoring'; import {desks} from './helpers/desks'; import {multiAction} from './helpers/actions'; -import {ECE, els} from '@superdesk/end-to-end-testing-helpers'; +import {ECE, el, els, s} from '@superdesk/end-to-end-testing-helpers'; describe('fetch', () => { beforeEach(() => { @@ -31,7 +31,7 @@ describe('fetch', () => { it('can fetch as', () => { workspace.openIngest(); content.actionOnItem('Fetch To', 0); - content.send(); + el(['interactive-actions-panel', 'fetch']).click(); workspace.openContent(); expect(content.count()).toBe(3); }); @@ -46,9 +46,9 @@ describe('fetch', () => { workspace.openIngest(); content.actionOnItem('Fetch To', 0); - var btnFetchAndOpen = element(by.css('[ng-disabled="disableFetchAndOpenButton()"]')); + var btnFetchAndOpen = element(s(['interactive-actions-panel', 'fetch-and-open'])); - expect(btnFetchAndOpen.getAttribute('disabled')).toBeFalsy(); + expect(btnFetchAndOpen.isEnabled()).toBe(true); // Adding a new desk with no member, which serves as a non-member desk when selected desks.openDesksSettings(); @@ -59,21 +59,32 @@ describe('fetch', () => { desks.setDeskType('authoring'); desks.setDeskDefaultContentTemplate('testing'); desks.setDeskDefaultContentProfile('testing'); - desks.actionDoneOnGeneralTab(); + desks.actionSaveAndContinueOnGeneralTab(); // save desk and continue to Stages tab + + desks.editStage('Working Stage'); + desks.toggleGlobalReadFlag(); // turn OFF Global Read + desks.saveEditedStage(); + + desks.editStage('Incoming Stage'); + desks.toggleGlobalReadFlag(); // turn OFF Global Read + desks.saveEditedStage(); + + desks.actionDoneOnStagesTab(); workspace.openIngest(); content.actionOnItem('Fetch To', 0); authoring.selectDeskforSendTo('Test Desk'); - expect(btnFetchAndOpen.getAttribute('disabled')).toBeTruthy(); + + expect(btnFetchAndOpen.isEnabled()).toBe(false); }); it('can hide stage with global read OFF if selected desk as a non-member', () => { workspace.openIngest(); content.actionOnItem('Fetch To', 0); - var btnFetchAndOpen = element(by.css('[ng-disabled="disableFetchAndOpenButton()"]')); + var btnFetchAndOpen = element(s(['interactive-actions-panel', 'fetch-and-open'])); - expect(btnFetchAndOpen.getAttribute('disabled')).toBeFalsy(); + expect(btnFetchAndOpen.isEnabled()).toBe(true); // Adding a new desk with no member, which serves as a non-member desk when selected desks.openDesksSettings(); @@ -106,11 +117,12 @@ describe('fetch', () => { content.actionOnItem('Fetch To', 0); authoring.selectDeskforSendTo('Test Desk'); - var sidebar = element.all(by.css('.side-panel')).last(); - - expect(sidebar.element(by.buttonText('Working Stage')).isPresent()).toBeTruthy(); - expect(sidebar.element(by.buttonText('Test Stage')).isPresent()).toBeFalsy(); - expect(btnFetchAndOpen.getAttribute('disabled')).toBeTruthy(); + expect( + element(s(['interactive-actions-panel', 'stage-select', 'item'], 'Working Stage')).isPresent(), + ).toBeTruthy(); + expect( + element(s(['interactive-actions-panel', 'stage-select', 'item'], 'Test Stage')).isPresent(), + ).toBeFalsy(); }); it('can fetch multiple items', () => { @@ -127,7 +139,7 @@ describe('fetch', () => { content.selectItem(0); browser.sleep(1000); // Wait for animation multiAction('Fetch to'); - content.send(); + el(['interactive-actions-panel', 'fetch']).click(); workspace.openContent(); expect(content.count()).toBe(3); }); diff --git a/e2e/client/specs/helpers/authoring.ts b/e2e/client/specs/helpers/authoring.ts index d87977be8f..3af555241e 100644 --- a/e2e/client/specs/helpers/authoring.ts +++ b/e2e/client/specs/helpers/authoring.ts @@ -3,10 +3,11 @@ import {element, by, browser, protractor} from 'protractor'; import {waitHidden, waitFor, click} from './utils'; import {ECE, els, el} from '@superdesk/end-to-end-testing-helpers'; +import {PLAIN_TEXT_TEMPLATE_NAME} from './constants'; +import {TreeSelectDriver} from './tree-select-driver'; class Authoring { lock: any; - publish_button: any; correct_button: any; kill_button: any; close_button: any; @@ -20,27 +21,21 @@ class Authoring { edit_correct_button: any; edit_kill_button: any; edit_takedown_button: any; - navbarMenuBtn: any; - newPlainArticleLink: any; newEmptyPackageLink: any; infoIconsBox: any; sendToButton: any; - sendAndContinueBtn: any; sendAndPublishBtn: any; - sendBtn: any; moreActionsButton: any; multieditButton: any; compareVersionsMenuItem: any; setCategoryBtn: any; getCategoryListItems: any; - sendItemContainer: any; linkToMasterButton: any; marked_for_legal: any; sms: any; anpa_category: any; subject: any; missing_link: any; - publish_panel: any; send_panel: any; fetch_panel: any; headline: any; @@ -67,9 +62,7 @@ class Authoring { ignore: () => any; savePublish: () => any; publish: (skipConfirm?: any) => void; - sendAndpublish: (desk: any, skipConfirm?: any) => void; closeSendAndPublish: () => any; - publishFrom: (desk: any) => void; schedule: (skipConfirm?: any) => void; correct: () => any; save: () => any; @@ -180,10 +173,10 @@ class Authoring { openCompareVersionsInnerDropdown: (index: any) => void; getInnerDropdownItemVersions: (index: any) => any; openItemVersionInBoard: (board: any, index: any) => void; + createPlainTextArticle: () => void; constructor() { this.lock = element(by.css('[ng-click="lock()"]')); - this.publish_button = element(by.buttonText('publish')); this.correct_button = element(by.buttonText('correct')); this.kill_button = element(by.buttonText('kill')); this.close_button = element(by.buttonText('Close')); @@ -198,15 +191,11 @@ class Authoring { this.edit_kill_button = element(by.css('[title="Kill"]')); this.edit_takedown_button = element(by.css('[title="Takedown"]')); - this.navbarMenuBtn = element(by.css('.dropdown__toggle.sd-create-btn')); - this.newPlainArticleLink = element(by.id('create_text_article')); this.newEmptyPackageLink = element(by.id('create_package')); this.infoIconsBox = element(by.css('.info-icons')); this.sendToButton = element(by.id('send-to-btn')); - this.sendAndContinueBtn = element(by.buttonText('send and continue')); this.sendAndPublishBtn = element(by.buttonText('publish from')); - this.sendBtn = element(by.buttonText('send')); this.moreActionsButton = element(by.id('more-actions')); @@ -219,7 +208,6 @@ class Authoring { this.getCategoryListItems = element(by.id('category-setting')) .all(el(['dropdown__item']).locator()); - this.sendItemContainer = element(by.id('send-item-container')); this.linkToMasterButton = element(by.id('preview-master')); this.marked_for_legal = element(by.model('item.flags.marked_for_legal')); this.sms = element(by.model('item.flags.marked_for_sms')); @@ -227,7 +215,6 @@ class Authoring { .all(by.css('[data-field="anpa_category"]')); this.subject = element(by.className('authoring-header__detailed')).all(by.css('[data-field="subject"]')); this.missing_link = element(by.className('missing-link')); - this.publish_panel = element(by.css('#panel-publish:not(.ng-hide)')); this.send_panel = element(by.css('#panel-send:not(.ng-hide)')); this.fetch_panel = element(by.css('#panel-fetch:not(.ng-hide)')); this.headline = element(by.css('.headline [contenteditable]')); @@ -280,8 +267,8 @@ class Authoring { var embargoDate = '09/09/' + ((new Date()).getFullYear() + 1); var embargoTime = '04:00'; - element(by.model('item.embargo_date')).element(by.tagName('input')).sendKeys(embargoDate); - element(by.model('item.embargo_time')).element(by.tagName('input')).sendKeys(embargoTime); + el(['authoring', 'interactive-actions-panel', 'embargo', 'date-input']).sendKeys(embargoDate); + el(['authoring', 'interactive-actions-panel', 'embargo', 'time-input']).sendKeys(embargoTime); }; this.confirmSendTo = function() { @@ -293,62 +280,55 @@ class Authoring { }; this.sendToSidebarOpened = function(desk, stage, _continue) { - browser.wait(ECE.elementToBeClickable(this.send_panel)); - this.send_panel.click(); + el(['interactive-actions-panel', 'tabs'], by.buttonText('Send to')).click(); - var sidebar = element.all(by.css('.side-panel')).last(), - dropdown = sidebar.element(by.css('.dropdown--boxed .dropdown__toggle')); + new TreeSelectDriver( + el(['interactive-actions-panel', 'destination-select']), + ).setValue(desk); - dropdown.waitReady(); - dropdown.click(); - sidebar.element(by.buttonText(desk)).click(); if (stage) { - sidebar.element(by.buttonText(stage)).click(); + el( + ['interactive-actions-panel', 'stage-select'], + by.cssContainingText('[data-test-id="item"]', stage), + ).click(); } if (_continue) { - this.sendAndContinueBtn.click(); + el(['interactive-actions-panel', 'send-and-open']).click(); } else { - this.sendBtn.click(); + el(['interactive-actions-panel', 'send']).click(); } }; this.duplicateTo = (desk, stage, open) => { - let duplicateButton = element(by.id('duplicate-btn')); - let duplicateAndOpenButton = element(by.id('duplicate-open-btn')); + new TreeSelectDriver( + el(['interactive-actions-panel', 'destination-select']), + ).setValue(desk); - var sidebar = element.all(by.css('.side-panel')).last(), - dropdown = sidebar.element(by.css('.dropdown--boxed .dropdown__toggle')); - - dropdown.waitReady(); - dropdown.click(); - sidebar.element(by.buttonText(desk)).click(); if (stage) { - sidebar.element(by.buttonText(stage)).click(); + el( + ['interactive-actions-panel', 'stage-select'], + by.cssContainingText('[data-test-id="item"]', stage), + ).click(); } if (open) { - duplicateAndOpenButton.click(); + el(['interactive-actions-panel', 'duplicate-and-open']).click(); } else { - duplicateButton.click(); + el(['interactive-actions-panel', 'duplicate']).click(); } }; this.selectDeskforSendTo = function(desk) { - var sidebar = element.all(by.css('.side-panel')).last(), - dropdown = element(by.css('.dropdown--boxed .dropdown__toggle')); - - dropdown.waitReady(); - dropdown.click(); - sidebar.element(by.buttonText(desk)).click(); + new TreeSelectDriver( + el(['interactive-actions-panel', 'destination-select']), + ).setValue(desk); }; this.markAction = function() { return element(by.className('svg-icon-add-to-list')).click(); }; - this.createTextItem = function() { - return element(by.className('sd-create-btn')) - .click() - .then(() => element(by.id('create_text_article')).click()); + this.createTextItem = () => { + this.createTextItemFromTemplate(PLAIN_TEXT_TEMPLATE_NAME); }; /** @@ -357,13 +337,11 @@ class Authoring { * @param {String} name */ this.createTextItemFromTemplate = (name) => { - element(by.className('sd-create-btn')).click(); - element(by.id('more_templates')).click(); - let templates = element.all(by.repeater('template in templates track by template._id')); - - templates.all(by.css('[ng-click="select({template: template})"]')) - .filter((elem) => elem.getText().then((text) => text.toUpperCase().indexOf(name.toUpperCase()) > -1)) - .click(); + el(['content-create']).click(); + el(['content-create-dropdown'], by.buttonText('More templates...')).click(); + el(['content-create-dropdown', 'search']).sendKeys(name); + el(['content-create-dropdown'], by.buttonText(name)).click(); + browser.wait(ECE.presenceOf(el(['authoring']))); }; this.close = function() { @@ -423,40 +401,8 @@ class Authoring { }; this.publish = function(skipConfirm) { - browser.wait(() => this.sendToButton.isPresent(), 1000); - this.sendToButton.click(); - - browser.wait(() => this.publish_panel.isPresent(), 3000); - - this.publish_panel.click(); - - browser.wait(() => this.publish_button.isPresent(), 3000); - - this.publish_panel.click(); - this.publish_button.click(); - - if (!skipConfirm) { - var modal = element(by.className('modal__dialog')); - - modal.isPresent().then((isPresent) => { - if (isPresent) { - modal.element(by.className('btn--primary')).click(); - } - }); - } - }; - - this.sendAndpublish = function(desk, skipConfirm) { - browser.wait(() => this.sendToButton.isPresent(), 1000); - this.sendToButton.click(); - - this.publish_panel.click(); - - browser.wait(() => this.publish_button.isPresent(), 1000); - - this.publish_panel.click(); - this.selectDeskforSendTo(desk); - this.sendAndPublishBtn.click(); + el(['authoring', 'open-send-publish-pane']).click(); + el(['authoring', 'interactive-actions-panel', 'publish']).click(); if (!skipConfirm) { var modal = element(by.className('modal__dialog')); @@ -470,17 +416,7 @@ class Authoring { }; this.closeSendAndPublish = function() { - var sidebar = element.all(by.css('.side-panel')).last(); - - return sidebar.element(by.css('[ng-click="close()"]')).click(); - }; - - this.publishFrom = function(desk) { - this.publish_panel.click(); - - browser.wait(() => this.publish_panel.isPresent(), 2000); - this.selectDeskforSendTo(desk); - this.sendAndPublishBtn.click(); + el(['authoring', 'interactive-actions-panel', 'close']).click(); }; this.schedule = function(skipConfirm) { @@ -490,14 +426,10 @@ class Authoring { var scheduleDate = '09/09/' + ((new Date()).getFullYear() + 1); var scheduleTime = '04:00'; - element(by.model('item.publish_schedule_date')).element(by.tagName('input')).sendKeys(scheduleDate); - element(by.model('item.publish_schedule_time')).element(by.tagName('input')).sendKeys(scheduleTime); - - this.publish_panel.click(); - - browser.wait(() => this.publish_button.isPresent(), 1000); + el(['authoring', 'interactive-actions-panel', 'publish-schedule', 'date-input']).sendKeys(scheduleDate); + el(['authoring', 'interactive-actions-panel', 'publish-schedule', 'time-input']).sendKeys(scheduleTime); - this.publish_button.click(); + el(['authoring', 'interactive-actions-panel', 'publish']).click(); if (!skipConfirm) { var modal = element(by.className('modal__dialog')); diff --git a/e2e/client/specs/helpers/constants.ts b/e2e/client/specs/helpers/constants.ts new file mode 100644 index 0000000000..fd2eec0ef5 --- /dev/null +++ b/e2e/client/specs/helpers/constants.ts @@ -0,0 +1 @@ +export const PLAIN_TEXT_TEMPLATE_NAME = 'plain text'; diff --git a/e2e/client/specs/helpers/content.ts b/e2e/client/specs/helpers/content.ts index 11cc465480..935ac47474 100644 --- a/e2e/client/specs/helpers/content.ts +++ b/e2e/client/specs/helpers/content.ts @@ -162,7 +162,7 @@ class Content { this.unspikeItems = function() { multiAction('Unspike'); - element(by.buttonText('send')).click(); + el(['interactive-actions-panel', 'unspike']).click(); }; this.selectSpikedList = function() { diff --git a/e2e/client/specs/helpers/monitoring.ts b/e2e/client/specs/helpers/monitoring.ts index f20358ff7c..4cd5f76cad 100644 --- a/e2e/client/specs/helpers/monitoring.ts +++ b/e2e/client/specs/helpers/monitoring.ts @@ -17,7 +17,6 @@ class Monitoring { showSpiked: () => void; showPersonal: () => void; showSearch: () => void; - createItemAction: (action: any) => void; createFromDeskTemplate: () => any; getGroup: (group: number) => any; getGroups: () => any; @@ -60,7 +59,7 @@ class Monitoring { selectGivenItem: (item: any) => any; spikeMultipleItems: () => void; unspikeMultipleItems: any; - unspikeItem: (item, stage?: string) => wdpromise.Promise; + unspikeItem: (item, stage?: string) => void; openItemMenu: (group: any, item: any) => ElementFinder; showMonitoringSettings: () => void; setLabel: (label: any) => void; @@ -98,7 +97,6 @@ class Monitoring { openSendMenu: () => void; publish: () => void; getPublishButtonText: any; - startUpload: () => void; uploadModal: ElementFinder; openFetchAsOptions: (group: any, item: any) => void; clickOnFetchButton: any; @@ -123,7 +121,6 @@ class Monitoring { searchInput: ElementFinder; getCorrectionItems: (group: any) => any; getTakeItems: (group: any) => any; - getSendToDropdown: () => ElementFinder; getPackageItem: (index: any) => ElementFinder; getPackageItemActionDropdown: (index: any) => ElementFinder; getPackageItemLabelEntry: () => ElementFinder; @@ -162,22 +159,13 @@ class Monitoring { el(['workspace-navigation'], by.css('[aria-label="Search"]')).click(); }; - /** - * On monitoring view create a new item - * - * @param {string} action - the create item action can be: create_text_article, - * create_preformatted_article and create_package - */ - this.createItemAction = function(action) { - element(by.className('icon-plus-large')).click(); - element(by.id(action)).click(); - browser.sleep(500); - }; - /** * Create new item using desk template */ - this.createFromDeskTemplate = () => this.createItemAction('create_text_article'); + this.createFromDeskTemplate = () => { + el(['content-create']).click(); + el(['content-create-dropdown', 'default-desk-template']).click(); + }; this.getGroup = function(group: number) { return this.getGroups().get(group); @@ -187,7 +175,7 @@ class Monitoring { const groups = element.all(by.repeater('group in aggregate.groups')); browser.sleep(3000); // due to debouncing, loading does not start immediately - browser.wait(ECE.hasElementCount(els(['item-list--loading']), 0), 2000); + browser.wait(ECE.hasElementCount(els(['item-list--loading']), 0), 3000); return groups; }; @@ -512,19 +500,20 @@ class Monitoring { this.unspikeMultipleItems = function() { multiAction('Unspike'); - return element(by.buttonText('send')).click(); + el(['interactive-actions-panel', 'unspike']).click(); }; this.unspikeItem = function(item, stage?: string) { articleList.executeContextMenuAction(this.getSpikedItem(item), 'Unspike Item'); - var sidebar = element.all(by.css('.side-panel')).last(); - if (stage) { - sidebar.element(by.buttonText(stage)).click(); + el( + ['interactive-actions-panel', 'stage-select'], + by.cssContainingText('[data-test-id="item"]', stage), + ).click(); } - return element(by.buttonText('send')).click(); + el(['interactive-actions-panel', 'unspike']).click(); }; this.openItemMenu = function(group, item) { @@ -539,7 +528,7 @@ class Monitoring { }; this.showMonitoringSettings = function() { - element(by.css('.icon-settings')).click(); + el(['monitoring-settings-button']).click(); browser.wait(() => element.all(by.css('.aggregate-widget-config')).isDisplayed()); element.all(by.css('[ng-click="goTo(step)"]')).first().click(); }; @@ -717,7 +706,7 @@ class Monitoring { }; this.openCreateMenu = function() { - element(by.className('sd-create-btn')).click(); + element(by.css('[data-test-id="content-create"]')).click(); browser.sleep(100); }; @@ -733,10 +722,6 @@ class Monitoring { this.getPublishButtonText = () => element(by.css('[ng-click="publish()"]')).getText(); - this.startUpload = function() { - element(by.id('start-upload-btn')).click(); - }; - this.uploadModal = element(by.className('upload-media')); this.openFetchAsOptions = function(group, item) { @@ -744,7 +729,7 @@ class Monitoring { }; this.clickOnFetchButton = function() { - return element(by.css('[ng-click="send()"]')).click(); + el(['interactive-actions-panel', 'fetch']).click(); }; // Cancel button resets the multi selection @@ -763,7 +748,7 @@ class Monitoring { this.fetchAndOpen = function(group, item) { this.actionOnItem('Fetch To', group, item); - return element(by.css('[ng-click="send(true)"]')).click(); + el(['interactive-actions-panel', 'fetch-and-open']).click(); }; /** @@ -976,18 +961,6 @@ class Monitoring { return this.getGroupItems(group).all(by.className('takekey')); }; - /** - * Returns the desk dropdown in send to panel - * - */ - this.getSendToDropdown = () => { - var sidebar = element.all(by.css('.side-panel')).last(), - dropdown = sidebar.element(by.css('.dropdown--boxed .dropdown__toggle')), - dropdownSelected = dropdown.element(by.css('[ng-show="selectedDesk"]')); - - return dropdownSelected; - }; - this.getPackageItem = function(index) { var elemIndex = index ? index : 0; diff --git a/e2e/client/specs/helpers/search.ts b/e2e/client/specs/helpers/search.ts index 08b972c092..ae0b6bfe16 100644 --- a/e2e/client/specs/helpers/search.ts +++ b/e2e/client/specs/helpers/search.ts @@ -149,7 +149,8 @@ class GlobalSearch { itemElem.click(); - browser.wait(() => itemElem.getAttribute('class').then((classes) => classes.includes('active')), 500); + browser.wait(ECE.attributeContains(itemElem, 'class', 'active')); + browser.sleep(350); // there is timeout on click }; @@ -181,7 +182,7 @@ class GlobalSearch { browser.sleep(100); const btn = itemElem.element(by.className('icn-btn')); - browser.wait(ECE.elementToBeClickable(btn), 1000); + browser.wait(ECE.elementToBeClickable(btn)); btn.click(); const menu = element(by.css('.dropdown__menu.open')); diff --git a/e2e/client/specs/helpers/tree-select-driver.ts b/e2e/client/specs/helpers/tree-select-driver.ts new file mode 100644 index 0000000000..d5fb74b211 --- /dev/null +++ b/e2e/client/specs/helpers/tree-select-driver.ts @@ -0,0 +1,51 @@ +import {by, element, ElementFinder, promise, protractor} from 'protractor'; +import {el, els, s} from '@superdesk/end-to-end-testing-helpers'; + +export class TreeSelectDriver { + private _element: ElementFinder; + + constructor(_element: ElementFinder) { + this._element = _element; + + this.getValue = this.getValue.bind(this); + this.addValue = this.addValue.bind(this); + this.setValue = this.setValue.bind(this); + } + + getValue(): promise.Promise> { + return els(['item'], null, this._element).then((elements) => { + return protractor.promise.all( + elements.map((_el: ElementFinder) => { + return _el.getAttribute('innerText'); + }), + ); + }); + } + + addValue(value: string | Array): void { + el(['open-popover'], null, this._element).click(); + + const values = typeof value === 'string' ? [value] : value; + + for (let i = 0; i < values.length; i++) { + element( + by.cssContainingText( + '[data-test-id="tree-select-popover"] [data-test-id="option"]', + values[i], + ), + ).click(); + } + } + + setValue(value: string | Array) { + const maybeClearButton = this._element.element(s(['clear-value'])); + + maybeClearButton.isPresent().then((present) => { + if (present === true) { + maybeClearButton.click(); + } + }); + + this.addValue(value); + } +} diff --git a/e2e/client/specs/helpers/utils.ts b/e2e/client/specs/helpers/utils.ts index e24adcebe7..f3725748c0 100644 --- a/e2e/client/specs/helpers/utils.ts +++ b/e2e/client/specs/helpers/utils.ts @@ -179,13 +179,6 @@ export function altKey(key) { export function assertToastMsg(type: 'info' | 'success' | 'error', msg: string) { const elem = element(s([`notification--${type}`], msg)); - click(elem); - - /** - * It seems there's an issue with protractor: - * Clicking an element throws `StaleElementReferenceError` when clicked immediately - * after waiting until it's clickable. - */ elem.isPresent().then((present) => { // Only click if the toast is still present. if (present) { diff --git a/e2e/client/specs/legal_archive_spec.ts b/e2e/client/specs/legal_archive_spec.ts index fd0ae6f285..5ccf09f610 100644 --- a/e2e/client/specs/legal_archive_spec.ts +++ b/e2e/client/specs/legal_archive_spec.ts @@ -79,7 +79,7 @@ describe('legal_archive', () => { expect(authoring.edit_button.isPresent()).toBe(false); expect(authoring.edit_correct_button.isPresent()).toBe(false); expect(authoring.edit_kill_button.isPresent()).toBe(false); - expect(authoring.navbarMenuBtn.isPresent()).toBe(false); + expect(element(by.css('[data-test-id="content-create"]')).isPresent()).toBe(false); expect(authoring.sendToButton.isDisplayed()).toBe(false); authoring.showInfo(); diff --git a/e2e/client/specs/monitoring_spec.ts b/e2e/client/specs/monitoring_spec.ts index 450c97e7ea..ece9da142e 100644 --- a/e2e/client/specs/monitoring_spec.ts +++ b/e2e/client/specs/monitoring_spec.ts @@ -1,19 +1,19 @@ /* eslint-disable newline-per-chained-call */ -import {element, browser, by, protractor, WebElementPromise, ElementFinder} from 'protractor'; +import {element, browser, by, protractor, ElementFinder} from 'protractor'; import {monitoring} from './helpers/monitoring'; import {workspace} from './helpers/workspace'; import {authoring} from './helpers/authoring'; import {dashboard} from './helpers/dashboard'; +import {TreeSelectDriver} from './helpers/tree-select-driver'; import {desks} from './helpers/desks'; import {el, s, els, ECE, articleList, getFocusedElement} from '@superdesk/end-to-end-testing-helpers'; import {nav} from './helpers/utils'; function createItem(headline: string) { - el(['content-create']).click(); - el(['content-create-dropdown']).element(by.buttonText('More templates...')).click(); - el(['select-template'], by.buttonText('editor3 template')).click(); + authoring.createTextItemFromTemplate('editor3 template'); + browser.wait(ECE.visibilityOf(element(s(['authoring'])))); el(['authoring', 'field--headline'], by.css('[contenteditable]')).sendKeys(headline); @@ -249,7 +249,6 @@ describe('monitoring', () => { it('configure a saved search from other user', () => { monitoring.openMonitoring(); workspace.createWorkspace('My Workspace'); - browser.sleep(500); monitoring.showMonitoringSettings(); monitoring.nextStages(); monitoring.toggleGlobalSearch(3); @@ -406,7 +405,7 @@ describe('monitoring', () => { authoring.close(); browser.wait(ECE.hasElementCount(els(['article-item']), 3), 2000); el(['content-profile-dropdown']).click(); - browser.wait(ECE.hasElementCount(els(['content-profiles']), 2)); + browser.wait(ECE.hasElementCount(els(['content-profiles']), 3)); el(['content-profile-dropdown'], by.buttonText('testing')).click(); browser.wait(ECE.hasElementCount(els(['article-item']), 1)); expect(monitoring.getTextItemBySlugline(0, 0)).toBe('TESTING1 SLUGLINE'); @@ -421,7 +420,7 @@ describe('monitoring', () => { expect(monitoring.getTextItem(4, 0)).toBe('item4'); el(['content-profile-dropdown']).click(); - browser.wait(ECE.hasElementCount(els(['content-profiles']), 2)); + browser.wait(ECE.hasElementCount(els(['content-profiles']), 3)); el(['content-profile-dropdown'], by.buttonText('testing')).click(); browser.wait(ECE.hasElementCount(els(['article-item']), 1), 2000); expect(monitoring.getTextItemBySlugline(0, 0)).toBe('TESTING1 SLUGLINE'); @@ -473,8 +472,10 @@ describe('monitoring', () => { it('can start content upload', () => { monitoring.openMonitoring(); - monitoring.openCreateMenu(); - monitoring.startUpload(); + + el(['content-create']).click(); + el(['content-create-dropdown', 'upload-media']).click(); + expect(monitoring.uploadModal.isDisplayed()).toBeTruthy(); }); @@ -667,7 +668,7 @@ describe('monitoring', () => { monitoring.fetchAndOpen(0, 5); - expect(authoring.save_button.isDisplayed()).toBe(true); + browser.wait(ECE.visibilityOf(authoring.save_button)); }); it('can display desk content in desk single view with their respective titles', () => { @@ -773,7 +774,6 @@ describe('monitoring', () => { monitoring.saveSettings(); monitoring.openMonitoring(); - browser.sleep(3000); // wait for monitoring groups to load expect(monitoring.getTextItem(1, 2)).toBe('item6'); @@ -791,7 +791,8 @@ describe('monitoring', () => { monitoring.actionOnItemSubmenu('Publishing actions', 'Correct item', 0, 0); authoring.send_correction_button.click(); - expect(element(by.id('multi-select-count')).isPresent()).toBeFalsy(); + + browser.wait(ECE.stalenessOf(element(by.id('multi-select-count')))); }); it('can view published duplicated item in duplicate tab of non-published original item', () => { @@ -839,18 +840,23 @@ describe('monitoring', () => { authoring.duplicateTo('Sports Desk', 'one'); monitoring.actionOnItemSubmenu('Duplicate', 'Duplicate To', 2, 0); - var dropdownSelected = monitoring.getSendToDropdown(); + expect( + new TreeSelectDriver( + el(['interactive-actions-panel', 'destination-select']), + ).getValue(), + ).toEqual(['Sports Desk']); - browser.sleep(500); - expect(dropdownSelected.getText()).toEqual('Sports Desk'); authoring.duplicateTo('Politic Desk', 'two', true); monitoring.actionOnItemSubmenu('Duplicate', 'Duplicate To', 2, 0); - - dropdownSelected = monitoring.getSendToDropdown(); authoring.close(); browser.sleep(500); - expect(dropdownSelected.getText()).toEqual('Politic Desk'); + + expect( + new TreeSelectDriver( + el(['interactive-actions-panel', 'destination-select']), + ).getValue(), + ).toEqual(['Politic Desk']); }); it('can view published item as readonly when opened', () => { @@ -897,11 +903,12 @@ describe('monitoring', () => { it('Can create items from templates', () => { const slugline = 'slugline template'; const editorsNote = 'test editor\'s note for template'; + const newTemplateName = 'template 1234'; monitoring.openMonitoring(); expect(browser.isElementPresent(element(s(['authoring'])))).toBe(false); - el(['content-create']).click(); - el(['content-create-dropdown']).element(by.buttonText('Plain text')).click(); + + authoring.createTextItemFromTemplate('plain text'); expect(browser.isElementPresent(element(s(['authoring'])))).toBe(true); el(['authoring', 'field-slugline']).sendKeys(slugline); @@ -911,13 +918,16 @@ describe('monitoring', () => { el(['authoring', 'actions-button']).click(); el(['authoring', 'actions-list']).element(by.buttonText('Save as template')).click(); + + el(['save-as-template', 'name-input']).clear(); + el(['save-as-template', 'name-input']).sendKeys(newTemplateName); + el(['create-template-modal--save']).click(); + el(['authoring', 'close']).click(); expect(browser.isElementPresent(element(s(['authoring'])))).toBe(false); - el(['content-create']).click(); - el(['content-create-dropdown']).element(by.buttonText('More templates...')).click(); - el(['select-template'], by.buttonText(slugline)).click(); + authoring.createTextItemFromTemplate(newTemplateName); browser.sleep(500); // animation expect(browser.isElementPresent(element(s(['authoring'])))).toBe(true); diff --git a/e2e/client/specs/publishing_spec.ts b/e2e/client/specs/publishing_spec.ts index 4d9802b3b0..335e159573 100644 --- a/e2e/client/specs/publishing_spec.ts +++ b/e2e/client/specs/publishing_spec.ts @@ -9,6 +9,7 @@ import {workspace} from './helpers/workspace'; import {authoring} from './helpers/authoring'; import {el, els, ECE} from '@superdesk/end-to-end-testing-helpers'; import {executeContextMenuAction} from '@superdesk/end-to-end-testing-helpers/dist/articlesList'; +import {TreeSelectDriver} from './helpers/tree-select-driver'; describe('publishing', () => { beforeEach(monitoring.openMonitoring); @@ -61,8 +62,9 @@ describe('publishing', () => { executeContextMenuAction(els(['article-item'], null, thirdStage).get(0), 'Edit'); el(['authoring', 'open-send-publish-pane']).click(); - el(['authoring', 'send-publish-pane', 'tab--publish']).click(); - el(['authoring', 'send-publish-pane', 'publish']).click(); + + el(['authoring', 'interactive-actions-panel', 'tabs'], by.buttonText('Publish')).click(); + el(['authoring', 'interactive-actions-panel', 'publish']).click(); assertToastMsg('error', 'SUBJECT is a required field'); assertToastMsg('error', 'BODY HTML is a required field'); @@ -81,9 +83,7 @@ describe('publishing', () => { it('can send and publish', () => { workspace.selectDesk('Politic Desk'); - el(['content-create']).click(); - el(['content-create-dropdown']).element(by.buttonText('More templates...')).click(); - el(['select-template'], by.buttonText('testing')).click(); + authoring.createTextItemFromTemplate('testing'); const slugline = 'testing-send-and-publish'; @@ -91,19 +91,20 @@ describe('publishing', () => { el(['authoring', 'save']).click(); el(['authoring', 'open-send-publish-pane']).click(); - el(['authoring', 'send-publish-pane', 'tab--publish']).click(); - el(['authoring', 'send-publish-pane', 'publish-from--options', 'desk-select--handle']).click(); - el( - ['authoring', 'send-publish-pane', 'publish-from--options', 'desk-select--options'], - by.buttonText('Sports Desk'), - ).click(); + el(['authoring', 'interactive-actions-panel', 'tabs'], by.buttonText('Publish')).click(); + + new TreeSelectDriver( + el(['interactive-actions-panel', 'destination-select']), + ).setValue('Sports Desk'); - el(['authoring', 'send-publish-pane', 'publish-from--submit']).click(); + el(['authoring', 'interactive-actions-panel', 'publish-from']).click(); assertToastMsg('success', 'Item published.'); - browser.wait(ECE.stalenessOf(element(by.cssContainingText( + const firstGroup = els(['monitoring-group']).get(0); + + browser.wait(ECE.stalenessOf(firstGroup.element(by.cssContainingText( '[data-test-id="article-item"] [data-test-id="field--slugline"]', slugline, ))), MONITORING_DEBOUNCE_MAX_WAIT); diff --git a/e2e/client/specs/search_spec.ts b/e2e/client/specs/search_spec.ts index b03647fabe..e89a122047 100644 --- a/e2e/client/specs/search_spec.ts +++ b/e2e/client/specs/search_spec.ts @@ -7,7 +7,7 @@ import {globalSearch} from './helpers/search'; import {content} from './helpers/content'; import {authoring} from './helpers/authoring'; import {nav, scrollToView} from './helpers/utils'; -import {ECE} from '@superdesk/end-to-end-testing-helpers'; +import {ECE, el} from '@superdesk/end-to-end-testing-helpers'; describe('search', () => { beforeEach(() => { @@ -126,7 +126,7 @@ describe('search', () => { authoring.sendTo('Politic Desk'); authoring.confirmSendTo(); monitoring.switchToDesk('POLITIC DESK'); - expect(monitoring.getTextItem(1, 0)).toBe('From-Sports-To-Politics'); + expect(monitoring.getTextItem(0, 0)).toBe('From-Sports-To-Politics'); // search by from desk field globalSearch.openGlobalSearch(); @@ -274,14 +274,21 @@ describe('search', () => { authoring.closeSendAndPublish(); authoring.save(); authoring.close(); - expect(globalSearch.getItem(0).element(by.className('state_embargo')).isDisplayed()).toBe(true); - expect(globalSearch.getItem(0).element(by.className('state_embargo')).getText()).toEqual('EMBARGO'); + + const embargoElement = globalSearch.getItem(0).element(by.className('state_embargo')); + + browser.wait(ECE.visibilityOf(embargoElement)); + + expect(embargoElement.getText()).toEqual('EMBARGO'); }); it('can search scheduled', () => { globalSearch.waitForItemCount(16); globalSearch.actionOnItem('Edit', 'item9'); authoring.schedule(false); + + browser.wait(ECE.stalenessOf(el(['notification--success']))); + globalSearch.openFilterPanel(); globalSearch.openParameters(); globalSearch.toggleSearchTabs('filters'); diff --git a/e2e/client/specs/send_spec.ts b/e2e/client/specs/send_spec.ts index cd94f35b93..4bd82767e4 100644 --- a/e2e/client/specs/send_spec.ts +++ b/e2e/client/specs/send_spec.ts @@ -6,6 +6,8 @@ import {monitoring} from './helpers/monitoring'; import {workspace} from './helpers/workspace'; import {content} from './helpers/content'; import {authoring} from './helpers/authoring'; +import {ECE, el} from '@superdesk/end-to-end-testing-helpers'; +import {TreeSelectDriver} from './helpers/tree-select-driver'; describe('send', () => { function getItemState(index) { @@ -32,14 +34,28 @@ describe('send', () => { expect(getItemState(0)).toBe('SUBMITTED'); }); - it('warns that there are spelling mistakes', () => { + /** + * Not sure if this was ever testing the intended thing. + * Currently it is only passing by accident + * since there's a modal that prompts to save unsaved changes. + * It isn't testing anything related to spellchecking. + * I'm disabling it in case we wanted to reimplement it in the future. + */ + xit('warns that there are spelling mistakes', () => { workspace.editItem(1); authoring.writeText('mispeled word'); authoring.sendTo('Sports Desk'); expect(element(by.className('modal__content')).isDisplayed()).toBe(true); }); - it('can submit item to a desk although there are spelling mistakes', () => { + /** + * Not sure if this was ever testing the intended thing. + * Currently it is only passing by accident + * since there's a modal that prompts to save unsaved changes. + * It isn't testing anything related to spellchecking. + * I'm disabling it in case we wanted to reimplement it in the future. + */ + xit('can submit item to a desk although there are spelling mistakes', () => { workspace.editItem(1); authoring.writeText('mispeled word'); authoring.sendTo('Sports Desk'); @@ -55,7 +71,14 @@ describe('send', () => { expect(getItemState(0)).toBe('SUBMITTED'); }); - it('can cancel submit request because there are spelling mistakes', () => { + /** + * Not sure if this was ever testing the intended thing. + * Currently it is only passing by accident + * since there's a modal that prompts to save unsaved changes. + * It isn't testing anything related to spellchecking. + * I'm disabling it in case we wanted to reimplement it in the future. + */ + xit('can cancel submit request because there are spelling mistakes', () => { workspace.editItem(1); authoring.writeText('mispeled word'); authoring.sendTo('Sports Desk'); @@ -72,7 +95,8 @@ describe('send', () => { expect(monitoring.hasClass(element(by.id('main-container')), 'hideMonitoring')).toBe(true); authoring.sendToButton.click(); - expect(authoring.sendItemContainer.isDisplayed()).toBe(true); + + browser.wait(ECE.visibilityOf(el(['interactive-actions-panel']))); }); it('can display monitoring after submitting an item to a desk using full view of authoring', () => { @@ -126,12 +150,13 @@ describe('send', () => { monitoring.showHideList(); authoring.sendToButton.click(); - var sidebar = element.all(by.css('.side-panel')).last(), - dropdown = sidebar.element(by.css('.dropdown--boxed .dropdown__toggle')), - dropdownSelected = dropdown.element(by.css('[ng-show="selectedDesk"]')); + el(['authoring', 'interactive-actions-panel', 'tabs'], by.buttonText('Send to')).click(); - browser.sleep(500); - expect(dropdownSelected.getText()).toEqual('Politic Desk'); + expect( + new TreeSelectDriver( + el(['interactive-actions-panel', 'destination-select']), + ).getValue(), + ).toEqual(['Politic Desk']); }); it('can remember last sent destination desk and stage on multi selection sendTo panel', () => { @@ -154,15 +179,14 @@ describe('send', () => { // open sendTo panel monitoring.openSendMenu(); - var sidebar = element.all(by.css('.side-panel')).last(), - dropdown = sidebar.element(by.css('.dropdown--boxed .dropdown__toggle')), - dropdownSelected = dropdown.element(by.css('[ng-show="selectedDesk"]')); - - browser.sleep(100); - expect(dropdownSelected.getText()).toEqual('Sports Desk'); // desk remembered - - var btnStage = sidebar.element(by.buttonText('Working Stage')); + expect( + new TreeSelectDriver( + el(['interactive-actions-panel', 'destination-select']), + ).getValue(), + ).toEqual(['Sports Desk']); - expect(btnStage.getAttribute('class')).toContain('active'); // stage remembered + expect( + el(['interactive-actions-panel', 'stage-select']).getAttribute('data-test-value'), + ).toEqual('Working Stage'); }); }); diff --git a/e2e/client/specs/templates_spec.ts b/e2e/client/specs/templates_spec.ts index 3880ac1cc8..6b14a20d21 100644 --- a/e2e/client/specs/templates_spec.ts +++ b/e2e/client/specs/templates_spec.ts @@ -21,7 +21,7 @@ describe('templates', () => { templates.openTemplatesSettings(); templates.add(); templates.getTemplateNameElement().sendKeys('New Template'); - templates.selectProfile('Text'); + templates.selectProfile('Plain text'); templates.setTemplateType('string:create'); templates.selectDesk('Politic Desk'); templates.selectDesk('Sports Desk'); @@ -44,14 +44,14 @@ describe('templates', () => { // check the New Template is accessable from both desks monitoring.openMonitoring(); workspace.selectDesk('Sports Desk'); - authoring.createTextItemFromTemplate('new'); + authoring.createTextItemFromTemplate('new template'); expect(authoring.getBodyText()).toBe('This is body from the template'); expect(authoring.getHeaderSluglineText()).toBe('Test Template'); expect(authoring.getHeadlineText()).toBe('New Item'); authoring.close(); workspace.selectDesk('Politic Desk'); - authoring.createTextItemFromTemplate('new'); + authoring.createTextItemFromTemplate('new template'); expect(authoring.getBodyText()).toBe('This is body from the template'); expect(authoring.getHeaderSluglineText()).toBe('Test Template'); expect(authoring.getHeadlineText()).toBe('New Item'); @@ -61,7 +61,7 @@ describe('templates', () => { templates.openTemplatesSettings(); templates.add(); templates.getTemplateNameElement().sendKeys('Second New Template'); - templates.selectProfile('Text'); + templates.selectProfile('Plain text'); templates.setTemplateType('string:create'); templates.selectDesk('Politic Desk'); templates.selectDesk('Sports Desk'); diff --git a/e2e/client/specs/users_spec.ts b/e2e/client/specs/users_spec.ts index dfc2d5cc80..b924feeabc 100644 --- a/e2e/client/specs/users_spec.ts +++ b/e2e/client/specs/users_spec.ts @@ -246,8 +246,8 @@ describe('users', () => { // navigate to Workspace and create a new article workspace.openContent(); - authoring.navbarMenuBtn.click(); - authoring.newPlainArticleLink.click(); + + authoring.createTextItem(); // authoring opened, click the set category menu and see what // categories are offered @@ -275,8 +275,7 @@ describe('users', () => { // navigate to Workspace and create a new article monitoring.openMonitoring(); - authoring.navbarMenuBtn.click(); - authoring.newPlainArticleLink.click(); + authoring.createTextItem(); browser.sleep(100); // Open subject metadata dropdown field @@ -354,19 +353,19 @@ describe('users', () => { }); it('while creating a new user', () => { - var buttonCreate = element(by.className('sd-create-btn')); + var buttonCreate = element(by.css('[data-test-id="create-user-button"]')); buttonCreate.click(); - expect(element(by.id('user_default_desk')).isPresent()).toBe(false); + expect(element(by.css('[data-test-id="default-desk-template"]')).isPresent()).toBe(false); }); it('while pre-viewing and user clicks on create new user', () => { - var buttonCreate = element(by.className('sd-create-btn')); + var buttonCreate = element(by.css('[data-test-id="create-user-button"]')); element.all(by.repeater('users')).first().click(); buttonCreate.click(); - expect(element(by.id('user_default_desk')).isPresent()).toBe(false); + expect(element(by.css('[data-test-id="default-desk-template"]')).isPresent()).toBe(false); }); }); diff --git a/e2e/server/requirements.txt b/e2e/server/requirements.txt index 49ac53dae6..c30d71eaab 100644 --- a/e2e/server/requirements.txt +++ b/e2e/server/requirements.txt @@ -26,9 +26,9 @@ blinker==1.4 # flask-mail # raven # superdesk-core -boto3==1.28.29 +boto3==1.28.50 # via superdesk-core -botocore==1.31.29 +botocore==1.31.50 # via # boto3 # s3transfer @@ -71,7 +71,7 @@ click-repl==0.3.0 # via celery croniter==0.3.37 # via superdesk-core -cryptography==41.0.3 +cryptography==41.0.4 # via # authlib # jwcrypto @@ -87,7 +87,7 @@ elasticsearch==7.13.4 # via eve-elastic eve==1.1.2 # via superdesk-core -eve-elastic==7.3.1 +eve-elastic==7.3.2 # via superdesk-core events==0.3 # via eve @@ -203,7 +203,7 @@ python-magic==0.4.27 # via superdesk-core python-twitter==3.5 # via superdesk-core -pytz==2023.3 +pytz==2023.3.post1 # via # celery # eve-elastic @@ -245,7 +245,7 @@ six==1.16.0 # python-dateutil superdesk-core @ git+https://github.com/superdesk/superdesk-core.git@release/2.7 # via -r requirements.in -typing-extensions==4.7.1 +typing-extensions==4.8.0 # via superdesk-core tzlocal==2.1 # via superdesk-core diff --git a/package-lock.json b/package-lock.json index 0c83ed4f87..11151ddba4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,7 +82,7 @@ }, "@material-ui/lab": { "version": "4.0.0-alpha.61", - "resolved": "https://verdaccio.sourcefabric.org/@material-ui/lab/-/lab-4.0.0-alpha.61.tgz", + "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.61.tgz", "integrity": "sha512-rSzm+XKiNUjKegj8bzt5+pygZeckNLOr+IjykH8sYdVk7dE9y2ZuUSofiMV2bJk3qU+JHwexmw+q0RyNZB9ugg==", "requires": { "@babel/runtime": "^7.4.4", @@ -111,7 +111,7 @@ }, "@material-ui/utils": { "version": "4.11.3", - "resolved": "https://verdaccio.sourcefabric.org/@material-ui/utils/-/utils-4.11.3.tgz", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.3.tgz", "integrity": "sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg==", "requires": { "@babel/runtime": "^7.4.4", @@ -576,7 +576,7 @@ }, "@superdesk/primereact": { "version": "5.0.2-12", - "resolved": "https://verdaccio.sourcefabric.org/@superdesk/primereact/-/primereact-5.0.2-12.tgz", + "resolved": "https://registry.npmjs.org/@superdesk/primereact/-/primereact-5.0.2-12.tgz", "integrity": "sha512-cyaek+NgIDg5AXxn29BwHprnHZB+pe3Ll2w2KlP2rmICm3cgbdVtjYJTT5d9Yxfioor6vVulo3O9BOxEmxpgnw==", "requires": { "react-transition-group": "^4.4.1" @@ -626,7 +626,7 @@ }, "@superdesk/react-resizable-panels": { "version": "0.0.39", - "resolved": "https://verdaccio.sourcefabric.org/@superdesk/react-resizable-panels/-/react-resizable-panels-0.0.39.tgz", + "resolved": "https://registry.npmjs.org/@superdesk/react-resizable-panels/-/react-resizable-panels-0.0.39.tgz", "integrity": "sha512-/aoKBYqNzzMACY82y7znr9v1jM63hvi0fglKU6IHWMvEpwQllsk/QHGzDNQb2lj8BOILfey4CRhRrDVXE3Rxmg==", "requires": { "@swc/helpers": "0.4.14" @@ -634,7 +634,7 @@ }, "@swc/helpers": { "version": "0.4.14", - "resolved": "https://verdaccio.sourcefabric.org/@swc/helpers/-/helpers-0.4.14.tgz", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", "requires": { "tslib": "^2.4.0" @@ -696,7 +696,7 @@ }, "@types/enzyme-adapter-react-16": { "version": "1.0.6", - "resolved": "https://verdaccio.sourcefabric.org/@types/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.0.6.tgz", + "resolved": "https://registry.npmjs.org/@types/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.0.6.tgz", "integrity": "sha512-VonDkZ15jzqDWL8mPFIQnnLtjwebuL9YnDkqeCDYnB4IVgwUm0mwKkqhrxLL6mb05xm7qqa3IE95m8CZE9imCg==", "requires": { "@types/enzyme": "*" @@ -776,7 +776,7 @@ }, "@typescript-eslint/parser": { "version": "5.57.0", - "resolved": "https://verdaccio.sourcefabric.org/@typescript-eslint/parser/-/parser-5.57.0.tgz", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.57.0.tgz", "integrity": "sha512-orrduvpWYkgLCyAdNtR1QIWovcNZlEm6yL8nwH/eTxWLd8gsP+25pdLHYzL2QdkqrieaDwLpytHqycncv0woUQ==", "requires": { "@typescript-eslint/scope-manager": "5.57.0", @@ -787,7 +787,7 @@ "dependencies": { "debug": { "version": "4.3.4", - "resolved": "https://verdaccio.sourcefabric.org/debug/-/debug-4.3.4.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" @@ -1000,7 +1000,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "prop-types": { "version": "15.8.1", @@ -2065,7 +2065,7 @@ }, "bindings": { "version": "1.5.0", - "resolved": "https://verdaccio.sourcefabric.org/bindings/-/bindings-1.5.0.tgz", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "optional": true, "requires": { @@ -2632,7 +2632,7 @@ "strip-ansi": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha512-DerhZL7j6i6/nEnVG0qViKXI0OKouvvpsAiaj7c+LfqZZZxdwZtv8+UiA/w4VUJpT8UzX0pR1dcHOii1GbmruQ==", + "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", "requires": { "ansi-regex": "^0.2.1" } @@ -2640,7 +2640,7 @@ "supports-color": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha512-tdCZ28MnM7k7cJDJc7Eq80A9CsRFAAOZUy41npOZCs++qSjfIy7o5Rh46CBk+Dk5FbKJ33X3Tqg4YrV07N5RaA==" + "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=" } } }, @@ -2676,7 +2676,7 @@ }, "chart.js": { "version": "2.9.4", - "resolved": "https://verdaccio.sourcefabric.org/chart.js/-/chart.js-2.9.4.tgz", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz", "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==", "requires": { "chartjs-color": "^2.1.0", @@ -2685,7 +2685,7 @@ }, "chartjs-color": { "version": "2.4.1", - "resolved": "https://verdaccio.sourcefabric.org/chartjs-color/-/chartjs-color-2.4.1.tgz", + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz", "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==", "requires": { "chartjs-color-string": "^0.6.0", @@ -2694,7 +2694,7 @@ }, "chartjs-color-string": { "version": "0.6.0", - "resolved": "https://verdaccio.sourcefabric.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", + "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==", "requires": { "color-name": "^1.0.0" @@ -3036,7 +3036,7 @@ }, "clsx": { "version": "1.2.1", - "resolved": "https://verdaccio.sourcefabric.org/clsx/-/clsx-1.2.1.tgz", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" }, "co": { @@ -3548,7 +3548,7 @@ }, "css-box-model": { "version": "1.2.1", - "resolved": "https://verdaccio.sourcefabric.org/css-box-model/-/css-box-model-1.2.1.tgz", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", "requires": { "tiny-invariant": "^1.0.6" @@ -3734,7 +3734,7 @@ }, "date-fns": { "version": "2.7.0", - "resolved": "https://verdaccio.sourcefabric.org/date-fns/-/date-fns-2.7.0.tgz", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.7.0.tgz", "integrity": "sha512-wxYp2PGoUDN5ZEACc61aOtYFvSsJUylIvCjpjDOqM1UDaKIIuMJ9fAnMYFHV3TQaDpfTVxhwNK/GiCaHKuemTA==" }, "date-format": { @@ -4215,7 +4215,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" } } }, @@ -4805,7 +4805,7 @@ }, "semver": { "version": "5.7.1", - "resolved": "https://verdaccio.sourcefabric.org/semver/-/semver-5.7.1.tgz", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "string.prototype.trimend": { @@ -5019,7 +5019,7 @@ }, "semver": { "version": "5.7.1", - "resolved": "https://verdaccio.sourcefabric.org/semver/-/semver-5.7.1.tgz", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "string.prototype.trimend": { @@ -6432,7 +6432,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" } } }, @@ -9608,7 +9608,7 @@ "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" }, "json-loader": { "version": "0.5.7", @@ -11183,7 +11183,7 @@ }, "memoize-one": { "version": "5.2.1", - "resolved": "https://verdaccio.sourcefabric.org/memoize-one/-/memoize-one-5.2.1.tgz", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" }, "memory-fs": { @@ -11580,7 +11580,7 @@ "dependencies": { "commander": { "version": "2.20.3", - "resolved": "https://verdaccio.sourcefabric.org/commander/-/commander-2.20.3.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" } } @@ -12095,7 +12095,7 @@ "object-assign": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==" + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" }, "object-component": { "version": "0.0.3", @@ -12921,7 +12921,7 @@ }, "popper.js": { "version": "1.14.4", - "resolved": "https://verdaccio.sourcefabric.org/popper.js/-/popper.js-1.14.4.tgz", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.4.tgz", "integrity": "sha512-VKAPR2KCx8Uw0oVn0Rt4iggzat+MJ1wu1uJiDnfnMiQcGQRBIopZLfXMKsK/K8NPEerY5kefaYtYjTLb3F6ncw==" }, "portfinder": { @@ -13547,7 +13547,7 @@ }, "primeicons": { "version": "2.0.0", - "resolved": "https://verdaccio.sourcefabric.org/primeicons/-/primeicons-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/primeicons/-/primeicons-2.0.0.tgz", "integrity": "sha512-GJTCeMSQU8UU1GqbsaDrg/IH+b/vSinJQl52NVpdJ7sShYLZA8Eq6jLF48Ye3N/dQloGrE07i7XsZvxQ9pNbqg==" }, "private": { @@ -13620,7 +13620,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" } } }, @@ -13811,7 +13811,7 @@ }, "raf-schd": { "version": "4.0.3", - "resolved": "https://verdaccio.sourcefabric.org/raf-schd/-/raf-schd-4.0.3.tgz", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==" }, "railroad-diagrams": { @@ -13948,7 +13948,7 @@ }, "react-beautiful-dnd": { "version": "13.1.1", - "resolved": "https://verdaccio.sourcefabric.org/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz", + "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz", "integrity": "sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==", "requires": { "@babel/runtime": "^7.9.2", @@ -14018,12 +14018,12 @@ }, "react-fast-compare": { "version": "3.2.2", - "resolved": "https://verdaccio.sourcefabric.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, "react-id-generator": { "version": "3.0.2", - "resolved": "https://verdaccio.sourcefabric.org/react-id-generator/-/react-id-generator-3.0.2.tgz", + "resolved": "https://registry.npmjs.org/react-id-generator/-/react-id-generator-3.0.2.tgz", "integrity": "sha512-d0rqWzZ6g0P9agHtA7wX/ErQ4iV/657/0Oz+SX3kid7nR4d0YwaWjjOTIrgYHv2lICZKrxIH4BaKppKrM8fRfw==" }, "react-is": { @@ -14075,7 +14075,7 @@ }, "react-popper": { "version": "2.3.0", - "resolved": "https://verdaccio.sourcefabric.org/react-popper/-/react-popper-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", "requires": { "react-fast-compare": "^3.0.1", @@ -14139,7 +14139,7 @@ }, "react-scrollspy": { "version": "3.4.3", - "resolved": "https://verdaccio.sourcefabric.org/react-scrollspy/-/react-scrollspy-3.4.3.tgz", + "resolved": "https://registry.npmjs.org/react-scrollspy/-/react-scrollspy-3.4.3.tgz", "integrity": "sha512-c2QZpMPWxm1HF71h1EqaxBldx2zLYO0aZ24Bcuo2mUWF79T+F6qOtr7XJCzUDm99NOwhVKQD01a7A8VC6c90CQ==", "requires": { "babel-runtime": "^6.26.0", @@ -14185,7 +14185,7 @@ }, "scheduler": { "version": "0.19.1", - "resolved": "https://verdaccio.sourcefabric.org/scheduler/-/scheduler-0.19.1.tgz", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", "requires": { "loose-envify": "^1.1.0", @@ -14463,7 +14463,7 @@ "regexpu-core": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", - "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "integrity": "sha512-Ci+lDRlvAElKjFp5keqmVUaJLqZiHywekXhshT6wVUyDObGPdymNPhxBmf38ZVsaUGOnZ3Fot9YzxvoI31ymYw==", "requires": { "regenerate": "^1.2.1", "regjsgen": "^0.2.0", @@ -14473,12 +14473,12 @@ "regjsgen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" + "integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==" }, "regjsparser": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==", "requires": { "jsesc": "~0.5.0" } @@ -16132,7 +16132,7 @@ "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" } @@ -16674,9 +16674,9 @@ } }, "superdesk-ui-framework": { - "version": "3.0.54", - "resolved": "https://registry.npmjs.org/superdesk-ui-framework/-/superdesk-ui-framework-3.0.54.tgz", - "integrity": "sha512-wWtx2AEJUEShU7v60KteMcPW+vfP0iI3KDnWxnBxsNm6Y7T/nT2ROrd2U5dM/fjNt41jJEiP+AD7mN3ykX8Q4g==", + "version": "3.0.59", + "resolved": "https://registry.npmjs.org/superdesk-ui-framework/-/superdesk-ui-framework-3.0.59.tgz", + "integrity": "sha512-FuXyJNGVE970jlHWm0vD1Cr9QGLEfjONPaPfNSAKQZHW1f//By2VERgPi8TFv1kTdZOlXcOP6vFhnw/OR/Z6Nw==", "requires": { "@material-ui/lab": "^4.0.0-alpha.56", "@popperjs/core": "^2.4.0", @@ -16699,9 +16699,9 @@ }, "dependencies": { "@types/node": { - "version": "14.18.56", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.56.tgz", - "integrity": "sha512-+k+57NVS9opgrEn5l9c0gvD1r6C+PtyhVE4BTnMMRwiEA8ZO8uFcs6Yy2sXIy0eC95ZurBtRSvhZiHXBysbl6w==" + "version": "14.18.61", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.61.tgz", + "integrity": "sha512-1mFT4DqS4/s9tlZbdkwEB/EnSykA9MDeDLIk3FHApGvIMGY//qgstB2gu9GKGESWyW/qiRUO+jhlLJ9bBJ8j+Q==" }, "cheerio": { "version": "1.0.0-rc.12", @@ -16860,7 +16860,7 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==" + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" }, "svgo": { "version": "0.7.2", @@ -17048,7 +17048,7 @@ }, "tiny-invariant": { "version": "1.3.1", - "resolved": "https://verdaccio.sourcefabric.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, "tinycolor": { @@ -17615,7 +17615,7 @@ }, "use-memo-one": { "version": "1.1.3", - "resolved": "https://verdaccio.sourcefabric.org/use-memo-one/-/use-memo-one-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz", "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==" }, "user-home": { @@ -17738,7 +17738,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" } } }, diff --git a/package.json b/package.json index 258e127b55..b17d5fac21 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "sass-loader": "6.0.6", "shortid": "2.2.8", "style-loader": "0.20.2", - "superdesk-ui-framework": "^3.0.54", + "superdesk-ui-framework": "^3.0.59", "ts-loader": "3.5.0", "tslint": "5.11.0", "typescript": "4.9.5", diff --git a/scripts/api/article-send.tsx b/scripts/api/article-send.tsx index 89e9dc869f..965843e60b 100644 --- a/scripts/api/article-send.tsx +++ b/scripts/api/article-send.tsx @@ -244,6 +244,10 @@ export function sendItems( delete patchFinal['_links']; return patchFinal; + }).catch((err) => { + notify.error(err._message ?? gettext('Unknown error occurred')); + + throw err; }); }); }), diff --git a/scripts/api/desks.ts b/scripts/api/desks.ts index e6c52e95c9..36f516a7d5 100644 --- a/scripts/api/desks.ts +++ b/scripts/api/desks.ts @@ -31,6 +31,10 @@ function getAllDesks(): OrderedMap { return desksMap; } +function getCurrentUserDesks(): Array { + return ng.get('desks').userDesks; +} + function getDeskStages(deskId: IDesk['_id']): OrderedMap { let stagesMap: OrderedMap = OrderedMap(); @@ -53,6 +57,7 @@ interface IDesksApi { getAllDesks(): OrderedMap; getDeskById(id: IDesk['_id']): IDesk ; getDeskStages(deskId: IDesk['_id']): OrderedMap; + getCurrentUserDesks(): Array; // desks that current user has access to } export const desks: IDesksApi = { @@ -62,4 +67,5 @@ export const desks: IDesksApi = { getAllDesks, getDeskById, getDeskStages, + getCurrentUserDesks, }; diff --git a/scripts/appConfig.ts b/scripts/appConfig.ts index f9fad0c3ec..7a5a2132e4 100644 --- a/scripts/appConfig.ts +++ b/scripts/appConfig.ts @@ -46,7 +46,7 @@ export const debugInfo = { translationsLoaded: false, }; -export let authoringReactEnabledUserSelection = (JSON.parse(localStorage.getItem('auth-react') ?? 'true') as boolean); +export let authoringReactEnabledUserSelection = (JSON.parse(localStorage.getItem('auth-react') ?? 'false') as boolean); export function toggleAuthoringReact(enabled: boolean) { localStorage.setItem('auth-react', JSON.stringify(enabled)); @@ -58,7 +58,7 @@ export function toggleAuthoringReact(enabled: boolean) { * Authoring react has to be enabled in the broadcasting * module regardless of the user selection. * */ -export let authoringReactViewEnabled = true; +export let authoringReactViewEnabled = authoringReactEnabledUserSelection; export const uiFrameworkAuthoringPanelTest = false; export function setAuthoringReact(enabled: boolean) { diff --git a/scripts/apps/authoring-bridge/authoring-api-common.ts b/scripts/apps/authoring-bridge/authoring-api-common.ts index 4d77ad285e..b55bf2a1bb 100644 --- a/scripts/apps/authoring-bridge/authoring-api-common.ts +++ b/scripts/apps/authoring-bridge/authoring-api-common.ts @@ -103,6 +103,8 @@ export const authoringApiCommon: IAuthoringApiCommon = { } }, closeAuthoringForce: () => { + ng.get('superdeskFlags').flags.hideMonitoring = false; + ng.get('authoringWorkspace').close(); }, }; diff --git a/scripts/apps/authoring/versioning/history/HistoryController.ts b/scripts/apps/authoring/versioning/history/HistoryController.ts index f63d06d6b6..b1fd919af1 100644 --- a/scripts/apps/authoring/versioning/history/HistoryController.ts +++ b/scripts/apps/authoring/versioning/history/HistoryController.ts @@ -135,31 +135,38 @@ export function getHistoryItems(item: IArticle): Promise> { .then((historyItems) => { let historyVersion = historyItems.length && historyItems[0].version || 200; - if (!historyItems.length || historyItems[0].version > 1) { - // no or partial history so get versions - archiveService.getVersions(item, desks, 'operations').then((versions) => { - let processedVersions = versions.map(processVersion); - - // use versions where version number is less than the history - historyItemsResult = _.filter(processedVersions, (v) => v.version < historyVersion); - - // if there's any history items then merge them - if (historyItems.length) { - historyItemsResult = historyItemsResult.concat(historyItems); - } - }); - } else { - historyItemsResult = historyItems; - } - - // Filter out item_lock and item_unlock history entries - if (historyItemsResult && historyItemsResult.length > 0) { - historyItemsResult = historyItemsResult.filter( - (entry) => !entry.operation || ['item_lock', 'item_unlock'].indexOf(entry.operation) < 0, - ); - } - - resolve(historyItemsResult); + const waitForVersions = new Promise((resolveVersions) => { + if (!historyItems.length || historyItems[0].version > 1) { + // no or partial history so get versions + archiveService.getVersions(item, desks, 'operations').then((versions) => { + let processedVersions = versions.map(processVersion); + + // use versions where version number is less than the history + historyItemsResult = _.filter(processedVersions, (v) => v.version < historyVersion); + + // if there's any history items then merge them + if (historyItems.length) { + historyItemsResult = historyItemsResult.concat(historyItems); + } + + resolveVersions(); + }); + } else { + historyItemsResult = historyItems; + resolveVersions(); + } + }); + + waitForVersions.then(() => { + // Filter out item_lock and item_unlock history entries + if (historyItemsResult && historyItemsResult.length > 0) { + historyItemsResult = historyItemsResult.filter( + (entry) => !entry.operation || ['item_lock', 'item_unlock'].indexOf(entry.operation) < 0, + ); + } + + resolve(historyItemsResult); + }); }) .catch(() => { reject(null); diff --git a/scripts/apps/monitoring/views/monitoring-view.html b/scripts/apps/monitoring/views/monitoring-view.html index ecff47b9f8..d282ec981f 100644 --- a/scripts/apps/monitoring/views/monitoring-view.html +++ b/scripts/apps/monitoring/views/monitoring-view.html @@ -113,7 +113,13 @@