From 3b9f86a54776ba5e5d942cf6be715ec4ba7343ab Mon Sep 17 00:00:00 2001 From: Jakub P Date: Wed, 9 Apr 2025 20:01:36 +0200 Subject: [PATCH 1/9] test: folder tests --- .../e2e-tests/fixtures/flow-editor-page.js | 1 + packages/e2e-tests/fixtures/flows-page.js | 19 +- .../fixtures/folder/create-folder-dialog.js | 15 + .../fixtures/folder/delete-folder-dialog.js | 14 + .../fixtures/folder/move-flow-dialog.js | 18 + .../fixtures/folder/update-folder-dialog.js | 12 + packages/e2e-tests/helpers/auth-api-helper.js | 10 +- .../e2e-tests/helpers/folder-api-helper.js | 14 + .../tests/flow-folders/flow-folder.spec.js | 358 ++++++++++++++++++ .../components/CreateFolderDialog/index.jsx | 2 + .../src/components/EditFolderDialog/index.jsx | 2 + .../components/EditorLayout/FlowFolder.jsx | 1 + .../src/components/FlowContextMenu/index.jsx | 12 +- .../FlowFolderChangeDialog/index.jsx | 2 + packages/web/src/components/Folders/index.jsx | 16 +- 15 files changed, 488 insertions(+), 8 deletions(-) create mode 100644 packages/e2e-tests/fixtures/folder/create-folder-dialog.js create mode 100644 packages/e2e-tests/fixtures/folder/delete-folder-dialog.js create mode 100644 packages/e2e-tests/fixtures/folder/move-flow-dialog.js create mode 100644 packages/e2e-tests/fixtures/folder/update-folder-dialog.js create mode 100644 packages/e2e-tests/helpers/folder-api-helper.js create mode 100644 packages/e2e-tests/tests/flow-folders/flow-folder.spec.js diff --git a/packages/e2e-tests/fixtures/flow-editor-page.js b/packages/e2e-tests/fixtures/flow-editor-page.js index dd2f32ae..eed41923 100644 --- a/packages/e2e-tests/fixtures/flow-editor-page.js +++ b/packages/e2e-tests/fixtures/flow-editor-page.js @@ -39,6 +39,7 @@ export class FlowEditorPage extends AuthenticatedPage { this.goBackButton = this.page.getByTestId('editor-go-back-button'); this.exportFlowButton = page.getByTestId('export-flow-button'); this.stepName = page.getByTestId('step-name'); + this.folderName = page.getByTestId('folder-name'); } async createWebhookTrigger(workSynchronously) { diff --git a/packages/e2e-tests/fixtures/flows-page.js b/packages/e2e-tests/fixtures/flows-page.js index 14c8cb97..87cba5c5 100644 --- a/packages/e2e-tests/fixtures/flows-page.js +++ b/packages/e2e-tests/fixtures/flows-page.js @@ -4,7 +4,24 @@ export class FlowsPage extends AuthenticatedPage { constructor(page) { super(page); - this.flowRow = this.page.getByTestId('flow-row'); + this.searchInput = page.locator('#search-input'); + this.flowRow = page.getByTestId('flow-row'); this.importFlowButton = page.getByTestId('import-flow-button'); + this.createFlowButton = page.getByTestId('create-flow-button'); + this.uncategorizedFlowsFolder = page.getByTestId( + 'uncategorized-flows-folder' + ); + this.allFlowsFolder = page.getByTestId('all-flows-folder'); + this.addNewFolderButton = page.getByTestId('add-folder-button'); + this.userFolders = page.getByTestId('user-folders'); + this.editFolder = page.getByTestId('edit-folder'); + this.deleteFolder = page.getByTestId('delete-folder'); + this.deleteFolderSuccessAlert = page.getByTestId( + 'snackbar-delete-folder-success' + ); + + //flow actions + this.moveTo = page.getByTestId('move-to'); + this.delete = page.getByTestId('delete-flow'); } } diff --git a/packages/e2e-tests/fixtures/folder/create-folder-dialog.js b/packages/e2e-tests/fixtures/folder/create-folder-dialog.js new file mode 100644 index 00000000..f1530f6e --- /dev/null +++ b/packages/e2e-tests/fixtures/folder/create-folder-dialog.js @@ -0,0 +1,15 @@ +const { AuthenticatedPage } = require('../authenticated-page'); + +export class CreateFolderDialog extends AuthenticatedPage { + constructor(page) { + super(page); + + this.folderNameInput = page.getByTestId('new-folder-name').locator('input'); + this.createButton = page.getByTestId('create-folder-dialog-create-button'); + this.successAlert = page.getByTestId('create-folder-dialog-success-alert'); + this.errorAlert = page.getByTestId( + 'create-folder-dialog-generic-error-alert' + ); + this.closeDialog = page.getByTestId('close-dialog'); + } +} diff --git a/packages/e2e-tests/fixtures/folder/delete-folder-dialog.js b/packages/e2e-tests/fixtures/folder/delete-folder-dialog.js new file mode 100644 index 00000000..194ff4d5 --- /dev/null +++ b/packages/e2e-tests/fixtures/folder/delete-folder-dialog.js @@ -0,0 +1,14 @@ +const { AuthenticatedPage } = require('../authenticated-page'); + +export class DeleteFolderDialog extends AuthenticatedPage { + constructor(page) { + super(page); + + this.modal = page.getByTestId('delete-folder-modal'); + this.cancelButton = this.modal.getByTestId('confirmation-cancel-button'); + this.deleteButton = this.modal.getByTestId('confirmation-confirm-button'); + this.deleteAlert = this.modal.getByTestId( + 'confirmation-dialog-error-alert' + ); + } +} diff --git a/packages/e2e-tests/fixtures/folder/move-flow-dialog.js b/packages/e2e-tests/fixtures/folder/move-flow-dialog.js new file mode 100644 index 00000000..4b0e5c71 --- /dev/null +++ b/packages/e2e-tests/fixtures/folder/move-flow-dialog.js @@ -0,0 +1,18 @@ +const { AuthenticatedPage } = require('../authenticated-page'); + +export class MoveFolderDialog extends AuthenticatedPage { + constructor(page) { + super(page); + + this.folderNameAutocomplete = page + .getByTestId('move-to-folder-name') + .locator('input'); + this.moveButton = page.getByTestId( + 'flow-folder-change-dialog-confirm-button' + ); + this.successAlert = page.getByTestId( + 'flow-folder-change-dialog-success-alert' + ); + this.closeDialog = page.getByTestId('close-dialog'); + } +} diff --git a/packages/e2e-tests/fixtures/folder/update-folder-dialog.js b/packages/e2e-tests/fixtures/folder/update-folder-dialog.js new file mode 100644 index 00000000..f085aa05 --- /dev/null +++ b/packages/e2e-tests/fixtures/folder/update-folder-dialog.js @@ -0,0 +1,12 @@ +const { AuthenticatedPage } = require('../authenticated-page'); + +export class UpdateFolderDialog extends AuthenticatedPage { + constructor(page) { + super(page); + + this.folderNameInput = page.getByTestId('new-folder-name').locator('input'); + this.updateButton = page.getByTestId('edit-folder-dialog-update-button'); + this.successAlert = page.getByTestId('edit-folder-dialog-success-alert'); + this.closeDialog = page.getByTestId('close-dialog'); + } +} diff --git a/packages/e2e-tests/helpers/auth-api-helper.js b/packages/e2e-tests/helpers/auth-api-helper.js index a5401e85..5f078ee0 100644 --- a/packages/e2e-tests/helpers/auth-api-helper.js +++ b/packages/e2e-tests/helpers/auth-api-helper.js @@ -1,12 +1,16 @@ const { expect } = require('../fixtures/index'); -export const getToken = async (apiRequest) => { +export const getToken = async ( + apiRequest, + email = process.env.LOGIN_EMAIL, + password = process.env.LOGIN_PASSWORD +) => { const tokenResponse = await apiRequest.post( `${process.env.BACKEND_APP_URL}/internal/api/v1/access-tokens`, { data: { - email: process.env.LOGIN_EMAIL, - password: process.env.LOGIN_PASSWORD, + email: email, + password: password, }, } ); diff --git a/packages/e2e-tests/helpers/folder-api-helper.js b/packages/e2e-tests/helpers/folder-api-helper.js new file mode 100644 index 00000000..3438bf9e --- /dev/null +++ b/packages/e2e-tests/helpers/folder-api-helper.js @@ -0,0 +1,14 @@ +const { expect } = require('../fixtures/index'); + +export const addFolder = async (apiRequest, token, folderName) => { + const addFolderResponse = await apiRequest.post( + `${process.env.BACKEND_APP_URL}/api/v1/folders`, + { + headers: { Authorization: token }, + data: { name: folderName }, + } + ); + await expect(addFolderResponse.status()).toBe(201); + + return await addFolderResponse.json(); +}; diff --git a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js new file mode 100644 index 00000000..1dce8b14 --- /dev/null +++ b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js @@ -0,0 +1,358 @@ +const { test, expect } = require('../../fixtures/index'); +const { request } = require('@playwright/test'); + +const { + CreateFolderDialog, +} = require('../../fixtures/folder/create-folder-dialog'); +const { + UpdateFolderDialog, +} = require('../../fixtures/folder/update-folder-dialog'); +const { MoveFolderDialog } = require('../../fixtures/folder/move-flow-dialog'); +const { + DeleteFolderDialog, +} = require('../../fixtures/folder/delete-folder-dialog'); +const { getToken } = require('../../helpers/auth-api-helper'); +const { addUser, acceptInvitation } = require('../../helpers/user-api-helper'); +const { addFolder } = require('../../helpers/folder-api-helper'); +const { createFlow, updateFlowName } = require('../../helpers/flow-api-helper'); + +test.describe('Folders', () => { + test('owner folder lifecycle', async ({ + page, + flowsPage, + flowEditorPage, + }) => { + const createFolderDialog = new CreateFolderDialog(page); + const updateFolderDialog = new UpdateFolderDialog(page); + const folderMoveToDialog = new MoveFolderDialog(page); + const deleteFolderDialog = new DeleteFolderDialog(page); + + await test.step('new flow should be in uncategorized folder', async () => { + await flowsPage.createFlowButton.click(); + await flowEditorPage.flowName.click(); + await flowEditorPage.flowNameInput.fill('uncategorizedFlow'); + await flowEditorPage.flowStep.first().click(); + await flowEditorPage.goBackButton.click(); + await expect(page).toHaveURL('/flows'); + await flowsPage.searchInput.fill('uncategorizedFlow'); + await expect( + flowsPage.flowRow.filter({ + hasText: 'uncategorizedFlow', + }) + ).toHaveCount(1); + await flowsPage.uncategorizedFlowsFolder.click(); + await flowsPage.searchInput.fill('uncategorizedFlow'); + await expect( + flowsPage.flowRow.filter({ + hasText: 'uncategorizedFlow', + }) + ).toHaveCount(1); + }); + + await test.step('folder name should be at least 1 character long', async () => { + await flowsPage.addNewFolderButton.click(); + await createFolderDialog.createButton.click(); + await expect(createFolderDialog.errorAlert).toHaveCount(1); + await createFolderDialog.closeDialog.click(); + }); + + await test.step('should be able to add a folder', async () => { + await flowsPage.addNewFolderButton.click(); + await createFolderDialog.folderNameInput.fill('newFolder'); + await createFolderDialog.createButton.click(); + await expect(createFolderDialog.successAlert).toHaveCount(1); + await createFolderDialog.closeDialog.click(); + await expect(flowsPage.userFolders.getByText('newFolder')).toHaveCount(1); + await flowsPage.userFolders.getByText('newFolder').click(); + await expect(flowsPage.flowRow).toHaveCount(0); + }); + + await test.step('should be possible to move flow to the new folder', async () => { + await flowsPage.allFlowsFolder.click(); + await flowsPage.flowRow + .filter({ + hasText: 'uncategorizedFlow', + }) + .getByRole('button') + .click(); + await flowsPage.moveTo.click(); + + await folderMoveToDialog.folderNameAutocomplete.click(); + await page.getByRole('option', { name: 'newFolder' }).last().click(); + await folderMoveToDialog.moveButton.click(); + await expect(folderMoveToDialog.successAlert).toHaveCount(1); + await folderMoveToDialog.closeDialog.click(); + }); + + await test.step('flow should be visible in the new folder and in all flows folder', async () => { + await flowsPage.userFolders.getByText('newFolder').click(); + await flowsPage.searchInput.fill('uncategorizedFlow'); + await expect( + flowsPage.flowRow.filter({ + hasText: 'uncategorizedFlow', + }) + ).toHaveCount(1); + await flowsPage.flowRow + .filter({ + hasText: 'uncategorizedFlow', + }) + .click(); + await expect(flowEditorPage.folderName).toContainText('newFolder'); + await flowEditorPage.goBackButton.click(); + + await flowsPage.allFlowsFolder.click(); + await flowsPage.searchInput.fill('uncategorizedFlow'); + await expect( + flowsPage.flowRow.filter({ + hasText: 'uncategorizedFlow', + }) + ).toHaveCount(1); + await flowsPage.uncategorizedFlowsFolder.click(); + await flowsPage.searchInput.fill('uncategorizedFlow'); + await expect( + flowsPage.flowRow.filter({ + hasText: 'uncategorizedFlow', + }) + ).toHaveCount(0); + }); + + await test.step('should be able to add a folder with the same name', async () => { + await flowsPage.addNewFolderButton.click(); + await createFolderDialog.folderNameInput.fill('newFolder'); + await createFolderDialog.createButton.click(); + await expect(createFolderDialog.successAlert).toHaveCount(1); + await createFolderDialog.closeDialog.click(); + await expect(flowsPage.userFolders.getByText('newFolder')).toHaveCount(2); + }); + + await test.step('should be able to update a folder', async () => { + await expect(flowsPage.userFolders.getByText('newFolder2')).toHaveCount( + 0 + ); + await flowsPage.userFolders.getByText('newFolder').first().click(); + await flowsPage.editFolder.click(); + await updateFolderDialog.folderNameInput.fill('newFolder2'); + await updateFolderDialog.updateButton.click(); + await expect(updateFolderDialog.successAlert).toHaveCount(1); + await updateFolderDialog.closeDialog.click(); + await expect(flowsPage.userFolders.getByText('newFolder2')).toHaveCount( + 1 + ); + await flowsPage.flowRow + .filter({ + hasText: 'uncategorizedFlow', + }) + .click(); + await expect(flowEditorPage.folderName).toContainText('newFolder2'); + await flowEditorPage.goBackButton.click(); + }); + + await test.step('should be able to delete a folder with a flow', async () => { + await expect(flowsPage.userFolders.getByText('newFolder2')).toHaveCount( + 1 + ); + + await flowsPage.deleteFolder.click(); + await deleteFolderDialog.cancelButton.click(); + await flowsPage.deleteFolder.click(); + await deleteFolderDialog.deleteButton.click(); + await expect(flowsPage.userFolders.getByText('newFolder2')).toHaveCount( + 0 + ); + await expect(flowsPage.deleteFolderSuccessAlert).toHaveCount(1); + await flowsPage.flowRow + .filter({ + hasText: 'uncategorizedFlow', + }) + .click(); + await expect(flowEditorPage.folderName).toContainText('Uncategorized'); + await flowEditorPage.goBackButton.click(); + }); + }); + + // removal of the empty folder is buggy + test.skip('should be able to delete empty folder', async ({ + page, + flowsPage, + flowEditorPage, + }) => { + // add flow + await flowsPage.createFlowButton.click(); + await flowEditorPage.flowName.click(); + await flowEditorPage.flowNameInput.fill('deleteFlow'); + await flowEditorPage.flowStep.first().click(); + await flowEditorPage.goBackButton.click(); + await expect(page).toHaveURL('/flows'); + // add folder + await flowsPage.addNewFolderButton.click(); + await createFolderDialog.folderNameInput.fill('deleteFolder'); + await createFolderDialog.createButton.click(); + await expect(createFolderDialog.successAlert).toContainText( + 'The folder has been successfully created!' + ); + await createFolderDialog.closeDialog.click(); + await expect(flowsPage.userFolders.getByText('deleteFolder')).toHaveCount( + 1 + ); + await flowsPage.userFolders.getByText('deleteFolder').click(); + // move flow + await flowsPage.allFlowsFolder.click(); + await flowsPage.flowRow + .filter({ + hasText: 'deleteFlow', + }) + .getByRole('button') + .click(); + await flowsPage.moveTo.click(); + + await folderMoveToDialog.folderNameAutocomplete.click(); + await page.getByRole('option', { name: 'deleteFolder' }).last().click(); + await folderMoveToDialog.moveButton.click(); + await expect(folderMoveToDialog.successAlert).toHaveCount(1); + await folderMoveToDialog.closeDialog.click(); + // remove flow + await flowsPage.allFlowsFolder.click(); + await flowsPage.flowRow + .filter({ + hasText: 'deleteFlow', + }) + .getByRole('button') + .click(); + await flowsPage.delete.click(); + // remove folder + await flowsPage.userFolders.getByText('deleteFolder').click(); + await flowsPage.deleteFolder.click(); + await deleteFolderDialog.deleteButton.click(); + await expect(flowsPage.userFolders.getByText('deleteFolder')).toHaveCount( + 0 + ); + await expect(flowsPage.deleteFolderSuccessAlert).toHaveCount(1); + }); + + // folder name is not correct (still uncategorized) + test.skip('should be possible to add flow in the new folder', async ({ + flowsPage, + flowEditorPage, + }) => { + await expect(flowsPage.userFolders.getByText('newFolder')).toHaveCount(1); + await flowsPage.userFolders.getByText('newFolder').click(); + await flowsPage.createFlowButton.click(); + await expect(flowEditorPage.folderName).toContainText('newFolder'); + }); + + test('non-owner folder visibility', async ({ + page, + flowsPage, + flowEditorPage, + adminCreateUserPage, + }) => { + const apiRequest = await request.newContext(); + const tokenJsonResponse = await getToken(apiRequest); + let userTokenJsonResponse; + let flowId; + + await test.step('add another user', async () => { + adminCreateUserPage.seed( + Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER) + ); + const testUser = adminCreateUserPage.generateUser(); + + const addUserResponse = await addUser( + apiRequest, + tokenJsonResponse.data.token, + { + fullName: testUser.fullName, + email: testUser.email, + } + ); + + const acceptToken = + addUserResponse.data.acceptInvitationUrl.split('=')[1]; + await acceptInvitation(apiRequest, { + token: acceptToken, + password: 'alamakota', + }); + userTokenJsonResponse = await getToken( + apiRequest, + testUser.email, + 'alamakota' + ); + }); + + await test.step('add folder as an another user', async () => { + await addFolder( + apiRequest, + userTokenJsonResponse.data.token, + 'anotherUserFolder' + ); + }); + + await test.step('add folder as a main user', async () => { + await addFolder( + apiRequest, + tokenJsonResponse.data.token, + 'mainUserFolder' + ); + }); + + await test.step('add flow as an another user', async () => { + const flow = await createFlow( + apiRequest, + userTokenJsonResponse.data.token + ); + flowId = flow.data.id; + await updateFlowName( + apiRequest, + userTokenJsonResponse.data.token, + flowId + ); + await page.reload(); + }); + + await test.step('should not see folders of different user on the list', async () => { + await expect( + flowsPage.userFolders.getByText('anotherUserFolder') + ).toHaveCount(0); + }); + + await test.step('should not see folders of different user in the flow details', async () => { + await flowsPage.flowRow + .filter({ + hasText: flowId, + }) + .click(); + await expect(flowEditorPage.folderName).toContainText('Uncategorized'); + await flowEditorPage.goBackButton.click(); + }); + + await test.step("another user's flow should be uncategorized and in all flows folder", async () => { + await flowsPage.allFlowsFolder.click(); + await flowsPage.searchInput.fill(flowId); + await expect( + flowsPage.flowRow.filter({ + hasText: flowId, + }) + ).toHaveCount(1); + await flowsPage.uncategorizedFlowsFolder.click(); + await flowsPage.searchInput.fill(flowId); + await expect( + flowsPage.flowRow.filter({ + hasText: flowId, + }) + ).toHaveCount(1); + await flowsPage.userFolders.getByText('mainUserFolder').click(); + await flowsPage.searchInput.fill(flowId); + await expect( + flowsPage.flowRow.filter({ + hasText: flowId, + }) + ).toHaveCount(0); + }); + }); + + test.skip('non-owner should not reassing folder of different user', async ({ + page, + }) => { + // TODO feature is wip https://github.com/automatisch/automatisch/pull/2420 + }); +}); diff --git a/packages/web/src/components/CreateFolderDialog/index.jsx b/packages/web/src/components/CreateFolderDialog/index.jsx index 73b4f688..ee32dee1 100644 --- a/packages/web/src/components/CreateFolderDialog/index.jsx +++ b/packages/web/src/components/CreateFolderDialog/index.jsx @@ -44,6 +44,7 @@ export default function CreateFolderDialog(props) { {formatMessage('createFolderDialog.title')} {formatMessage('editFolderDialog.title')} {(allowed) => ( - + {formatMessage('flow.moveTo')} )} @@ -166,7 +170,11 @@ function ContextMenu(props) { {(allowed) => ( - + {formatMessage('flow.delete')} )} diff --git a/packages/web/src/components/FlowFolderChangeDialog/index.jsx b/packages/web/src/components/FlowFolderChangeDialog/index.jsx index 0384e211..45f2fb9a 100644 --- a/packages/web/src/components/FlowFolderChangeDialog/index.jsx +++ b/packages/web/src/components/FlowFolderChangeDialog/index.jsx @@ -62,6 +62,7 @@ function FlowFolderChangeDialog(props) { {formatMessage('flowFolderChangeDialog.title')} folder.id === selectedFolder) || uncategorizedFolder diff --git a/packages/web/src/components/Folders/index.jsx b/packages/web/src/components/Folders/index.jsx index a8f341f8..0f61a9d3 100644 --- a/packages/web/src/components/Folders/index.jsx +++ b/packages/web/src/components/Folders/index.jsx @@ -110,6 +110,7 @@ export default function Folders() { secondaryAction={ setShowEditFolderDialog(true)} @@ -117,6 +118,7 @@ export default function Folders() { setShowDeleteFolderDialog(true)} @@ -154,6 +156,7 @@ export default function Folders() { - + {folders?.data?.map((folder) => generateFolderItem(folder))} - setShowCreateFolderDialog(true)}> + setShowCreateFolderDialog(true)} + > @@ -212,6 +223,7 @@ export default function Folders() { onConfirm={handleDeleteFolderConfirmation} cancelButtonChildren={formatMessage('deleteFolderDialog.cancel')} confirmButtonChildren={formatMessage('deleteFolderDialog.confirm')} + data-test="delete-folder-modal" errorMessage={generalErrorMessage} /> )} From cda8ede7c6dd96502f53dbebd44cbbc85a66c328 Mon Sep 17 00:00:00 2001 From: Jakub P Date: Thu, 10 Apr 2025 12:42:55 +0200 Subject: [PATCH 2/9] test: expect edit flow page opened after flow is clicked --- .../e2e-tests/tests/flow-folders/flow-folder.spec.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js index 1dce8b14..ece1c461 100644 --- a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js +++ b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js @@ -97,6 +97,9 @@ test.describe('Folders', () => { hasText: 'uncategorizedFlow', }) .click(); + await expect(page).toHaveURL( + /\/editor\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/ + ); await expect(flowEditorPage.folderName).toContainText('newFolder'); await flowEditorPage.goBackButton.click(); @@ -143,6 +146,9 @@ test.describe('Folders', () => { hasText: 'uncategorizedFlow', }) .click(); + await expect(page).toHaveURL( + /\/editor\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/ + ); await expect(flowEditorPage.folderName).toContainText('newFolder2'); await flowEditorPage.goBackButton.click(); }); @@ -165,6 +171,9 @@ test.describe('Folders', () => { hasText: 'uncategorizedFlow', }) .click(); + await expect(page).toHaveURL( + /\/editor\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/ + ); await expect(flowEditorPage.folderName).toContainText('Uncategorized'); await flowEditorPage.goBackButton.click(); }); @@ -321,6 +330,9 @@ test.describe('Folders', () => { hasText: flowId, }) .click(); + await expect(page).toHaveURL( + /\/editor\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/ + ); await expect(flowEditorPage.folderName).toContainText('Uncategorized'); await flowEditorPage.goBackButton.click(); }); From 0ae2392e32e6083cf221b92f1d5ea8c54e345e23 Mon Sep 17 00:00:00 2001 From: Jakub P Date: Thu, 10 Apr 2025 13:40:11 +0200 Subject: [PATCH 3/9] test: extract add folder with the same name test into the group --- .../tests/flow-folders/flow-folder.spec.js | 64 ++++++++++++------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js index ece1c461..0f2b0c90 100644 --- a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js +++ b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js @@ -119,28 +119,19 @@ test.describe('Folders', () => { ).toHaveCount(0); }); - await test.step('should be able to add a folder with the same name', async () => { - await flowsPage.addNewFolderButton.click(); - await createFolderDialog.folderNameInput.fill('newFolder'); - await createFolderDialog.createButton.click(); - await expect(createFolderDialog.successAlert).toHaveCount(1); - await createFolderDialog.closeDialog.click(); - await expect(flowsPage.userFolders.getByText('newFolder')).toHaveCount(2); - }); - await test.step('should be able to update a folder', async () => { - await expect(flowsPage.userFolders.getByText('newFolder2')).toHaveCount( - 0 - ); + await expect( + flowsPage.userFolders.getByText('updatedFolderName') + ).toHaveCount(0); await flowsPage.userFolders.getByText('newFolder').first().click(); await flowsPage.editFolder.click(); - await updateFolderDialog.folderNameInput.fill('newFolder2'); + await updateFolderDialog.folderNameInput.fill('updatedFolderName'); await updateFolderDialog.updateButton.click(); await expect(updateFolderDialog.successAlert).toHaveCount(1); await updateFolderDialog.closeDialog.click(); - await expect(flowsPage.userFolders.getByText('newFolder2')).toHaveCount( - 1 - ); + await expect( + flowsPage.userFolders.getByText('updatedFolderName') + ).toHaveCount(1); await flowsPage.flowRow .filter({ hasText: 'uncategorizedFlow', @@ -149,22 +140,24 @@ test.describe('Folders', () => { await expect(page).toHaveURL( /\/editor\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/ ); - await expect(flowEditorPage.folderName).toContainText('newFolder2'); + await expect(flowEditorPage.folderName).toContainText( + 'updatedFolderName' + ); await flowEditorPage.goBackButton.click(); }); await test.step('should be able to delete a folder with a flow', async () => { - await expect(flowsPage.userFolders.getByText('newFolder2')).toHaveCount( - 1 - ); + await expect( + flowsPage.userFolders.getByText('updatedFolderName') + ).toHaveCount(1); await flowsPage.deleteFolder.click(); await deleteFolderDialog.cancelButton.click(); await flowsPage.deleteFolder.click(); await deleteFolderDialog.deleteButton.click(); - await expect(flowsPage.userFolders.getByText('newFolder2')).toHaveCount( - 0 - ); + await expect( + flowsPage.userFolders.getByText('updatedFolderName') + ).toHaveCount(0); await expect(flowsPage.deleteFolderSuccessAlert).toHaveCount(1); await flowsPage.flowRow .filter({ @@ -249,6 +242,31 @@ test.describe('Folders', () => { await expect(flowEditorPage.folderName).toContainText('newFolder'); }); + test('should be able to add a folder with the same name', async ({ + flowsPage, + page, + }) => { + const createFolderDialog = new CreateFolderDialog(page); + + await flowsPage.addNewFolderButton.click(); + await createFolderDialog.folderNameInput.fill('sameNameFolder'); + await createFolderDialog.createButton.click(); + await expect(createFolderDialog.successAlert).toHaveCount(1); + await createFolderDialog.closeDialog.click(); + await expect(flowsPage.userFolders.getByText('sameNameFolder')).toHaveCount( + 1 + ); + + await flowsPage.addNewFolderButton.click(); + await createFolderDialog.folderNameInput.fill('sameNameFolder'); + await createFolderDialog.createButton.click(); + await expect(createFolderDialog.successAlert).toHaveCount(1); + await createFolderDialog.closeDialog.click(); + await expect(flowsPage.userFolders.getByText('sameNameFolder')).toHaveCount( + 2 + ); + }); + test('non-owner folder visibility', async ({ page, flowsPage, From 1d5a2556db83673903f2295d4da06606a2df06cd Mon Sep 17 00:00:00 2001 From: Jakub P Date: Thu, 10 Apr 2025 14:30:55 +0200 Subject: [PATCH 4/9] test: make test flow name random --- .../tests/flow-folders/flow-folder.spec.js | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js index 0f2b0c90..72ea9a68 100644 --- a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js +++ b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js @@ -15,6 +15,7 @@ const { getToken } = require('../../helpers/auth-api-helper'); const { addUser, acceptInvitation } = require('../../helpers/user-api-helper'); const { addFolder } = require('../../helpers/folder-api-helper'); const { createFlow, updateFlowName } = require('../../helpers/flow-api-helper'); +import Crypto from 'crypto'; test.describe('Folders', () => { test('owner folder lifecycle', async ({ @@ -26,25 +27,26 @@ test.describe('Folders', () => { const updateFolderDialog = new UpdateFolderDialog(page); const folderMoveToDialog = new MoveFolderDialog(page); const deleteFolderDialog = new DeleteFolderDialog(page); + const flowName = Crypto.randomUUID(); await test.step('new flow should be in uncategorized folder', async () => { await flowsPage.createFlowButton.click(); await flowEditorPage.flowName.click(); - await flowEditorPage.flowNameInput.fill('uncategorizedFlow'); + await flowEditorPage.flowNameInput.fill(flowName); await flowEditorPage.flowStep.first().click(); await flowEditorPage.goBackButton.click(); await expect(page).toHaveURL('/flows'); - await flowsPage.searchInput.fill('uncategorizedFlow'); + await flowsPage.searchInput.fill(flowName); await expect( flowsPage.flowRow.filter({ - hasText: 'uncategorizedFlow', + hasText: flowName, }) ).toHaveCount(1); await flowsPage.uncategorizedFlowsFolder.click(); - await flowsPage.searchInput.fill('uncategorizedFlow'); + await flowsPage.searchInput.fill(flowName); await expect( flowsPage.flowRow.filter({ - hasText: 'uncategorizedFlow', + hasText: flowName, }) ).toHaveCount(1); }); @@ -71,7 +73,7 @@ test.describe('Folders', () => { await flowsPage.allFlowsFolder.click(); await flowsPage.flowRow .filter({ - hasText: 'uncategorizedFlow', + hasText: flowName, }) .getByRole('button') .click(); @@ -86,15 +88,15 @@ test.describe('Folders', () => { await test.step('flow should be visible in the new folder and in all flows folder', async () => { await flowsPage.userFolders.getByText('newFolder').click(); - await flowsPage.searchInput.fill('uncategorizedFlow'); + await flowsPage.searchInput.fill(flowName); await expect( flowsPage.flowRow.filter({ - hasText: 'uncategorizedFlow', + hasText: flowName, }) ).toHaveCount(1); await flowsPage.flowRow .filter({ - hasText: 'uncategorizedFlow', + hasText: flowName, }) .click(); await expect(page).toHaveURL( @@ -104,17 +106,17 @@ test.describe('Folders', () => { await flowEditorPage.goBackButton.click(); await flowsPage.allFlowsFolder.click(); - await flowsPage.searchInput.fill('uncategorizedFlow'); + await flowsPage.searchInput.fill(flowName); await expect( flowsPage.flowRow.filter({ - hasText: 'uncategorizedFlow', + hasText: flowName, }) ).toHaveCount(1); await flowsPage.uncategorizedFlowsFolder.click(); - await flowsPage.searchInput.fill('uncategorizedFlow'); + await flowsPage.searchInput.fill(flowName); await expect( flowsPage.flowRow.filter({ - hasText: 'uncategorizedFlow', + hasText: flowName, }) ).toHaveCount(0); }); @@ -134,7 +136,7 @@ test.describe('Folders', () => { ).toHaveCount(1); await flowsPage.flowRow .filter({ - hasText: 'uncategorizedFlow', + hasText: flowName, }) .click(); await expect(page).toHaveURL( @@ -161,7 +163,7 @@ test.describe('Folders', () => { await expect(flowsPage.deleteFolderSuccessAlert).toHaveCount(1); await flowsPage.flowRow .filter({ - hasText: 'uncategorizedFlow', + hasText: flowName, }) .click(); await expect(page).toHaveURL( From edcf080500e6705009836960b1266e392ee2ebe4 Mon Sep 17 00:00:00 2001 From: Jakub P Date: Thu, 10 Apr 2025 15:13:43 +0200 Subject: [PATCH 5/9] test: wait for folder update/delete to finish --- .../tests/flow-folders/flow-folder.spec.js | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js index 72ea9a68..33589c16 100644 --- a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js +++ b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js @@ -128,8 +128,14 @@ test.describe('Folders', () => { await flowsPage.userFolders.getByText('newFolder').first().click(); await flowsPage.editFolder.click(); await updateFolderDialog.folderNameInput.fill('updatedFolderName'); - await updateFolderDialog.updateButton.click(); - await expect(updateFolderDialog.successAlert).toHaveCount(1); + await Promise.all([ + page.waitForResponse( + (resp) => /(\/folders\/.*)/.test(resp.url()) && resp.status() === 200 + ), + updateFolderDialog.updateButton.click(), + expect(updateFolderDialog.successAlert).toHaveCount(1), + ]); + await updateFolderDialog.closeDialog.click(); await expect( flowsPage.userFolders.getByText('updatedFolderName') @@ -156,11 +162,17 @@ test.describe('Folders', () => { await flowsPage.deleteFolder.click(); await deleteFolderDialog.cancelButton.click(); await flowsPage.deleteFolder.click(); - await deleteFolderDialog.deleteButton.click(); - await expect( - flowsPage.userFolders.getByText('updatedFolderName') - ).toHaveCount(0); - await expect(flowsPage.deleteFolderSuccessAlert).toHaveCount(1); + await Promise.all([ + page.waitForResponse( + (resp) => /(\/folders\/.*)/.test(resp.url()) && resp.status() === 204 + ), + deleteFolderDialog.deleteButton.click(), + expect( + flowsPage.userFolders.getByText('updatedFolderName') + ).toHaveCount(0), + expect(flowsPage.deleteFolderSuccessAlert).toHaveCount(1), + ]); + await flowsPage.flowRow .filter({ hasText: flowName, From b5917509a64399c2d33f106c6ab450c8104c93cb Mon Sep 17 00:00:00 2001 From: Jakub P Date: Thu, 10 Apr 2025 17:58:54 +0200 Subject: [PATCH 6/9] test: assert proper page url --- packages/e2e-tests/tests/flow-folders/flow-folder.spec.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js index 33589c16..34f625ef 100644 --- a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js +++ b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js @@ -163,6 +163,10 @@ test.describe('Folders', () => { await deleteFolderDialog.cancelButton.click(); await flowsPage.deleteFolder.click(); await Promise.all([ + page.waitForResponse( + (resp) => + /(\/flows\?name=.*)/.test(resp.url()) && resp.status() === 200 + ), page.waitForResponse( (resp) => /(\/folders\/.*)/.test(resp.url()) && resp.status() === 204 ), @@ -172,6 +176,9 @@ test.describe('Folders', () => { ).toHaveCount(0), expect(flowsPage.deleteFolderSuccessAlert).toHaveCount(1), ]); + await expect(page).toHaveURL( + /\/flows\?flowName=[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/ + ); await flowsPage.flowRow .filter({ From c5b2e6027fd4c8bd09c4e48d7e45f9efb34435bd Mon Sep 17 00:00:00 2001 From: Jakub P Date: Thu, 10 Apr 2025 19:11:44 +0200 Subject: [PATCH 7/9] test: changes in assertions --- .../tests/flow-folders/flow-folder.spec.js | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js index 34f625ef..f78b205c 100644 --- a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js +++ b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js @@ -128,14 +128,8 @@ test.describe('Folders', () => { await flowsPage.userFolders.getByText('newFolder').first().click(); await flowsPage.editFolder.click(); await updateFolderDialog.folderNameInput.fill('updatedFolderName'); - await Promise.all([ - page.waitForResponse( - (resp) => /(\/folders\/.*)/.test(resp.url()) && resp.status() === 200 - ), - updateFolderDialog.updateButton.click(), - expect(updateFolderDialog.successAlert).toHaveCount(1), - ]); - + await updateFolderDialog.updateButton.click(); + await expect(updateFolderDialog.successAlert).toHaveCount(1); await updateFolderDialog.closeDialog.click(); await expect( flowsPage.userFolders.getByText('updatedFolderName') @@ -148,6 +142,7 @@ test.describe('Folders', () => { await expect(page).toHaveURL( /\/editor\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/ ); + await page.reload(); await expect(flowEditorPage.folderName).toContainText( 'updatedFolderName' ); @@ -162,20 +157,13 @@ test.describe('Folders', () => { await flowsPage.deleteFolder.click(); await deleteFolderDialog.cancelButton.click(); await flowsPage.deleteFolder.click(); - await Promise.all([ - page.waitForResponse( - (resp) => - /(\/flows\?name=.*)/.test(resp.url()) && resp.status() === 200 - ), - page.waitForResponse( - (resp) => /(\/folders\/.*)/.test(resp.url()) && resp.status() === 204 - ), - deleteFolderDialog.deleteButton.click(), - expect( + await deleteFolderDialog.deleteButton.click(), + await expect( flowsPage.userFolders.getByText('updatedFolderName') - ).toHaveCount(0), - expect(flowsPage.deleteFolderSuccessAlert).toHaveCount(1), - ]); + ).toHaveCount(0); + await expect(flowsPage.deleteFolderSuccessAlert).toHaveCount(1); + await flowsPage.deleteFolderSuccessAlert.click(); + await expect(flowsPage.deleteFolderSuccessAlert).toHaveCount(0); await expect(page).toHaveURL( /\/flows\?flowName=[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/ ); From 2ebe05e55ad4a9bb673602ef06c5c59d78ec8f4b Mon Sep 17 00:00:00 2001 From: Jakub P Date: Sat, 3 May 2025 23:53:55 +0200 Subject: [PATCH 8/9] test: enable flow folder reassing test for non-owner --- packages/e2e-tests/.env-example | 7 +- .../e2e-tests/helpers/folder-api-helper.js | 2 +- .../tests/flow-folders/flow-folder.spec.js | 86 ++++++++++++++++++- 3 files changed, 91 insertions(+), 4 deletions(-) diff --git a/packages/e2e-tests/.env-example b/packages/e2e-tests/.env-example index 0cf8775e..446683be 100644 --- a/packages/e2e-tests/.env-example +++ b/packages/e2e-tests/.env-example @@ -3,4 +3,9 @@ POSTGRES_USER=automatisch_user POSTGRES_PASSWORD=automatisch_password POSTGRES_PORT=5432 POSTGRES_HOST=localhost -BACKEND_APP_URL=http://localhost:3000 \ No newline at end of file +BACKEND_APP_URL=http://localhost:3000 +LOGIN_EMAIL=user@automatisch.io +LOGIN_PASSWORD=sample +ENCRYPTION_KEY=sample_encryption_key +WEBHOOK_SECRET_KEY=sample_webhook_secret_key +LICENSE_KEY=dummy_license_key \ No newline at end of file diff --git a/packages/e2e-tests/helpers/folder-api-helper.js b/packages/e2e-tests/helpers/folder-api-helper.js index 3438bf9e..c68d9ca9 100644 --- a/packages/e2e-tests/helpers/folder-api-helper.js +++ b/packages/e2e-tests/helpers/folder-api-helper.js @@ -2,7 +2,7 @@ const { expect } = require('../fixtures/index'); export const addFolder = async (apiRequest, token, folderName) => { const addFolderResponse = await apiRequest.post( - `${process.env.BACKEND_APP_URL}/api/v1/folders`, + `${process.env.BACKEND_APP_URL}/internal/api/v1/folders`, { headers: { Authorization: token }, data: { name: folderName }, diff --git a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js index f78b205c..4d2de36f 100644 --- a/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js +++ b/packages/e2e-tests/tests/flow-folders/flow-folder.spec.js @@ -389,9 +389,91 @@ test.describe('Folders', () => { }); }); - test.skip('non-owner should not reassing folder of different user', async ({ + test('non-owner should not reassign folder of different user', async ({ page, + flowsPage, + adminCreateUserPage, }) => { - // TODO feature is wip https://github.com/automatisch/automatisch/pull/2420 + const folderMoveToDialog = new MoveFolderDialog(page); + const apiRequest = await request.newContext(); + const tokenJsonResponse = await getToken(apiRequest); + let userTokenJsonResponse; + let flowId; + + await test.step('add another user', async () => { + adminCreateUserPage.seed( + Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER) + ); + const testUser = adminCreateUserPage.generateUser(); + + const addUserResponse = await addUser( + apiRequest, + tokenJsonResponse.data.token, + { + fullName: testUser.fullName, + email: testUser.email, + } + ); + + const acceptToken = + addUserResponse.data.acceptInvitationUrl.split('=')[1]; + await acceptInvitation(apiRequest, { + token: acceptToken, + password: 'alamakota', + }); + userTokenJsonResponse = await getToken( + apiRequest, + testUser.email, + 'alamakota' + ); + }); + + await test.step('add folder as an another user', async () => { + await addFolder( + apiRequest, + userTokenJsonResponse.data.token, + 'anotherUserFolder' + ); + }); + + await test.step('add flow as an another user', async () => { + const flow = await createFlow( + apiRequest, + userTokenJsonResponse.data.token + ); + flowId = flow.data.id; + await updateFlowName( + apiRequest, + userTokenJsonResponse.data.token, + flowId + ); + await page.reload(); + }); + + await test.step("should not be able to move another user's flow", async () => { + await flowsPage.allFlowsFolder.click(); + await flowsPage.searchInput.fill(flowId); + await expect( + flowsPage.flowRow.filter({ + hasText: flowId, + }) + ).toHaveCount(1); + + await flowsPage.flowRow + .filter({ + hasText: flowId, + }) + .getByRole('button') + .click(); + await flowsPage.moveTo.click(); + + await expect( + page.getByText( + 'A flow can only be moved to a folder by the flow owner.' + ) + ).toHaveCount(1); + + await expect(folderMoveToDialog.moveButton).toBeDisabled(); + }); }); }); From c6b919f1832c64320456ab8750c76468d743f4db Mon Sep 17 00:00:00 2001 From: Jakub P Date: Sun, 4 May 2025 00:19:11 +0200 Subject: [PATCH 9/9] test: improve navigateTo on users-page --- packages/e2e-tests/fixtures/admin/users-page.js | 10 ++++++++++ packages/e2e-tests/tests/admin/manage-roles.spec.js | 4 ++-- packages/e2e-tests/tests/admin/manage-users.spec.js | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/e2e-tests/fixtures/admin/users-page.js b/packages/e2e-tests/fixtures/admin/users-page.js index 9b707669..301ad47d 100644 --- a/packages/e2e-tests/fixtures/admin/users-page.js +++ b/packages/e2e-tests/fixtures/admin/users-page.js @@ -24,6 +24,16 @@ export class AdminUsersPage extends AuthenticatedPage { } async navigateTo() { + await this.profileMenuButton.click(); + await Promise.all([this.adminMenuItem.click(), this.isMounted()]); + if (await this.usersLoader.isVisible()) { + await this.usersLoader.waitFor({ + state: 'detached', + }); + } + } + + async navigateToAndWaitForUsers() { await this.profileMenuButton.click(); await Promise.all([ this.page.waitForResponse( diff --git a/packages/e2e-tests/tests/admin/manage-roles.spec.js b/packages/e2e-tests/tests/admin/manage-roles.spec.js index 2419ee84..194fb110 100644 --- a/packages/e2e-tests/tests/admin/manage-roles.spec.js +++ b/packages/e2e-tests/tests/admin/manage-roles.spec.js @@ -195,7 +195,7 @@ test.describe('Role management page', () => { }); await test.step('Change the role the user has', async () => { - await adminUsersPage.navigateTo(); + await adminUsersPage.navigateToAndWaitForUsers(); await adminUsersPage.usersLoader.waitFor({ state: 'detached', }); @@ -264,7 +264,7 @@ test.describe('Role management page', () => { }); await test.step('Delete this user', async () => { - await adminUsersPage.navigateTo(); + await adminUsersPage.navigateToAndWaitForUsers(); const row = await adminUsersPage.findUserPageWithEmail( 'user-delete-role-test@automatisch.io' ); diff --git a/packages/e2e-tests/tests/admin/manage-users.spec.js b/packages/e2e-tests/tests/admin/manage-users.spec.js index 2887412c..274852d4 100644 --- a/packages/e2e-tests/tests/admin/manage-users.spec.js +++ b/packages/e2e-tests/tests/admin/manage-users.spec.js @@ -100,7 +100,7 @@ test.describe('User management page', () => { }); await test.step('Delete the created user', async () => { - await adminUsersPage.navigateTo(); + await adminUsersPage.navigateToAndWaitForUsers(); await adminUsersPage.findUserPageWithEmail(testUser.email); const userRow = await adminUsersPage.getUserRowByEmail(testUser.email); await adminUsersPage.clickDeleteUser(userRow); @@ -198,7 +198,7 @@ test.describe('User management page', () => { }); await test.step('Try editing the second user to have the email of the first user', async () => { - await adminUsersPage.navigateTo(); + await adminUsersPage.navigateToAndWaitForUsers(); await adminUsersPage.findUserPageWithEmail(user2.email); let userRow = await adminUsersPage.getUserRowByEmail(user2.email); await adminUsersPage.clickEditUser(userRow);