🚨(tests) add language related tests; fix getByRole not working in tests

- adds tests and test-utility for solid language switching in tests
- fixes where ...getByRole(menuitem... would not return a valid object
This commit is contained in:
rvveber
2025-02-25 15:44:33 +01:00
committed by Samuel Paccoud
parent f95173e096
commit 251787b835
8 changed files with 136 additions and 175 deletions

View File

@@ -97,7 +97,7 @@ export const addNewMember = async (
// Choose a role
await page.getByLabel('doc-role-dropdown').click();
await page.getByRole('menuitem', { name: role }).click();
await page.getByLabel(role).click();
await page.getByRole('button', { name: 'Invite' }).click();
return users[index].email;

View File

@@ -15,41 +15,6 @@ test.beforeEach(async ({ page }) => {
});
test.describe('Doc Editor', () => {
test('it check translations of the slash menu when changing language', async ({
page,
browserName,
}) => {
await createDoc(page, 'doc-toolbar', browserName, 1);
const header = page.locator('header').first();
const editor = page.locator('.ProseMirror');
// Trigger slash menu to show english menu
await editor.click();
await editor.fill('/');
await expect(page.getByText('Headings', { exact: true })).toBeVisible();
await header.click();
await expect(page.getByText('Headings', { exact: true })).toBeHidden();
// Reset menu
await editor.click();
await editor.fill('');
// Change language to French
await header.click();
await header.getByRole('button', { name: /Language/ }).click();
await page.getByRole('menuitem', { name: 'Français' }).click();
await expect(
header.getByRole('button').getByText('Français'),
).toBeVisible();
// Trigger slash menu to show french menu
await editor.click();
await editor.fill('/');
await expect(page.getByText('Titres', { exact: true })).toBeVisible();
await header.click();
await expect(page.getByText('Titres', { exact: true })).toBeHidden();
});
test('it checks default toolbar buttons are displayed', async ({
page,
browserName,
@@ -128,11 +93,7 @@ test.describe('Doc Editor', () => {
const wsClosePromise = webSocket.waitForEvent('close');
await selectVisibility.click();
await page
.getByRole('menuitem', {
name: 'Connected',
})
.click();
await page.getByLabel('Connected').click();
// Assert that the doc reconnects to the ws
const wsClose = await wsClosePromise;

View File

@@ -88,11 +88,7 @@ test.describe('Doc Header', () => {
const [randomDoc] = await createDoc(page, 'doc-delete', browserName, 1);
await page.getByLabel('Open the document options').click();
await page
.getByRole('menuitem', {
name: 'Delete document',
})
.click();
await page.getByLabel('Delete document').click();
await expect(
page.getByRole('heading', { name: 'Delete a doc' }),
@@ -150,9 +146,7 @@ test.describe('Doc Header', () => {
await page.getByLabel('Open the document options').click();
await expect(
page.getByRole('menuitem', { name: 'Delete document' }),
).toBeDisabled();
await expect(page.getByLabel('Delete document')).toBeDisabled();
// Click somewhere else to close the options
await page.click('body', { position: { x: 0, y: 0 } });
@@ -174,11 +168,7 @@ test.describe('Doc Header', () => {
await invitationCard.getByRole('button', { name: 'more_horiz' }).click();
await expect(
page.getByRole('menuitem', {
name: 'delete',
}),
).toBeEnabled();
await expect(page.getByLabel('Delete')).toBeEnabled();
await invitationCard.click();
const memberCard = shareModal.getByLabel('List members card');
@@ -192,11 +182,7 @@ test.describe('Doc Header', () => {
).toBeVisible();
await memberCard.getByRole('button', { name: 'more_horiz' }).click();
await expect(
page.getByRole('menuitem', {
name: 'delete',
}),
).toBeEnabled();
await expect(page.getByLabel('Delete')).toBeEnabled();
});
test('it checks the options available if editor', async ({ page }) => {
@@ -230,9 +216,7 @@ test.describe('Doc Header', () => {
await expect(page.getByRole('button', { name: 'download' })).toBeVisible();
await page.getByLabel('Open the document options').click();
await expect(
page.getByRole('menuitem', { name: 'Delete document' }),
).toBeDisabled();
await expect(page.getByLabel('Delete document')).toBeDisabled();
// Click somewhere else to close the options
await page.click('body', { position: { x: 0, y: 0 } });
@@ -292,9 +276,7 @@ test.describe('Doc Header', () => {
await expect(page.getByRole('button', { name: 'download' })).toBeVisible();
await page.getByLabel('Open the document options').click();
await expect(
page.getByRole('menuitem', { name: 'Delete document' }),
).toBeDisabled();
await expect(page.getByLabel('Delete document')).toBeDisabled();
// Click somewhere else to close the options
await page.click('body', { position: { x: 0, y: 0 } });
@@ -350,7 +332,7 @@ test.describe('Doc Header', () => {
// Copy content to clipboard
await page.getByLabel('Open the document options').click();
await page.getByRole('menuitem', { name: 'Copy as Markdown' }).click();
await page.getByLabel('Copy as Markdown').click();
await expect(page.getByText('Copied to clipboard')).toBeVisible();
// Test that clipboard is in Markdown format
@@ -385,7 +367,7 @@ test.describe('Doc Header', () => {
// Copy content to clipboard
await page.getByLabel('Open the document options').click();
await page.getByRole('menuitem', { name: 'Copy as HTML' }).click();
await page.getByLabel('Copy as HTML').click();
await expect(page.getByText('Copied to clipboard')).toBeVisible();
// Test that clipboard is in HTML format
@@ -458,7 +440,7 @@ test.describe('Documents Header mobile', () => {
await expect(page.getByRole('button', { name: 'Copy link' })).toBeHidden();
await page.getByLabel('Open the document options').click();
await page.getByRole('menuitem', { name: 'Share' }).click();
await page.getByLabel('Share').click();
await page.getByRole('button', { name: 'Copy link' }).click();
await expect(page.getByText('Link Copied !')).toBeVisible();
// Test that clipboard is in HTML format
@@ -492,7 +474,7 @@ test.describe('Documents Header mobile', () => {
await goToGridDoc(page);
await page.getByLabel('Open the document options').click();
await page.getByRole('menuitem', { name: 'Share' }).click();
await page.getByLabel('Share').click();
await expect(page.getByLabel('Share modal')).toBeVisible();
await page.getByRole('button', { name: 'close' }).click();

View File

@@ -65,15 +65,13 @@ test.describe('Document create member', () => {
// Check roles are displayed
await list.getByLabel('doc-role-dropdown').click();
await expect(page.getByRole('menuitem', { name: 'Reader' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Editor' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Owner' })).toBeVisible();
await expect(
page.getByRole('menuitem', { name: 'Administrator' }),
).toBeVisible();
await expect(page.getByLabel('Reader')).toBeVisible();
await expect(page.getByLabel('Editor')).toBeVisible();
await expect(page.getByLabel('Owner')).toBeVisible();
await expect(page.getByLabel('Administrator')).toBeVisible();
// Validate
await page.getByRole('menuitem', { name: 'Administrator' }).click();
await page.getByLabel('Administrator').click();
await page.getByRole('button', { name: 'Invite' }).click();
// Check invitation added
@@ -121,7 +119,7 @@ test.describe('Document create member', () => {
// Choose a role
const container = page.getByTestId('doc-share-add-member-list');
await container.getByLabel('doc-role-dropdown').click();
await page.getByRole('menuitem', { name: 'Owner' }).click();
await page.getByLabel('Owner').click();
const responsePromiseCreateInvitation = page.waitForResponse(
(response) =>
@@ -139,7 +137,7 @@ test.describe('Document create member', () => {
// Choose a role
await container.getByLabel('doc-role-dropdown').click();
await page.getByRole('menuitem', { name: 'Owner' }).click();
await page.getByLabel('Owner').click();
const responsePromiseCreateInvitationFail = page.waitForResponse(
(response) =>
@@ -155,47 +153,6 @@ test.describe('Document create member', () => {
expect(responseCreateInvitationFail.ok()).toBeFalsy();
});
test('The invitation endpoint get the language of the website', async ({
page,
browserName,
}) => {
await createDoc(page, 'user-invitation', browserName, 1);
const header = page.locator('header').first();
await header.getByRole('button', { name: /Language/ }).click();
await page.getByRole('menuitem', { name: 'Français' }).click();
await page.getByRole('button', { name: 'Partager' }).click();
const inputSearch = page.getByRole('combobox', {
name: 'Saisie de recherche rapide',
});
const email = randomName('test@test.fr', browserName, 1)[0];
await inputSearch.fill(email);
await page.getByTestId(`search-user-row-${email}`).click();
// Choose a role
const container = page.getByTestId('doc-share-add-member-list');
await container.getByLabel('doc-role-dropdown').click();
await page.getByRole('menuitem', { name: 'Administrateur' }).click();
const responsePromiseCreateInvitation = page.waitForResponse(
(response) =>
response.url().includes('/invitations/') && response.status() === 201,
);
await page.getByRole('button', { name: 'Invite' }).click();
// Check invitation sent
const responseCreateInvitation = await responsePromiseCreateInvitation;
expect(responseCreateInvitation.ok()).toBeTruthy();
expect(
responseCreateInvitation.request().headers()['content-language'],
).toBe('fr-fr');
});
test('it manages invitation', async ({ page, browserName }) => {
await createDoc(page, 'user-invitation', browserName, 1);
@@ -212,7 +169,7 @@ test.describe('Document create member', () => {
// Choose a role
const container = page.getByTestId('doc-share-add-member-list');
await container.getByLabel('doc-role-dropdown').click();
await page.getByRole('menuitem', { name: 'Administrator' }).click();
await page.getByLabel('Administrator').click();
const responsePromiseCreateInvitation = page.waitForResponse(
(response) =>
@@ -232,14 +189,14 @@ test.describe('Document create member', () => {
await expect(userInvitation).toBeVisible();
await userInvitation.getByLabel('doc-role-dropdown').click();
await page.getByRole('menuitem', { name: 'Reader' }).click();
await page.getByLabel('Reader').click();
const moreActions = userInvitation.getByRole('button', {
name: 'more_horiz',
});
await moreActions.click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByLabel('Delete').click();
await expect(userInvitation).toBeHidden();
});

View File

@@ -161,12 +161,12 @@ test.describe('Document list members', () => {
await list.click();
await currentUserRole.click();
await page.getByRole('menuitem', { name: 'Administrator' }).click();
await page.getByLabel('Administrator').click();
await list.click();
await expect(currentUserRole).toBeVisible();
await currentUserRole.click();
await page.getByRole('menuitem', { name: 'Reader' }).click();
await page.getByLabel('Reader').click();
await list.click();
await expect(currentUserRole).toBeHidden();
});
@@ -215,11 +215,11 @@ test.describe('Document list members', () => {
await expect(mySelfMoreActions).toBeVisible();
await userReaderMoreActions.click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByLabel('Delete').click();
await expect(userReader).toBeHidden();
await mySelfMoreActions.click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByLabel('Delete').click();
await expect(
page.getByText('You do not have permission to view this document.'),
).toBeVisible();

View File

@@ -18,11 +18,7 @@ test.describe('Doc Version', () => {
await verifyDocName(page, randomDoc);
await page.getByLabel('Open the document options').click();
await page
.getByRole('menuitem', {
name: 'Version history',
})
.click();
await page.getByLabel('Version history').click();
await expect(page.getByText('History', { exact: true })).toBeVisible();
const modal = page.getByLabel('version history modal');
@@ -58,11 +54,7 @@ test.describe('Doc Version', () => {
).toBeVisible();
await page.getByLabel('Open the document options').click();
await page
.getByRole('menuitem', {
name: 'Version history',
})
.click();
await page.getByLabel('Version history').click();
await expect(panel).toBeVisible();
await expect(page.getByText('History', { exact: true })).toBeVisible();
@@ -90,9 +82,7 @@ test.describe('Doc Version', () => {
await verifyDocName(page, 'Mocked document');
await page.getByLabel('Open the document options').click();
await expect(
page.getByRole('menuitem', { name: 'Version history' }),
).toBeDisabled();
await expect(page.getByLabel('Version history')).toBeDisabled();
});
test('it restores the doc version', async ({ page, browserName }) => {
@@ -119,11 +109,7 @@ test.describe('Doc Version', () => {
await expect(page.getByText('World')).toBeVisible();
await page.getByLabel('Open the document options').click();
await page
.getByRole('menuitem', {
name: 'Version history',
})
.click();
await page.getByLabel('Version history').click();
const modal = page.getByLabel('version history modal');
const panel = modal.getByLabel('version list');

View File

@@ -49,21 +49,13 @@ test.describe('Doc Visibility', () => {
await expect(page.getByLabel('Can read and edit')).toBeHidden();
await selectVisibility.click();
await page
.getByRole('menuitem', {
name: 'Connected',
})
.click();
await page.getByLabel('Connected').click();
await expect(page.getByLabel('Visibility mode')).toBeVisible();
await selectVisibility.click();
await page
.getByRole('menuitem', {
name: 'Public',
})
.click();
await page.getByLabel('Public', { exact: true }).click();
await expect(page.getByLabel('Visibility mode')).toBeVisible();
});
@@ -162,7 +154,7 @@ test.describe('Doc Visibility: Restricted', () => {
// Choose a role
const container = page.getByTestId('doc-share-add-member-list');
await container.getByLabel('doc-role-dropdown').click();
await page.getByRole('menuitem', { name: 'Administrator' }).click();
await page.getByLabel('Administrator').click();
await page.getByRole('button', { name: 'Invite' }).click();

View File

@@ -1,19 +1,41 @@
import { expect, test } from '@playwright/test';
import { Page, expect, test } from '@playwright/test';
test.beforeEach(async ({ page }) => {
await page.goto('/');
});
import { createDoc } from './common';
test.describe('Language', () => {
test('checks the language picker', async ({ page }) => {
await expect(page.getByLabel('Logout')).toBeVisible();
test.describe.serial('Language', () => {
let page: Page;
test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
});
test.afterAll(async () => {
await page.close();
});
test.beforeEach(async ({ page }) => {
await page.goto('/');
await waitForLanguageSwitch(page, TestLanguage.English);
});
test.afterEach(async ({ page }) => {
// Switch back to English - important for other tests to run as expected
await waitForLanguageSwitch(page, TestLanguage.English);
});
test('checks language switching', async ({ page }) => {
const header = page.locator('header').first();
await header
.getByRole('button', { name: /Language/ })
.getByText('English')
.click();
await page.getByRole('menuitem', { name: 'Français' }).click();
// initial language should be english
await expect(
page.getByRole('button', {
name: 'New doc',
}),
).toBeVisible();
// switch to french
await waitForLanguageSwitch(page, TestLanguage.French);
await expect(
header.getByRole('button').getByText('Français'),
).toBeVisible();
@@ -21,7 +43,7 @@ test.describe('Language', () => {
await expect(page.getByLabel('Se déconnecter')).toBeVisible();
await header.getByRole('button').getByText('Français').click();
await page.getByRole('menuitem', { name: 'Deutsch' }).click();
await page.getByLabel('Deutsch').click();
await expect(header.getByRole('button').getByText('Deutsch')).toBeVisible();
await expect(page.getByLabel('Abmelden')).toBeVisible();
@@ -52,15 +74,76 @@ test.describe('Language', () => {
// Check for English 404 response
await check404Response('Not found.');
// Switch language to French
const header = page.locator('header').first();
await header
.getByRole('button', { name: /Language/ })
.getByText('English')
.click();
await page.getByRole('menuitem', { name: 'Français' }).click();
await waitForLanguageSwitch(page, TestLanguage.French);
// Check for French 404 response
await check404Response('Pas trouvé.');
});
test('it check translations of the slash menu when changing language', async ({
page,
browserName,
}) => {
await createDoc(page, 'doc-toolbar', browserName, 1);
const header = page.locator('header').first();
const editor = page.locator('.ProseMirror');
// Trigger slash menu to show english menu
await editor.click();
await editor.fill('/');
await expect(page.getByText('Headings', { exact: true })).toBeVisible();
await header.click();
await expect(page.getByText('Headings', { exact: true })).toBeHidden();
// Reset menu
await editor.click();
await editor.fill('');
// Change language to French
await waitForLanguageSwitch(page, TestLanguage.French);
// Trigger slash menu to show french menu
await editor.click();
await editor.fill('/');
await expect(page.getByText('Titres', { exact: true })).toBeVisible();
await header.click();
await expect(page.getByText('Titres', { exact: true })).toBeHidden();
});
});
// language helper
export const TestLanguage = {
English: {
label: 'English',
expectedLocale: ['en-us'],
},
French: {
label: 'Français',
expectedLocale: ['fr-fr'],
},
German: {
label: 'Deutsch',
expectedLocale: ['de-de'],
},
} as const;
type TestLanguageKey = keyof typeof TestLanguage;
type TestLanguageValue = (typeof TestLanguage)[TestLanguageKey];
export async function waitForLanguageSwitch(
page: Page,
lang: TestLanguageValue,
) {
const header = page.locator('header').first();
await header.getByRole('button', { name: 'arrow_drop_down' }).click();
const responsePromise = page.waitForResponse(
(resp) =>
resp.url().includes('/user') && resp.request().method() === 'PATCH',
);
await page.getByLabel(lang.label).click();
const resolvedResponsePromise = await responsePromise;
const responseData = await resolvedResponsePromise.json();
expect(lang.expectedLocale).toContain(responseData.language);
}