Skip to content

Commit

Permalink
Merge branch 'develop' into custom-fileds-e2e-test
Browse files Browse the repository at this point in the history
  • Loading branch information
dzonidoo committed Jun 3, 2024
2 parents c835516 + 2ec11fa commit 2d153d9
Show file tree
Hide file tree
Showing 130 changed files with 2,741 additions and 1,419 deletions.
4 changes: 2 additions & 2 deletions .fireq.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"superdesk_branch": "release/2.5"
}
"superdesk_branch": "develop"
}
7 changes: 7 additions & 0 deletions e2e/README-PROTRACTOR.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,10 @@
webdriver-manager only supports chrome <114 - https://github.com/angular/protractor/issues/5563

To use newer chrome versions, set `CHROME_BIN` and `CHROMEWEBDRIVER`(should point to folder where `chromedriver` file is located) environment variables. Use [Chrome for testing](https://developer.chrome.com/blog/chrome-for-testing) project to download desired chrome version and driver.

# MacOS Setup
`.app` is not an executable so path to chrome test browser should be pointing to the executable inside that folder

Example setup with chrome test browser executable path:

export CHROME_BIN="/Downloads/chrome-mac-arm64/Google_Chrome_for_Testing.app/Contents/MacOS/Google_Chrome_for_Testing"
2 changes: 2 additions & 0 deletions e2e/client/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export default defineConfig({

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',

screenshot: 'only-on-failure',
},

/* Configure projects for major browsers */
Expand Down
5 changes: 2 additions & 3 deletions e2e/client/playwright/authoring.correct.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ test('correcting with unsaved changes', async ({page}) => {

// publishing the article end

// TODO: should be 'monitoring-group=Sports / output'
await page.locator(
s('monitoring-group=Sports', 'article-item=test sports story'),
s('monitoring-group=Sports desk output', 'article-item=test sports story'),
).dblclick({timeout: 10000}); // need to wait until published item appears in output

await page.locator(s('authoring', 'authoring-topbar')).getByLabel('Correct').click();
Expand All @@ -51,7 +50,7 @@ test('correcting with unsaved changes', async ({page}) => {
await page.locator(s('authoring', 'authoring-topbar')).getByRole('button', {name: 'Send Correction'}).click();

await page.locator(
s('monitoring-group=Sports', 'article-item=test sports story [corrected]'),
s('monitoring-group=Sports desk output', 'article-item=test sports story [corrected]'),
).dblclick({timeout: 10000}); // need to wait until published item appears in output

// initialize correction only to make field editable and accessible using the same selector
Expand Down
5 changes: 4 additions & 1 deletion e2e/client/playwright/desks.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import {test, expect} from '@playwright/test';
import {restoreDatabaseSnapshot, s} from './utils';
import {Monitoring} from './page-object-models/monitoring';

/**
* when a desk is mentioned in article comments,
* a notification must show up next to an incoming stage of that desk
*/
test('desk notifications', async ({page}) => {
await restoreDatabaseSnapshot();
const monitoring = new Monitoring(page);

await restoreDatabaseSnapshot();
await page.goto('/#/workspace/monitoring');

await monitoring.selectDeskOrWorkspace('Sports');
await page.locator(
s('monitoring-group=Sports / Working Stage', 'article-item=test sports story'),
).dblclick();
Expand Down
296 changes: 296 additions & 0 deletions e2e/client/playwright/editor3.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
import {Monitoring} from './page-object-models/monitoring';
import {test, expect} from '@playwright/test';
import {restoreDatabaseSnapshot, s} from './utils';
import {getEditor3FormattingOptions, getEditor3Paragraphs} from './utils/editor3';
import {TreeSelectDriver} from './utils/tree-select-driver';

test('accepting a spelling suggestion', async ({page}) => {
const monitoring = new Monitoring(page);

await restoreDatabaseSnapshot({snapshotName: 'spellchecker'});

await page.goto('/#/workspace/monitoring');

await monitoring.selectDeskOrWorkspace('Sports');

await page.locator(
s('monitoring-group=Sports / Working Stage', 'article-item=spellchecker test'),
).dblclick();

await expect(page.locator(s('authoring', 'authoring-field=body_html', 'spellchecker-warning'))).toHaveCount(2);

expect(await getEditor3Paragraphs(page.locator(s('authoring', 'authoring-field=body_html'))))
.toStrictEqual(['ghello world', 'ghello world']);

await page.locator(s('authoring', 'authoring-field=body_html', 'spellchecker-warning'))
.first()
.click({button: 'right'});

await page.locator(s('spellchecker-menu')).getByRole('button', {name: 'hello'}).click();

await expect(
(await page.locator(s('authoring', 'authoring-field=body_html', 'spellchecker-warning')).all()).length,
).toBe(1);

expect(await getEditor3Paragraphs(page.locator(s('authoring', 'authoring-field=body_html'))))
.toStrictEqual(['hello world', 'ghello world']);
});

test('adding word marked as a spellchecker issue to dictionary', async ({page}) => {
const monitoring = new Monitoring(page);

await restoreDatabaseSnapshot({snapshotName: 'spellchecker'});

await page.goto('/#/workspace/monitoring');

await monitoring.selectDeskOrWorkspace('Sports');

await page.locator(
s('monitoring-group=Sports / Working Stage', 'article-item=spellchecker test'),
).dblclick();

await expect(page.locator(s('authoring', 'authoring-field=body_html', 'spellchecker-warning'))).toHaveCount(2);

expect(await getEditor3Paragraphs(page.locator(s('authoring', 'authoring-field=body_html'))))
.toStrictEqual(['ghello world', 'ghello world']);

await page.locator(s('authoring', 'authoring-field=body_html', 'spellchecker-warning'))
.first()
.click({button: 'right'});

await page.locator(s('spellchecker-menu')).getByRole('button', {name: 'Add to dictionary'}).click();

/**
* it expects zero, because when a word is added to dictionary
* it should remove warnings for all instances of that word
* including nested editors (e.g. multi-line-quote)
*/
await expect(
page.locator(s('authoring', 'authoring-field=body_html', 'spellchecker-warning')),
).toHaveCount(0);

expect(await getEditor3Paragraphs(page.locator(s('authoring', 'authoring-field=body_html'))))
.toStrictEqual(['ghello world', 'ghello world']);
});

/**
* FYI undo/redo isn't working the same as in the main editor outside tables
* and it's not great that it's character based.
*/
test('tables maintaining cursor position at the start when executing "undo" action', async ({page}) => {
const monitoring = new Monitoring(page);

await restoreDatabaseSnapshot({snapshotName: 'editor3-tables'});

await page.goto('/#/workspace/monitoring');

await monitoring.selectDeskOrWorkspace('Sports');

await page.locator(
s('monitoring-group=Sports / Working Stage', 'article-item=test sports story'),
).dblclick();

await page.locator(
s('authoring', 'authoring-field=body_html', 'toolbar'),
).getByRole('button', {name: 'table'}).click();

await page.locator(s('authoring', 'authoring-field=body_html', 'table-block'))
.locator('[contenteditable]').first().pressSequentially('foo', {delay: 100});

await page.keyboard.press('ArrowLeft');
await page.keyboard.press('ArrowLeft');
await page.keyboard.press('ArrowLeft');
await page.keyboard.press('Control+z');

await page.locator(s('authoring', 'authoring-field=body_html', 'table-block'))
.locator('[contenteditable]').first().pressSequentially('bar', {delay: 100});

await expect(
page.locator(s('authoring', 'authoring-field=body_html', 'table-block')).locator('[contenteditable]').first(),
).toHaveText('barfo');
});

/**
* FYI undo/redo isn't working the same as in the main editor outside tables
* and it's not great that it's character based.
*/
test('tables maintaining cursor position in the middle when executing "undo" action', async ({page}) => {
const monitoring = new Monitoring(page);

await restoreDatabaseSnapshot({snapshotName: 'editor3-tables'});

await page.goto('/#/workspace/monitoring');

await monitoring.selectDeskOrWorkspace('Sports');

await page.locator(
s('monitoring-group=Sports / Working Stage', 'article-item=test sports story'),
).dblclick();

await page.locator(
s('authoring', 'authoring-field=body_html', 'toolbar'),
).getByRole('button', {name: 'table'}).click();

await page.locator(s('authoring', 'authoring-field=body_html', 'table-block'))
.locator('[contenteditable]').first().pressSequentially('foo', {delay: 100});

await page.keyboard.press('ArrowLeft');
await page.keyboard.press('ArrowLeft');
await page.keyboard.press('Control+z');
await page.keyboard.press('Control+z');

await page.locator(s('authoring', 'authoring-field=body_html', 'table-block'))
.locator('[contenteditable]').first().pressSequentially('bar', {delay: 100});

await expect(
page.locator(s('authoring', 'authoring-field=body_html', 'table-block')).locator('[contenteditable]').first(),
).toHaveText('fbar');
});

/**
* FYI undo/redo isn't working the same as in the main editor outside tables
* and it's not great that it's character based.
*/
test('tables maintaining cursor position at the end when executing "undo" action', async ({page}) => {
const monitoring = new Monitoring(page);

await restoreDatabaseSnapshot({snapshotName: 'editor3-tables'});

await page.goto('/#/workspace/monitoring');

await monitoring.selectDeskOrWorkspace('Sports');

await page.locator(
s('monitoring-group=Sports / Working Stage', 'article-item=test sports story'),
).dblclick();

await page.locator(
s('authoring', 'authoring-field=body_html', 'toolbar'),
).getByRole('button', {name: 'table'}).click();

await page.locator(s('authoring', 'authoring-field=body_html', 'table-block'))
.locator('[contenteditable]').first().pressSequentially('foo', {delay: 100});

await page.keyboard.press('Control+z'); // undo last character

await page.locator(s('authoring', 'authoring-field=body_html', 'table-block'))
.locator('[contenteditable]').first().pressSequentially('bar', {delay: 100});

await expect(
page.locator(s('authoring', 'authoring-field=body_html', 'table-block')).locator('[contenteditable]').first(),
).toHaveText('fobar');
});

/**
* FYI undo/redo isn't working the same as in the main editor outside tables
* and it's not great that it's character based.
*/
test('tables maintaining cursor position when executing "redo" action', async ({page}) => {
const monitoring = new Monitoring(page);

await restoreDatabaseSnapshot({snapshotName: 'editor3-tables'});

await page.goto('/#/workspace/monitoring');

await monitoring.selectDeskOrWorkspace('Sports');

await page.locator(
s('monitoring-group=Sports / Working Stage', 'article-item=test sports story'),
).dblclick();

await page.locator(
s('authoring', 'authoring-field=body_html', 'toolbar'),
).getByRole('button', {name: 'table'}).click();

await page.locator(s('authoring', 'authoring-field=body_html', 'table-block'))
.locator('[contenteditable]').first().pressSequentially('foo', {delay: 100});

await page.keyboard.press('Control+z');
await page.keyboard.press('Control+y');

await page.locator(s('authoring', 'authoring-field=body_html', 'table-block'))
.locator('[contenteditable]').first().pressSequentially('bar', {delay: 100});

await expect(
page.locator(s('authoring', 'authoring-field=body_html', 'table-block')).locator('[contenteditable]').first(),
).toHaveText('fobaro');
});

test('configuring a vocabulary for custom blocks', async ({page}) => {
await restoreDatabaseSnapshot();

await page.goto('/#/settings/vocabularies');

await page.locator(s('metadata-navigation')).getByRole('button', {name: 'Custom blocks'}).click();

await page.getByRole('button', {name: 'Add New'}).click();

// Input sample data
await page.locator(s('vocabulary-edit-content')).getByLabel('Id').fill('custom_blocks_2');

await page.locator(s('vocabulary-edit-content')).getByLabel('Name').fill('Custom blocks 2');

await new TreeSelectDriver(
page,
page.locator(s('vocabulary-edit-content', 'formatting-options')),
).setValue(['h1']);

await page.locator(s('vocabulary-edit-content', 'editor3')).getByRole('textbox').fill('test data');


// Apply formatting option to sample text data
await page.locator(s('editor3')).getByText('test data').click();
await page.locator(s('editor3', 'formatting-option=h1')).click();

// Save editor block
await page.locator(s('vocabulary-edit-footer')).getByRole('button', {name: 'Save'}).click();

await expect(page.locator(s('vocabulary-edit-content'))).not.toBeVisible(); // wait for saving to finish

// Edit custom block
await page.locator(s('vocabulary-item=Custom blocks 2')).hover();
await page.locator(s('vocabulary-item=Custom blocks 2', 'vocabulary-item--start-editing')).click();

// Check if formatting option, sample text data
await expect(page.locator(s('editor3', 'formatting-option=h1'))).toBeVisible();
await expect(page.locator(s('editor3')).getByRole('textbox')).toHaveText('test data');
});

test('adding a custom block inside editor3', async ({page}) => {
const monitoring = new Monitoring(page);

await restoreDatabaseSnapshot({snapshotName: 'custom-blocks'});

await page.goto('/#/workspace/monitoring');

await monitoring.selectDeskOrWorkspace('Sports');

await page.locator(
s('monitoring-group=Sports / Working Stage', 'article-item=test sports story'),
).dblclick();

await page.locator(s('authoring', 'authoring-field=body_html')).getByRole('textbox').click();

await page.locator(
s('authoring', 'authoring-field=body_html', 'toolbar'),
).getByRole('button', {name: 'Custom block'}).click();

await page.locator(s('tree-menu-popover'))
.getByRole('button', {name: 'Custom Block 1'})
.click();

await expect(
page.locator(s('authoring', 'authoring-field=body_html', 'custom-block')).getByRole('textbox').first(),
).toHaveText('custom block 1 template content');

await page.locator(
s('authoring', 'authoring-field=body_html', 'custom-block'),
).getByRole('textbox').click();

const result = await getEditor3FormattingOptions(
page.locator(s('authoring', 'authoring-field=body_html', 'editor3')),
);

expect(result).toEqual(['h2', 'italic', 'bold']);
});

Loading

0 comments on commit 2d153d9

Please sign in to comment.