(frontend) enhance tests

- Removed 'feature/doc-dnd' branch from the Docker Hub workflow to
streamline deployment processes.
- Updated document creation tests to replace 'New page' button
references with 'New doc' for consistency.
- Enhanced test cases to improve clarity and ensure accurate
verification of document functionalities.
- Added new utility function for creating root subpages, improving test
maintainability.
This commit is contained in:
Nathan Panchout
2025-07-02 14:33:57 +02:00
committed by Anthony LC
parent 44909faa67
commit 82f2cb59e6
11 changed files with 117 additions and 307 deletions

View File

@@ -2,4 +2,4 @@
BURST_THROTTLE_RATES="200/minute"
COLLABORATION_API_URL=http://y-provider:4444/collaboration/api/
SUSTAINED_THROTTLE_RATES="200/hour"
Y_PROVIDER_API_BASE_URL=http://y-provider:4444/api/
Y_PROVIDER_API_BASE_URL=http://y-provider:4444/api/

View File

@@ -90,7 +90,7 @@ export const createDoc = async (
await page
.getByRole('button', {
name: isChild ? 'New page' : 'New doc',
name: 'New doc',
})
.click();
@@ -220,6 +220,7 @@ export const updateDocTitle = async (page: Page, title: string) => {
await input.click();
await input.fill(title);
await input.click();
await input.blur();
await verifyDocName(page, title);
};
@@ -302,6 +303,24 @@ export const mockedListDocs = async (page: Page, data: object[] = []) => {
};
export const mockedInvitations = async (page: Page, json?: object) => {
let result = [
{
id: '120ec765-43af-4602-83eb-7f4e1224548a',
abilities: {
destroy: true,
update: true,
partial_update: true,
retrieve: true,
},
created_at: '2024-10-03T12:19:26.107687Z',
email: 'test@invitation.test',
document: '4888c328-8406-4412-9b0b-c0ba5b9e5fb6',
role: 'editor',
issuer: '7380f42f-02eb-4ad5-b8f0-037a0e66066d',
is_expired: false,
...json,
},
];
await page.route('**/invitations/**/', async (route) => {
const request = route.request();
if (
@@ -314,36 +333,33 @@ export const mockedInvitations = async (page: Page, json?: object) => {
count: 1,
next: null,
previous: null,
results: [
{
id: '120ec765-43af-4602-83eb-7f4e1224548a',
abilities: {
destroy: true,
update: true,
partial_update: true,
retrieve: true,
},
created_at: '2024-10-03T12:19:26.107687Z',
email: 'test@invitation.test',
document: '4888c328-8406-4412-9b0b-c0ba5b9e5fb6',
role: 'editor',
issuer: '7380f42f-02eb-4ad5-b8f0-037a0e66066d',
is_expired: false,
...json,
},
],
results: result,
},
});
} else {
await route.continue();
}
});
await page.route(
'**/invitations/120ec765-43af-4602-83eb-7f4e1224548a/**/',
async (route) => {
const request = route.request();
if (request.method().includes('DELETE')) {
result = [];
await route.fulfill({
json: {},
});
}
},
);
};
export const mockedAccesses = async (page: Page, json?: object) => {
await page.route('**/accesses/**/', async (route) => {
const request = route.request();
console.log('oui');
if (
request.method().includes('GET') &&
request.url().includes('accesses')

View File

@@ -72,6 +72,7 @@ test.describe('Doc Export', () => {
await page
.getByRole('button', {
name: 'download',
exact: true,
})
.click();
@@ -82,6 +83,7 @@ test.describe('Doc Export', () => {
void page
.getByRole('button', {
name: 'Download',
exact: true,
})
.click();
@@ -120,6 +122,7 @@ test.describe('Doc Export', () => {
await page
.getByRole('button', {
name: 'download',
exact: true,
})
.click();
@@ -129,6 +132,7 @@ test.describe('Doc Export', () => {
await expect(
page.getByRole('button', {
name: 'Download',
exact: true,
}),
).toBeVisible();
@@ -139,6 +143,7 @@ test.describe('Doc Export', () => {
void page
.getByRole('button', {
name: 'Download',
exact: true,
})
.click();
@@ -312,12 +317,14 @@ test.describe('Doc Export', () => {
await page
.getByRole('button', {
name: 'download',
exact: true,
})
.click();
await expect(
page.getByRole('button', {
name: 'Download',
exact: true,
}),
).toBeVisible();
@@ -328,6 +335,7 @@ test.describe('Doc Export', () => {
void page
.getByRole('button', {
name: 'Download',
exact: true,
})
.click();

View File

@@ -226,6 +226,8 @@ test.describe('Documents filters', () => {
await allDocs.click();
await page.waitForURL('**/?target=all_docs');
let url = new URL(page.url());
let target = url.searchParams.get('target');
expect(target).toBe('all_docs');

View File

@@ -69,11 +69,7 @@ test.describe('Doc Header', () => {
page.getByRole('heading', { name: 'Delete a doc' }),
).toBeVisible();
await expect(
page.getByText(
`Are you sure you want to delete the document "${randomDoc}"?`,
),
).toBeVisible();
await expect(page.getByText(`This document and any sub-`)).toBeVisible();
await page
.getByRole('button', {
@@ -134,32 +130,31 @@ test.describe('Doc Header', () => {
await expect(shareModal).toBeVisible();
await expect(page.getByText('Share the document')).toBeVisible();
// await expect(page.getByPlaceholder('Type a name or email')).toBeVisible();
const invitationCard = shareModal.getByLabel('List invitation card');
await expect(invitationCard).toBeVisible();
await expect(
invitationCard.getByText('test@invitation.test').first(),
).toBeVisible();
await expect(invitationCard.getByLabel('doc-role-dropdown')).toBeVisible();
const invitationRole = invitationCard.getByLabel('doc-role-dropdown');
await expect(invitationRole).toBeVisible();
await invitationCard.getByRole('button', { name: 'more_horiz' }).click();
await invitationRole.click();
await expect(page.getByLabel('Delete')).toBeEnabled();
await invitationCard.click();
await page.getByRole('menuitem', { name: 'Remove access' }).click();
await expect(invitationCard).toBeHidden();
const memberCard = shareModal.getByLabel('List members card');
const roles = memberCard.getByLabel('doc-role-dropdown');
await expect(memberCard).toBeVisible();
await expect(
memberCard.getByText('test@accesses.test').first(),
).toBeVisible();
await expect(memberCard.getByLabel('doc-role-dropdown')).toBeVisible();
await expect(
memberCard.getByRole('button', { name: 'more_horiz' }),
).toBeVisible();
await memberCard.getByRole('button', { name: 'more_horiz' }).click();
await expect(roles).toBeVisible();
await expect(page.getByLabel('Delete')).toBeEnabled();
await roles.click();
await expect(
page.getByRole('menuitem', { name: 'Remove access' }),
).toBeEnabled();
});
test('it checks the options available if editor', async ({ page }) => {

View File

@@ -1,108 +1,35 @@
import { expect, test } from '@playwright/test';
import { createDoc } from './common';
import {
addMemberToDoc,
searchUserToInviteToDoc,
updateShareLink,
verifyLinkReachIsDisabled,
verifyLinkReachIsEnabled,
verifyLinkRoleIsDisabled,
verifyLinkRoleIsEnabled,
verifyMemberAddedToDoc,
} from './share-utils';
import { createRootSubPage, createSubPageFromParent } from './sub-pages-utils';
import { createDoc, verifyDocName } from './common';
import { updateShareLink } from './share-utils';
import { createRootSubPage } from './sub-pages-utils';
test.describe('Inherited share accesses', () => {
test('it checks inherited accesses', async ({ page, browserName }) => {
await page.goto('/');
const [titleParent] = await createDoc(page, 'root-doc', browserName, 1);
const docTree = page.getByTestId('doc-tree');
const [parentTitle] = await createDoc(page, 'root-doc', browserName, 1);
const addButton = page.getByRole('button', { name: 'New page' });
// Wait for and intercept the POST request to create a new page
const responsePromise = page.waitForResponse(
(response) =>
response.url().includes('/documents/') &&
response.url().includes('/children/') &&
response.request().method() === 'POST',
);
await addButton.click();
await createRootSubPage(page, browserName, 'sub-page');
const response = await responsePromise;
expect(response.ok()).toBeTruthy();
const subPageJson = await response.json();
await expect(docTree).toBeVisible();
const subPageItem = docTree
.getByTestId(`doc-sub-page-item-${subPageJson.id}`)
.first();
await expect(subPageItem).toBeVisible();
await subPageItem.click();
await page.getByRole('button', { name: 'Share' }).click();
await expect(page.getByText('Inherited share')).toBeVisible();
await expect(page.getByRole('link', { name: titleParent })).toBeVisible();
await page.getByRole('button', { name: 'See access' }).click();
await expect(page.getByText('Access inherited from the')).toBeVisible();
await expect(
page.getByText('People with access via the parent document'),
).toBeVisible();
const user = page.getByTestId(
`doc-share-member-row-user@${browserName}.e2e`,
`doc-share-member-row-user@${browserName}.test`,
);
await expect(user).toBeVisible();
await expect(user.getByText('E2E Chromium')).toBeVisible();
await expect(user.getByText('Owner')).toBeVisible();
});
test('it checks that the highest role is displayed', async ({
page,
browserName,
}) => {
await page.goto('/');
await createDoc(page, 'root-doc', browserName, 1);
await page
.locator('.--docs--doc-inherited-share-content')
.getByRole('link')
.click();
// Search user to add
let users = await searchUserToInviteToDoc(page);
let userToAdd = users[0];
// Add user as Administrator in root doc
await addMemberToDoc(page, 'Administrator', [userToAdd]);
await verifyMemberAddedToDoc(page, userToAdd, 'Administrator');
await page.getByRole('button', { name: 'OK' }).click();
// Create sub page
const { name: subPageName, item: subPageJson } = await createRootSubPage(
page,
browserName,
'sub-page',
);
// Add user as Editor in sub page
users = await searchUserToInviteToDoc(page);
userToAdd = users[0];
await addMemberToDoc(page, 'Editor', [userToAdd]);
const userRow = await verifyMemberAddedToDoc(page, userToAdd, 'Editor');
await userRow.getByRole('button', { name: 'doc-role-dropdown' }).click();
await page.getByText('This user has access').click();
await userRow.click();
await page.getByRole('button', { name: 'OK' }).click();
// Add new sub page to sub page
await createSubPageFromParent(
page,
browserName,
subPageJson.id,
'sub-page-2',
);
// // Check sub page inherited share
await page.getByRole('button', { name: 'Share' }).click();
await expect(page.getByText('Inherited share')).toBeVisible();
await expect(page.getByRole('link', { name: subPageName })).toBeVisible();
await page.getByRole('button', { name: 'See access' }).click();
await expect(page.getByText('Access inherited from the')).toBeVisible();
const user = page.getByTestId(`doc-share-member-row-${userToAdd.email}`);
await expect(user).toBeVisible();
await expect(user.getByText('Administrator')).toBeVisible();
await verifyDocName(page, parentTitle);
});
});
@@ -122,87 +49,10 @@ test.describe('Inherited share link', () => {
// // verify share link is restricted and reader
await page.getByRole('button', { name: 'Share' }).click();
await expect(page.getByText('Inherited share')).toBeVisible();
// await verifyShareLink(page, 'Connected', 'Reading');
});
test('it checks warning message when sharing rules differ', async ({
page,
browserName,
}) => {
await page.goto('/');
// Create root doc
await createDoc(page, 'root-doc', browserName, 1);
// Update share link
await page.getByRole('button', { name: 'Share' }).click();
await updateShareLink(page, 'Connected', 'Reading');
await page.getByRole('button', { name: 'OK' }).click();
// Create sub page
await createRootSubPage(page, browserName, 'sub-page');
await page.getByRole('button', { name: 'Share' }).click();
// Update share link to public and edition
await updateShareLink(page, 'Public', 'Edition');
await expect(page.getByText('Sharing rules differ from the')).toBeVisible();
const restoreButton = page.getByRole('button', { name: 'Restore' });
await expect(restoreButton).toBeVisible();
await restoreButton.click();
await expect(
page.getByText('The document visibility has been updated').first(),
).toBeVisible();
await expect(page.getByText('Sharing rules differ from the')).toBeHidden();
});
test('it checks inherited link possibilities', async ({
page,
browserName,
}) => {
await page.goto('/');
// Create root doc
await createDoc(page, 'root-doc', browserName, 1);
// Update share link
await page.getByRole('button', { name: 'Share' }).click();
await updateShareLink(page, 'Connected', 'Reading');
await page.getByRole('button', { name: 'OK' }).click();
await expect(
page.getByText('Document accessible to any connected person'),
).toBeVisible();
// Create sub page
const { item: subPageItem } = await createRootSubPage(
page,
browserName,
'sub-page',
);
await expect(
page.getByText('Document accessible to any connected person'),
).toBeVisible();
// Update share link to public and edition
await page.getByRole('button', { name: 'Share' }).click();
await verifyLinkReachIsDisabled(page, 'Private');
await updateShareLink(page, 'Public', 'Edition');
await page.getByRole('button', { name: 'OK' }).click();
await expect(page.getByText('Public document')).toBeVisible();
// Create sub page
await createSubPageFromParent(
page,
browserName,
subPageItem.id,
'sub-page-2',
);
await expect(page.getByText('Public document')).toBeVisible();
// Verify share link and role
await page.getByRole('button', { name: 'Share' }).click();
await verifyLinkReachIsDisabled(page, 'Private');
await verifyLinkReachIsDisabled(page, 'Connected');
await verifyLinkReachIsEnabled(page, 'Public');
await verifyLinkRoleIsDisabled(page, 'Reading');
await verifyLinkRoleIsEnabled(page, 'Edition');
// await expect(page.getByText('Inherited share')).toBeVisible();
const docVisibilityCard = page.getByLabel('Doc visibility card');
await expect(docVisibilityCard).toBeVisible();
await expect(docVisibilityCard.getByText('Connected')).toBeVisible();
await expect(docVisibilityCard.getByText('Reading')).toBeVisible();
});
});

View File

@@ -13,7 +13,7 @@ test.describe('Document list members', () => {
// Get the current URL and extract the last part
const currentUrl = page.url();
console.log('Current URL:', currentUrl);
const currentDocId = (() => {
// Remove trailing slash if present
const cleanUrl = currentUrl.endsWith('/')
@@ -184,17 +184,14 @@ test.describe('Document list members', () => {
const emailMyself = `user@${browserName}.test`;
const mySelf = list.getByTestId(`doc-share-member-row-${emailMyself}`);
const mySelfMoreActions = mySelf.getByRole('button', {
name: 'more_horiz',
const mySelfRole = mySelf.getByRole('button', {
name: 'doc-role-dropdown',
});
const userOwnerEmail = await addNewMember(page, 0, 'Owner');
const userOwner = list.getByTestId(
`doc-share-member-row-${userOwnerEmail}`,
);
const userOwnerMoreActions = userOwner.getByRole('button', {
name: 'more_horiz',
});
await page.getByRole('button', { name: 'close' }).first().click();
await page.getByRole('button', { name: 'Share' }).first().click();
@@ -204,24 +201,20 @@ test.describe('Document list members', () => {
const userReader = list.getByTestId(
`doc-share-member-row-${userReaderEmail}`,
);
const userReaderMoreActions = userReader.getByRole('button', {
name: 'more_horiz',
const userReaderRole = userReader.getByRole('button', {
name: 'doc-role-dropdown',
});
await expect(mySelf).toBeVisible();
await expect(userOwner).toBeVisible();
await expect(userReader).toBeVisible();
await expect(userOwnerMoreActions).toBeVisible();
await expect(userReaderMoreActions).toBeVisible();
await expect(mySelfMoreActions).toBeVisible();
await userReaderMoreActions.click();
await page.getByLabel('Delete').click();
await userReaderRole.click();
await page.getByRole('menuitem', { name: 'Remove access' }).click();
await expect(userReader).toBeHidden();
await mySelfMoreActions.click();
await page.getByLabel('Delete').click();
await mySelfRole.click();
await page.getByRole('menuitem', { name: 'Remove access' }).click();
await expect(
page.getByText('Insufficient access rights to view the document.'),
).toBeVisible();

View File

@@ -154,7 +154,7 @@ test.describe('Sub page search', () => {
1,
);
await verifyDocName(page, doc1Title);
await page.getByRole('button', { name: 'New page' }).click();
await page.getByRole('button', { name: 'New doc' }).click();
await verifyDocName(page, '');
await page.getByRole('textbox', { name: 'doc title input' }).click();
await page

View File

@@ -6,8 +6,10 @@ import {
expectLoginPage,
keyCloakSignIn,
randomName,
updateDocTitle,
verifyDocName,
} from './common';
import { clickOnAddRootSubPage, createRootSubPage } from './sub-pages-utils';
test.describe('Doc Tree', () => {
test('create new sub pages', async ({ page, browserName }) => {
@@ -19,7 +21,7 @@ test.describe('Doc Tree', () => {
1,
);
await verifyDocName(page, titleParent);
const addButton = page.getByRole('button', { name: 'New page' });
const addButton = page.getByRole('button', { name: 'New doc' });
const docTree = page.getByTestId('doc-tree');
await expect(addButton).toBeVisible();
@@ -32,7 +34,7 @@ test.describe('Doc Tree', () => {
response.request().method() === 'POST',
);
await addButton.click();
await clickOnAddRootSubPage(page);
const response = await responsePromise;
expect(response.ok()).toBeTruthy();
const subPageJson = await response.json();
@@ -58,7 +60,7 @@ test.describe('Doc Tree', () => {
test('check the reorder of sub pages', async ({ page, browserName }) => {
await page.goto('/');
await createDoc(page, 'doc-tree-content', browserName, 1);
const addButton = page.getByRole('button', { name: 'New page' });
const addButton = page.getByRole('button', { name: 'New doc' });
await expect(addButton).toBeVisible();
const docTree = page.getByTestId('doc-tree');
@@ -71,9 +73,10 @@ test.describe('Doc Tree', () => {
response.request().method() === 'POST',
);
await addButton.click();
await clickOnAddRootSubPage(page);
const firstResponse = await firstResponsePromise;
expect(firstResponse.ok()).toBeTruthy();
await updateDocTitle(page, 'first');
const secondResponsePromise = page.waitForResponse(
(response) =>
@@ -83,9 +86,10 @@ test.describe('Doc Tree', () => {
);
// Create second sub page
await addButton.click();
await clickOnAddRootSubPage(page);
const secondResponse = await secondResponsePromise;
expect(secondResponse.ok()).toBeTruthy();
await updateDocTitle(page, 'second');
const secondSubPageJson = await secondResponse.json();
const firstSubPageJson = await firstResponse.json();
@@ -123,8 +127,8 @@ test.describe('Doc Tree', () => {
await page.mouse.move(
secondSubPageBoundingBox.x + secondSubPageBoundingBox.width / 2,
secondSubPageBoundingBox.y + secondSubPageBoundingBox.height + 4,
{ steps: 10 },
secondSubPageBoundingBox.y + secondSubPageBoundingBox.height + 2,
{ steps: 20 },
);
await page.mouse.up();
@@ -170,16 +174,15 @@ test.describe('Doc Tree', () => {
);
await verifyDocName(page, docParent);
const [docChild] = await createDoc(
const { name: docChild } = await createRootSubPage(
page,
'doc-tree-detach-child',
browserName,
1,
true,
'doc-tree-detach-child',
);
await verifyDocName(page, docChild);
const docTree = page.getByTestId('doc-tree');
await expect(docTree.getByText(docChild)).toBeVisible();
await docTree.click();
const child = docTree
.getByRole('treeitem')
.locator('.--docs-sub-page-item')
@@ -189,7 +192,7 @@ test.describe('Doc Tree', () => {
await child.hover();
const menu = child.getByText(`more_horiz`);
await menu.click();
await page.getByText('Convert to doc').click();
await page.getByText('Move to my docs').click();
await expect(
page.getByRole('textbox', { name: 'doc title input' }),
@@ -232,14 +235,11 @@ test.describe('Doc Tree: Inheritance', () => {
await page.getByRole('button', { name: 'close' }).click();
const [docChild] = await createDoc(
const { name: docChild } = await createRootSubPage(
page,
'doc-tree-inheritance-child',
browserName,
1,
true,
'doc-tree-inheritance-child',
);
await verifyDocName(page, docChild);
const urlDoc = page.url();
@@ -258,62 +258,4 @@ test.describe('Doc Tree: Inheritance', () => {
const docTree = page.getByTestId('doc-tree');
await expect(docTree.getByText(docParent)).toBeVisible();
});
test('Do not show private parent from children', async ({
page,
browserName,
}) => {
await page.goto('/');
await keyCloakSignIn(page, browserName);
const [docParent] = await createDoc(
page,
'doc-tree-inheritance-private-parent',
browserName,
1,
);
await verifyDocName(page, docParent);
const [docChild] = await createDoc(
page,
'doc-tree-inheritance-private-child',
browserName,
1,
true,
);
await verifyDocName(page, docChild);
await page.getByRole('button', { name: 'Share' }).click();
const selectVisibility = page.getByLabel('Visibility', { exact: true });
await selectVisibility.click();
await page
.getByRole('menuitem', {
name: 'Public',
})
.click();
await expect(
page.getByText('The document visibility has been updated.'),
).toBeVisible();
await page.getByRole('button', { name: 'close' }).click();
const urlDoc = page.url();
await page
.getByRole('button', {
name: 'Logout',
})
.click();
await expectLoginPage(page);
await page.goto(urlDoc);
await expect(page.locator('h2').getByText(docChild)).toBeVisible();
const docTree = page.getByTestId('doc-tree');
await expect(docTree.getByText(docParent)).toBeHidden();
});
});

View File

@@ -246,7 +246,7 @@ test.describe('Doc Visibility: Public', () => {
).toBeVisible();
await expect(page.getByRole('button', { name: 'search' })).toBeVisible();
await expect(page.getByRole('button', { name: 'New page' })).toBeVisible();
await expect(page.getByRole('button', { name: 'New doc' })).toBeVisible();
const urlDoc = page.url();
@@ -262,7 +262,7 @@ test.describe('Doc Visibility: Public', () => {
await expect(page.locator('h2').getByText(docTitle)).toBeVisible();
await expect(page.getByRole('button', { name: 'search' })).toBeHidden();
await expect(page.getByRole('button', { name: 'New page' })).toBeHidden();
await expect(page.getByRole('button', { name: 'New doc' })).toBeHidden();
await expect(page.getByRole('button', { name: 'Share' })).toBeVisible();
const card = page.getByLabel('It is the card information');
await expect(card).toBeVisible();

View File

@@ -7,12 +7,9 @@ export const createRootSubPage = async (
browserName: string,
docName: string,
) => {
// Get add button
const addButton = page.getByRole('button', { name: 'New page' });
// Get response
const responsePromise = waitForResponseCreateDoc(page);
await addButton.click();
await clickOnAddRootSubPage(page);
const response = await responsePromise;
expect(response.ok()).toBeTruthy();
const subPageJson = (await response.json()) as { id: string };
@@ -36,6 +33,13 @@ export const createRootSubPage = async (
return { name: randomDocs[0], docTreeItem: subPageItem, item: subPageJson };
};
export const clickOnAddRootSubPage = async (page: Page) => {
const rootItem = page.getByTestId('doc-tree-root-item');
await expect(rootItem).toBeVisible();
await rootItem.hover();
await rootItem.getByRole('button', { name: 'add_box' }).click();
};
export const createSubPageFromParent = async (
page: Page,
browserName: string,