diff --git a/env.d/development/common.e2e b/env.d/development/common.e2e index 6394c8b2b..b69b5b97c 100644 --- a/env.d/development/common.e2e +++ b/env.d/development/common.e2e @@ -1,7 +1,7 @@ # For the CI job test-e2e -BURST_THROTTLE_RATES="200/minute" +BURST_THROTTLE_RATES="1000/minute" COLLABORATION_API_URL=http://y-provider:4444/collaboration/api/ -SUSTAINED_THROTTLE_RATES="200/hour" +SUSTAINED_THROTTLE_RATES="1000/minute" Y_PROVIDER_API_BASE_URL=http://y-provider:4444/api/ # Throttle diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts index 7407027fd..9a055253b 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts @@ -137,7 +137,6 @@ test.describe('Doc Editor', () => { }) => { // Check the first doc const [firstDoc] = await createDoc(page, 'doc-switch-1', browserName, 1); - await verifyDocName(page, firstDoc); const editor = page.locator('.ProseMirror'); await editor.click(); @@ -145,8 +144,7 @@ test.describe('Doc Editor', () => { await expect(editor.getByText('Hello World Doc 1')).toBeVisible(); // Check the second doc - const [secondDoc] = await createDoc(page, 'doc-switch-2', browserName, 1); - await verifyDocName(page, secondDoc); + await createDoc(page, 'doc-switch-2', browserName, 1); await expect(editor.getByText('Hello World Doc 1')).toBeHidden(); await editor.click(); @@ -178,20 +176,13 @@ test.describe('Doc Editor', () => { }) => { // Check the first doc const [doc] = await createDoc(page, 'doc-saves-change', browserName); - await verifyDocName(page, doc); - const editor = page.locator('.ProseMirror'); - await editor.click(); - await editor.fill('Hello World Doc persisted 1'); - await expect(editor.getByText('Hello World Doc persisted 1')).toBeVisible(); - - const [secondDoc] = await createDoc( + const editor = await writeInEditor({ page, - 'doc-saves-change-other', - browserName, - ); + text: 'Hello World Doc persisted 1', + }); - await verifyDocName(page, secondDoc); + await createDoc(page, 'doc-saves-change-other', browserName); await goToGridDoc(page, { title: doc, @@ -208,12 +199,10 @@ test.describe('Doc Editor', () => { const [doc] = await createDoc(page, 'doc-quit-1', browserName, 1); await verifyDocName(page, doc); - const editor = page.locator('.ProseMirror'); - await editor.click(); - await editor.fill('Hello World Doc persisted 2'); - await expect(editor.getByText('Hello World Doc persisted 2')).toBeVisible(); - - await page.waitForTimeout(1000); + const editor = await writeInEditor({ + page, + text: 'Hello World Doc persisted 2', + }); const urlDoc = page.url(); await page.goto(urlDoc); @@ -228,7 +217,7 @@ test.describe('Doc Editor', () => { const fileChooserPromise = page.waitForEvent('filechooser'); - await page.locator('.bn-block-outer').last().fill('Hello World'); + await writeInEditor({ page, text: 'Hello World' }); await page.keyboard.press('Enter'); await page.locator('.bn-block-outer').last().fill('/'); @@ -344,8 +333,6 @@ test.describe('Doc Editor', () => { const fileChooserPromise = page.waitForEvent('filechooser'); - await verifyDocName(page, randomDoc); - const { editor } = await openSuggestionMenu({ page }); await page.getByText('Embedded file').click(); await page.getByText('Upload file').click(); @@ -356,7 +343,9 @@ test.describe('Doc Editor', () => { await expect(editor.getByText('Analyzing file...')).toBeVisible(); // To be sure the retry happens even after a page reload - await page.reload(); + await goToGridDoc(page, { + title: randomDoc, + }); await expect(editor.getByText('Analyzing file...')).toBeVisible(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts index 3fe255c5b..b852a32be 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts @@ -152,8 +152,6 @@ test.describe('Doc Tree', () => { test('check the reorder of sub pages', async ({ page, browserName }) => { await createDoc(page, 'doc-tree-content', browserName, 1); - const addButton = page.getByTestId('new-doc-button'); - await expect(addButton).toBeVisible(); const docTree = page.getByTestId('doc-tree'); @@ -181,8 +179,9 @@ test.describe('Doc Tree', () => { await expect(allSubPageItems.nth(1).getByText('second move')).toBeVisible(); // Will move the first sub page to the second position - const firstSubPageBoundingBox = await firstSubPageItem.boundingBox(); - const secondSubPageBoundingBox = await secondSubPageItem.boundingBox(); + // Use the testId-based locators for bounding box to avoid stale text locators + const firstSubPageBoundingBox = await allSubPageItems.nth(0).boundingBox(); + const secondSubPageBoundingBox = await allSubPageItems.nth(1).boundingBox(); expect(firstSubPageBoundingBox).toBeDefined(); expect(secondSubPageBoundingBox).toBeDefined(); @@ -218,16 +217,8 @@ test.describe('Doc Tree', () => { await expect(secondSubPageItem).toBeVisible(); // Check that elements are in the correct order - const allSubPageItemsAfterReload = - docTree.getByTestId(/^doc-sub-page-item/); - await expect(allSubPageItemsAfterReload).toHaveCount(2); - - await expect( - allSubPageItemsAfterReload.nth(0).getByText('second move'), - ).toBeVisible(); - await expect( - allSubPageItemsAfterReload.nth(1).getByText('first move'), - ).toBeVisible(); + await expect(allSubPageItems.nth(0).getByText('second move')).toBeVisible(); + await expect(allSubPageItems.nth(1).getByText('first move')).toBeVisible(); }); test('it detaches a document', async ({ page, browserName }) => { @@ -237,7 +228,6 @@ test.describe('Doc Tree', () => { browserName, 1, ); - await verifyDocName(page, docParent); const { name: docChild } = await createRootSubPage( page, @@ -259,23 +249,14 @@ test.describe('Doc Tree', () => { await menu.click(); await page.getByText('Move to my docs').click(); - await expect( - page.getByRole('textbox', { name: 'Document title' }), - ).not.toHaveText(docChild); + await verifyDocName(page, docParent); await page.getByRole('button', { name: 'Back to homepage' }).click(); await expect(page.getByText(docChild)).toBeVisible(); }); test('Only owner can detaches a document', async ({ page, browserName }) => { - const [docParent] = await createDoc( - page, - 'doc-tree-detach', - browserName, - 1, - ); - - await verifyDocName(page, docParent); + await createDoc(page, 'doc-tree-detach', browserName, 1); await page.getByRole('button', { name: 'Share' }).click(); @@ -446,13 +427,7 @@ test.describe('Doc Tree', () => { page, browserName, }) => { - const [docParent] = await createDoc( - page, - 'doc-child-emoji', - browserName, - 1, - ); - await verifyDocName(page, docParent); + await createDoc(page, 'doc-child-emoji', browserName, 1); const { name: docChild } = await createRootSubPage( page, @@ -473,6 +448,8 @@ test.describe('Doc Tree', () => { // Close the menu await page.keyboard.press('Escape'); + await page.waitForTimeout(500); + // Update the emoji from the tree await row.locator('.--docs--doc-icon').click(); await page.getByRole('button', { name: '😀' }).first().click(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-version.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-version.spec.ts index 11b694b89..7294a52b2 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-version.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-version.spec.ts @@ -4,6 +4,7 @@ import { createDoc, goToGridDoc, mockedDocument, + saveContent, verifyDocName, } from './utils-common'; import { openSuggestionMenu, writeInEditor } from './utils-editor'; @@ -16,8 +17,6 @@ test.describe('Doc Version', () => { test('it displays the doc versions', async ({ page, browserName }) => { const [randomDoc] = await createDoc(page, 'doc-version', browserName, 1); - await verifyDocName(page, randomDoc); - // Initially, there is no version await page.getByLabel('Open the document options').click(); await page.getByRole('menuitem', { name: 'Version history' }).click(); @@ -32,10 +31,7 @@ test.describe('Doc Version', () => { await writeInEditor({ page, text: 'Hello World' }); - // It will trigger a save, no version created yet (initial version is not counted) - await goToGridDoc(page, { - title: randomDoc, - }); + await saveContent(page, randomDoc); await expect(page.getByText('Hello World')).toBeVisible(); @@ -51,10 +47,7 @@ test.describe('Doc Version', () => { await expect(calloutBlock).toBeVisible(); - // It will trigger a save and create a version this time - await goToGridDoc(page, { - title: randomDoc, - }); + await saveContent(page, randomDoc); await expect(page.getByText('Hello World')).toBeHidden(); await expect(page.getByText('It will create a version')).toBeVisible(); @@ -64,10 +57,7 @@ test.describe('Doc Version', () => { // Write more await writeInEditor({ page, text: 'It will create a second version' }); - // It will trigger a save and create a second version - await goToGridDoc(page, { - title: randomDoc, - }); + await saveContent(page, randomDoc); await expect( page.getByText('It will create a second version'), @@ -144,18 +134,14 @@ test.describe('Doc Version', () => { await thread.locator('[data-test="save"]').click(); await expect(thread).toBeHidden(); - await goToGridDoc(page, { - title: randomDoc, - }); + await saveContent(page, randomDoc); await expect(editor.getByText('Hello')).toBeVisible(); await page.locator('.bn-block-outer').last().click(); await page.keyboard.press('Enter'); await page.locator('.bn-block-outer').last().fill('World'); - await goToGridDoc(page, { - title: randomDoc, - }); + await saveContent(page, randomDoc); await expect(page.getByText('World')).toBeVisible(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts b/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts index 032ac32df..782792fcb 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts @@ -269,6 +269,31 @@ export const waitForResponseCreateDoc = (page: Page) => { ); }; +/** + * Navigates back to the homepage, waits for the PATCH /content/ request + * triggered by the route change to complete, then navigates back to the doc. + * + * Use this instead of goToGridDoc when the test must assert on content that + * was just written in the editor, to avoid a race condition where the GET + * request fired on doc mount returns stale data because the server has not + * yet processed the PATCH. + */ +export const saveContent = async (page: Page, title: string) => { + const savePromise = page.waitForResponse( + (response) => + response.url().includes('/content/') && + response.request().method() === 'PATCH', + ); + + await page.getByRole('button', { name: 'Back to homepage' }).click(); + await expect(page.getByTestId('docs-grid')).toBeVisible(); + await expect(page.getByTestId('grid-loader')).toBeHidden(); + + await savePromise; + + await goToGridDoc(page, { title }); +}; + export const mockedDocument = async (page: Page, data: object) => { // document/[ID]/ or document/[ID]/tree/ routes let uuid: string | undefined;