Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add desk tests #4587

Draft
wants to merge 13 commits into
base: develop
Choose a base branch
from
12 changes: 10 additions & 2 deletions e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Most tests run against `main` database snapshot (`e2e/server/dump/full/main`). T
5. install python dependencies - `pip install -Ur requirements.txt`

6. restore main dump `python manage.py storage:restore main`
7. remove the dump you just restored `rm -r server/dump/full/main`
7. remove the dump you just restored `rm -r dump/full/main`
8. open superdesk in the browser and do the changes you need(best not to remove/rename things because it might break other tests)
9. regenerate `main` dump from your existing database state `python manage.py storage:dump --name main`
10. in case you make a mistake, undo the removal of the main dump and continue from step 6.
Expand Down Expand Up @@ -85,4 +85,12 @@ await page.locator(s('authoring', 'comments-widget', 'submit')).click();

### Known issues

* Playwright VSCode extension seems not to respect viewport size that is set in `e2e/client/playwright.config.ts`. An easy workaround is adjusting browser size manually in development. It will work in CI.
#### Viewport

Playwright VSCode extension seems not to respect viewport size that is set in `e2e/client/playwright.config.ts`. An easy workaround is adjusting browser size manually in development. It will work in CI.

#### Current desk

There is an issue with Superdesk that does not reproduce locally where upon openiing monitoring view, a workspace is selected instead of a default "Sports" desk. If that happens, use the following helper in your test to ensure a correct desk is selected.

`await monitoring.selectDeskOrWorkspace('Sports');`
10 changes: 5 additions & 5 deletions e2e/client/playwright/.auth/user.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
{
"name": "session",
"value": "eyJzZXNzaW9uX3Rva2VuIjoiMDc5ZmI2M2MtZGM5OC00NTBmLWEzM2UtYzE5NzkzNzU2ZGYxIn0.Za43nw.4OjKgOWCcJ3oxa0kHscH-h47aLo",
"value": "eyJzZXNzaW9uX3Rva2VuIjoiN2VjM2UzYjUtOTc0NC00YjAyLWEzZjktNjdhMjY5NjYzNzMzIn0.Zqu1EQ.jLabsVCRMPN6BkZpxSQnDvNltcs",
"domain": "localhost",
"path": "/",
"expires": -1,
Expand All @@ -27,19 +27,19 @@
"localStorage": [
{
"name": "sess:id",
"value": "65ae379f77677941642bb478"
"value": "66abb510f2ff97e74a138403"
},
{
"name": "sess:href",
"value": "auth_db/65ae379f77677941642bb478"
"value": "auth_db/66abb510f2ff97e74a138403"
},
{
"name": "sess:user",
"value": "{\"_id\":\"655494d8dfb36babb9663383\",\"username\":\"admin\",\"email\":\"[email protected]\",\"user_type\":\"administrator\",\"is_active\":true,\"is_support\":false,\"needs_activation\":false,\"is_author\":true,\"private\":false,\"is_enabled\":true,\"password_changed_on\":\"2023-11-15T09:52:24+0000\",\"display_name\":\"admin\",\"sign_off\":\"ADM\",\"role\":null,\"_created\":\"2023-11-15T09:52:24+0000\",\"_updated\":\"2024-01-22T09:38:39+0000\",\"_etag\":\"d7adcb6bc3104208aacdfefeeefd7a01f8949663\",\"invisible_stages\":[],\"last_activity_at\":\"2024-01-22T09:38:39+0000\",\"_links\":{\"self\":{\"title\":\"User\",\"href\":\"users/655494d8dfb36babb9663383\"},\"parent\":{\"title\":\"home\",\"href\":\"/\"},\"collection\":{\"title\":\"users\",\"href\":\"users\"}},\"dateline_source\":\"Short name for your organisation\"}"
"value": "{\"_id\":\"655494d8dfb36babb9663383\",\"username\":\"admin\",\"email\":\"[email protected]\",\"user_type\":\"administrator\",\"is_active\":true,\"is_support\":false,\"needs_activation\":false,\"is_author\":true,\"private\":false,\"is_enabled\":true,\"password_changed_on\":\"2023-11-15T09:52:24+0000\",\"display_name\":\"John Doe\",\"sign_off\":\"ADM\",\"role\":null,\"_created\":\"2023-11-15T09:52:24+0000\",\"_updated\":\"2024-08-01T16:17:20+0000\",\"_etag\":\"618b115f9c52f9af13cd7ac4326665a5c42947b4\",\"invisible_stages\":[],\"last_activity_at\":\"2024-08-01T16:17:20+0000\",\"first_name\":\"John\",\"last_name\":\"Doe\",\"desk\":\"6554951a71839faddb615a2a\",\"_links\":{\"self\":{\"title\":\"User\",\"href\":\"users/655494d8dfb36babb9663383\"},\"related\":{\"desk\":{\"title\":\"Desk\",\"href\":\"desks/6554951a71839faddb615a2a\"}},\"parent\":{\"title\":\"home\",\"href\":\"/\"},\"collection\":{\"title\":\"users\",\"href\":\"users\"}},\"dateline_source\":\"Short name for your organisation\"}"
},
{
"name": "sess:token",
"value": "Basic MDc5ZmI2M2MtZGM5OC00NTBmLWEzM2UtYzE5NzkzNzU2ZGYxOg=="
"value": "Basic N2VjM2UzYjUtOTc0NC00YjAyLWEzZjktNjdhMjY5NjYzNzMzOg=="
}
]
}
Expand Down
16 changes: 13 additions & 3 deletions e2e/client/playwright/article-send-to.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
await new TreeSelectDriver(
page,
page.locator(s('destination-select')),
).setValue(['Educations']);
).setValue(['Education']);
await page
.locator(s('interactive-actions-panel', 'stage-select'))
.getByRole('radio', {name: 'Working Stage'})
Expand All @@ -33,9 +33,9 @@
await expect(
page.locator(s('monitoring-group=Sports / Working Stage', 'article-item=story 2')),
).not.toBeVisible();
await monitoring.selectDeskOrWorkspace('Educations');
await monitoring.selectDeskOrWorkspace('Education');
await expect(
page.locator(s('monitoring-group=Educations / Working Stage', 'article-item=story 2')),
page.locator(s('monitoring-group=Education / Working Stage', 'article-item=story 2')),
).toBeVisible();
});

Expand Down Expand Up @@ -69,3 +69,13 @@
).toBeVisible();
});
});

test('only members can switch to a desk', async ({page}) => {
await restoreDatabaseSnapshot();
await page.goto('/#/workspace/monitoring');
await page.locator(s('monitoring--selected-desk')).click();

await expect(page.locator(`${s('monitoring--select-desk-options')} button`, {hasText: 'Sport'})).toBeVisible();
await expect(page.locator(`${s('monitoring--select-desk-options')} button`, {hasText: 'Science'})).not.toBeVisible();

Check failure on line 79 in e2e/client/playwright/article-send-to.spec.ts

View workflow job for this annotation

GitHub Actions / test

This line has a length of 121. Maximum allowed is 120

Check failure on line 79 in e2e/client/playwright/article-send-to.spec.ts

View workflow job for this annotation

GitHub Actions / test

This line has a length of 121. Maximum allowed is 120

Check failure on line 79 in e2e/client/playwright/article-send-to.spec.ts

View workflow job for this annotation

GitHub Actions / test

This line has a length of 121. Maximum allowed is 120
});

67 changes: 66 additions & 1 deletion e2e/client/playwright/desks.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,72 @@
import {test, expect} from '@playwright/test';
import {restoreDatabaseSnapshot, s} from './utils';
import {restoreDatabaseSnapshot, s, withTestContext} from './utils';
import {Monitoring} from './page-object-models/monitoring';

test('adding a desk', async ({page}) => {
await restoreDatabaseSnapshot();

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

await page.locator(s('add-new-desk')).click();

await withTestContext('desk-config-modal', async ({cs}) => {
await page.locator(cs('field--name')).fill('desk 7');
await page.locator(cs('field--source')).fill('from desk 7');
await page.locator(cs('field--default-content-template')).selectOption('story 2');
await page.locator(cs('field--default-content-profile')).selectOption('Story');
await page.locator(cs('field--desk-type')).selectOption('production');
await page.locator(cs('done')).click();
});

await expect(page.locator(s('desk--desk 7'))).toBeVisible();
});

test('deleting a desk', async ({page}) => {
await restoreDatabaseSnapshot();

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

await page.locator('[data-test-id="desk--Education"] [data-test-id="desk-actions"]').click();
await page.locator('[data-test-id="desk--Education"] [data-test-id="desk-actions--remove"]').click();
await page.locator('[data-test-id="modal-confirm"]').getByRole('button', {name: 'OK'}).click();
await expect(page.locator('[data-test-id="desk--Education"]')).not.toBeVisible();
});

test('desk deletion being blocked if desk has published articles', async ({page}) => {
await restoreDatabaseSnapshot();

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

await page.locator('[data-test-id="desk--Finance"] [data-test-id="desk-actions"]').click();
await page.locator('[data-test-id="desk--Finance"] [data-test-id="desk-actions--remove"]').click();
await page.locator('[data-test-id="modal-confirm"]').getByRole('button', {name: 'OK'}).click();
await expect(page.getByText(
'Error: Cannot delete desk as it has article(s) or referenced by versions of the article(s).',
)).toBeVisible();

await page.reload();

await expect(page.locator('[data-test-id="desk--Finance"]')).toBeVisible({timeout: 5000});
});


test('desk deletion being blocked if a user has it assigned as default desk', async ({page}) => {
await restoreDatabaseSnapshot();

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

await page.locator('[data-test-id="desk--Sports"] [data-test-id="desk-actions"]').click();
await page.locator('[data-test-id="desk--Sports"] [data-test-id="desk-actions--remove"]').click();
await page.locator('[data-test-id="modal-confirm"]').getByRole('button', {name: 'OK'}).click();
await expect(page.getByText(
'Error: Cannot delete desk as it is assigned as default desk to user(s).',
)).toBeVisible();

await page.reload();

await expect(page.locator('[data-test-id="desk--Sports"]')).toBeVisible({timeout: 5000});
});

/**
* when a desk is mentioned in article comments,
* a notification must show up next to an incoming stage of that desk
Expand Down
4 changes: 2 additions & 2 deletions e2e/client/playwright/hightlights.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ test.describe('highlights', async () => {
await page.locator(s('workspace-navigation')).getByRole('button', {name: 'Highlights'}).hover();
await expect(page.locator(s('workspace-navigation')).getByRole('button', {name: 'Highlight 2'})).toBeVisible();

await monitoring.selectDeskOrWorkspace('Educations');
await monitoring.selectDeskOrWorkspace('Education');
await page.locator(s('workspace-navigation')).getByRole('button', {name: 'Highlights'}).hover();
await expect(page.locator(s('workspace-navigation')).getByRole('button', {name: 'Highlight 2'})).toBeVisible();
});
Expand All @@ -42,7 +42,7 @@ test.describe('highlights', async () => {
await page.locator(s('workspace-navigation')).getByRole('button', {name: 'Highlights'}).hover();
await expect(page.locator(s('workspace-navigation')).getByRole('button', {name: 'Highlight 2'})).toBeVisible();

await monitoring.selectDeskOrWorkspace('Educations');
await monitoring.selectDeskOrWorkspace('Education');
await page.locator(s('workspace-navigation')).getByRole('button', {name: 'Highlights'}).hover();
await expect(
page.locator(s('workspace-navigation')).getByRole('button', {name: 'Highlight 2'}),
Expand Down
40 changes: 40 additions & 0 deletions e2e/client/playwright/monitoring.publishing.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {test, expect} from '@playwright/test';
import {Monitoring} from './page-object-models/monitoring';
import {restoreDatabaseSnapshot, s} from './utils';
import {TreeSelectDriver} from './utils/tree-select-driver';

test('publishing an article from a different desk', async ({page}) => {
const monitoring = new Monitoring(page);

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

await monitoring.selectDeskOrWorkspace('Education');
await expect(
page.locator(s('monitoring-group=Education desk output', 'article-item=story 2')),
).not.toBeVisible();

await monitoring.selectDeskOrWorkspace('Sports');

await monitoring.executeActionOnMonitoringItem(
page.locator(s('monitoring-group=Sports / Working Stage', 'article-item=story 2')),
'Edit',
);

await page.locator(s('authoring-topbar', 'open-send-publish-pane')).click();
await page.locator(s('interactive-actions-panel', 'tabs')).getByRole('tab', {name: 'Publish'}).click();

await new TreeSelectDriver(
page,
page.locator(s('destination-select')),
).setValue(['Education']);

await page.locator(s('interactive-actions-panel')).getByRole('button', {name: 'Publish from'}).click();

await monitoring.selectDeskOrWorkspace('Education');
await expect(
page.locator(s('monitoring-group=Education desk output', 'article-item=story 2')),
).toBeVisible();
});


20 changes: 17 additions & 3 deletions e2e/client/playwright/monitoring.spiking.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ test('spiking and unspiking an article', async ({page}) => {

await monitoring.selectDeskOrWorkspace('Sports');

// spike article
await monitoring.executeActionOnMonitoringItem(
page.locator(s('article-item=story 2')),
'Spike Item',
Expand All @@ -21,7 +20,7 @@ test('spiking and unspiking an article', async ({page}) => {
await expect(page.locator(s('monitoring-view', 'article-item=story 2'))).not.toBeVisible();

// go to spike item list and check visibility of article
await page.locator(s('Spiked Items')).click();
await page.goto('/#/workspace/spike-monitoring');
await expect(page.locator(s('articles-list', 'article-item=story 2'))).toBeVisible();

// unspike article
Expand All @@ -36,4 +35,19 @@ test('spiking and unspiking an article', async ({page}) => {
// go to monitoring and check visibility of article
await page.goto('/#/workspace/monitoring');
await expect(page.locator(s('monitoring-view', 'article-item=story 2'))).toBeVisible();
});
});

test('spiked view respecting the selected desk', async ({page}) => {
const monitoring = new Monitoring(page);

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

await monitoring.selectDeskOrWorkspace('Sports');
await expect(page.locator(s('articles-list', 'article-item=Spiked article from sport desk'))).toBeVisible();
await expect(page.locator(s('articles-list', 'article-item=Spiked article from education desk'))).not.toBeVisible();

await monitoring.selectDeskOrWorkspace('Education');
await expect(page.locator(s('articles-list', 'article-item=Spiked article from education desk'))).toBeVisible();
await expect(page.locator(s('articles-list', 'article-item=Spiked article from sport desk'))).not.toBeVisible();
});
6 changes: 3 additions & 3 deletions e2e/client/playwright/templates.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ test('assigning template to a desk', async ({page}) => {

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

await page.locator(s('content-create')).click();
await page.locator(s('content-create-dropdown')).getByRole('button', {name: 'More Templates...'}).click();
Expand All @@ -55,12 +55,12 @@ test('assigning template to a desk', async ({page}) => {
await page.locator(s('template-content', 'content-template=story 2', 'template-actions')).click();
await page.locator(s('template-actions--options')).getByRole('button', {name: 'Edit'}).click();
// toggling button from 'off' to 'on'
await page.locator(s('template-edit-view', 'desks', 'desk--Finances')).click();
await page.locator(s('template-edit-view', 'desks', 'desk--Finance')).click();
await page.locator(s('template-edit-view')).getByRole('button', {name: 'Save'}).click();
await expect(page.locator(s('template-edit-view'))).not.toBeVisible();

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

await page.locator(s('content-create')).click();
await page.locator(s('content-create-dropdown')).getByRole('button', {name: 'More Templates...'}).click();
Expand Down
33 changes: 33 additions & 0 deletions e2e/client/playwright/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,36 @@ export function sleep(ms: number): Promise<void> {
setTimeout(resolve, ms);
});
}

/**
* A helper to make code shorter, but maintain selector scoping.
*
* Without this helper:
*
* ```
* await page.locator(s('desk-config-modal', 'field--name')).fill('desk 7');
* await page.locator(s('desk-config-modal', 'field--source')).fill('desk 7');
* await page.locator(s('desk-config-modal')).getByRole('button', {name: 'test'}).click();
* ```
*
* With this helper:
* ```
* await withTestContext('desk-config-modal', async ({cs}) => {
* await page.locator(cs('field--name')).fill('desk 7');
* await page.locator(cs('field--source')).fill('from desk 7');
* await page.locator(cs()).getByRole('button', {name: 'test'}).click();
* });
*/
export function withTestContext(
selector: string,
callback: (
options: {
// cs - contextualized selector
cs: (...testIds: Array<string>) => string;
}
) => Promise<void>,
): Promise<void> {
const getTestSelectorWithContext = (...testIds: Array<string>) => getTestSelector(selector, ...testIds);

return callback({cs: getTestSelectorWithContext});
}
1 change: 0 additions & 1 deletion e2e/server/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
name: superdesk-client-core_e2e
version: "3.2"
services:
redis:
image: redis:alpine
Expand Down
Binary file not shown.
Binary file modified e2e/server/dump/full/main/contentapi_e2e/items.json.bz2
Binary file not shown.
Binary file modified e2e/server/dump/full/main/contentapi_e2e/items_versions.json.bz2
Binary file not shown.
Binary file not shown.
Binary file modified e2e/server/dump/full/main/superdesk_e2e/activity.json.bz2
Binary file not shown.
Binary file modified e2e/server/dump/full/main/superdesk_e2e/archive.json.bz2
Binary file not shown.
Binary file modified e2e/server/dump/full/main/superdesk_e2e/archive_history.json.bz2
Binary file not shown.
Binary file not shown.
Binary file modified e2e/server/dump/full/main/superdesk_e2e/audit.json.bz2
Binary file not shown.
Binary file modified e2e/server/dump/full/main/superdesk_e2e/auth.json.bz2
Binary file not shown.
Binary file modified e2e/server/dump/full/main/superdesk_e2e/content_templates.json.bz2
Binary file not shown.
Binary file modified e2e/server/dump/full/main/superdesk_e2e/desks.json.bz2
Binary file not shown.
Binary file modified e2e/server/dump/full/main/superdesk_e2e/published.json.bz2
Binary file not shown.
Binary file not shown.
Binary file modified e2e/server/dump/full/main/superdesk_e2e/sequences.json.bz2
Binary file not shown.
Binary file modified e2e/server/dump/full/main/superdesk_e2e/stages.json.bz2
Binary file not shown.
Binary file modified e2e/server/dump/full/main/superdesk_e2e/users.json.bz2
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
15 changes: 6 additions & 9 deletions scripts/apps/monitoring/controllers/AggregateCtrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,12 @@ export function AggregateCtrl($scope, desks, workspaces, preferencesService, sto
});
}));
}))
.then(angular.bind(this, function() {
return this.readSettings()
.then(angular.bind(this, function(settings) {
initGroups(settings);
setupCards();
this.settings = settings;
getActiveProfiles();
}));
}));
.then(() => Promise.all([this.readSettings(), getActiveProfiles()]))
.then(([settings, _]) => {
initGroups(settings);
setupCards();
this.settings = settings;
});

/**
* If view showed as widget set the current widget
Expand Down
2 changes: 2 additions & 0 deletions scripts/core/editor3/html/tests/to-html.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {editor3StateToHtml} from '../to-html/editor3StateToHtml';
import {CustomEditor3Entity} from 'core/editor3/constants';

describe('core.editor3.html.to-html snapshots', () => {
beforeEach(window.module('superdesk.apps.spellcheck'));

it('converts a sentence without formatting', () => {
const rawContentState: any = {"blocks":[{"key":"fcbn3","text":"The name of Highlaws comes from the Old English hēah-hlāw, meaning \"high mounds\".","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{"MULTIPLE_HIGHLIGHTS":{}}}],"entityMap":{}};

Expand Down
Loading