From 53d95366e996855738ea8f390b77edf39a472d17 Mon Sep 17 00:00:00 2001 From: "Jakub P." Date: Tue, 10 Dec 2024 00:32:51 +0100 Subject: [PATCH] test: use new alert in create role and create user tests --- .../fixtures/admin/create-user-page.js | 18 +- .../tests/admin/manage-roles.spec.js | 154 +++--- .../tests/admin/manage-users.spec.js | 442 ++++++++---------- .../tests/flow-editor/create-flow.spec.js | 335 +++++++------ .../tests/my-profile/profile-updates.spec.js | 5 +- 5 files changed, 430 insertions(+), 524 deletions(-) diff --git a/packages/e2e-tests/fixtures/admin/create-user-page.js b/packages/e2e-tests/fixtures/admin/create-user-page.js index 135b38fb..ddf0f6e6 100644 --- a/packages/e2e-tests/fixtures/admin/create-user-page.js +++ b/packages/e2e-tests/fixtures/admin/create-user-page.js @@ -1,3 +1,5 @@ +const { expect } = require('@playwright/test'); + const { faker } = require('@faker-js/faker'); const { AuthenticatedPage } = require('../authenticated-page'); @@ -11,11 +13,17 @@ export class AdminCreateUserPage extends AuthenticatedPage { super(page); this.fullNameInput = page.getByTestId('full-name-input'); this.emailInput = page.getByTestId('email-input'); - this.roleInput = page.getByTestId('role.id-autocomplete'); + this.roleInput = page.getByTestId('roleId-autocomplete'); this.createButton = page.getByTestId('create-button'); this.pageTitle = page.getByTestId('create-user-title'); - this.invitationEmailInfoAlert = page.getByTestId('invitation-email-info-alert'); - this.acceptInvitationLink = page.getByTestId('invitation-email-info-alert').getByRole('link'); + this.invitationEmailInfoAlert = page.getByTestId( + 'invitation-email-info-alert' + ); + this.acceptInvitationLink = page + .getByTestId('invitation-email-info-alert') + .getByRole('link'); + this.createUserSuccessAlert = page.getByTestId('create-user-success-alert'); + this.fieldError = page.locator('p[id$="-helper-text"]'); } seed(seed) { @@ -28,4 +36,8 @@ export class AdminCreateUserPage extends AuthenticatedPage { email: faker.internet.email().toLowerCase(), }; } + + async expectCreateUserSuccessAlertToBeVisible() { + await expect(this.createUserSuccessAlert).toBeVisible(); + } } diff --git a/packages/e2e-tests/tests/admin/manage-roles.spec.js b/packages/e2e-tests/tests/admin/manage-roles.spec.js index 00299c5d..1e9a405f 100644 --- a/packages/e2e-tests/tests/admin/manage-roles.spec.js +++ b/packages/e2e-tests/tests/admin/manage-roles.spec.js @@ -35,9 +35,8 @@ test.describe('Role management page', () => { await adminCreateRolePage.closeSnackbar(); }); - let roleRow = await test.step( - 'Make sure role data is correct', - async () => { + let roleRow = + await test.step('Make sure role data is correct', async () => { const roleRow = await adminRolesPage.getRoleRowByName( 'Create Edit Test' ); @@ -48,8 +47,7 @@ test.describe('Role management page', () => { await expect(roleData.canEdit).toBe(true); await expect(roleData.canDelete).toBe(true); return roleRow; - } - ); + }); await test.step('Edit the role', async () => { await adminRolesPage.clickEditRole(roleRow); @@ -67,9 +65,8 @@ test.describe('Role management page', () => { await adminEditRolePage.closeSnackbar(); }); - roleRow = await test.step( - 'Make sure changes reflected on roles page', - async () => { + roleRow = + await test.step('Make sure changes reflected on roles page', async () => { await adminRolesPage.isMounted(); const roleRow = await adminRolesPage.getRoleRowByName( 'Create Update Test' @@ -81,8 +78,7 @@ test.describe('Role management page', () => { await expect(roleData.canEdit).toBe(true); await expect(roleData.canDelete).toBe(true); return roleRow; - } - ); + }); await test.step('Delete the role', async () => { await adminRolesPage.clickDeleteRole(roleRow); @@ -184,49 +180,39 @@ test.describe('Role management page', () => { await expect(snackbar.variant).toBe('success'); await adminCreateRolePage.closeSnackbar(); }); - await test.step( - 'Create a new user with the "Delete Role" role', - async () => { - await adminUsersPage.navigateTo(); - await adminUsersPage.createUserButton.click(); - await adminCreateUserPage.fullNameInput.fill('User Role Test'); - await adminCreateUserPage.emailInput.fill( - 'user-role-test@automatisch.io' - ); - await adminCreateUserPage.roleInput.click(); - await adminCreateUserPage.page - .getByRole('option', { name: 'Delete Role', exact: true }) - .click(); - await adminCreateUserPage.createButton.click(); - await adminCreateUserPage.snackbar.waitFor({ - state: 'attached', - }); - await adminCreateUserPage.invitationEmailInfoAlert.waitFor({ - state: 'attached', - }); - const snackbar = await adminUsersPage.getSnackbarData( - 'snackbar-create-user-success' - ); - await expect(snackbar.variant).toBe('success'); - await adminUsersPage.closeSnackbar(); - } - ); - await test.step( - 'Try to delete "Delete Role" role when new user has it', - async () => { - await adminRolesPage.navigateTo(); - const row = await adminRolesPage.getRoleRowByName('Delete Role'); - const modal = await adminRolesPage.clickDeleteRole(row); - await modal.deleteButton.click(); - await adminRolesPage.snackbar.waitFor({ - state: 'attached', - }); - const snackbar = await adminRolesPage.getSnackbarData('snackbar-delete-role-error'); - await expect(snackbar.variant).toBe('error'); - await adminRolesPage.closeSnackbar(); - await modal.close(); - } - ); + await test.step('Create a new user with the "Delete Role" role', async () => { + await adminUsersPage.navigateTo(); + await adminUsersPage.createUserButton.click(); + await adminCreateUserPage.fullNameInput.fill('User Role Test'); + await adminCreateUserPage.emailInput.fill( + 'user-role-test@automatisch.io' + ); + await adminCreateUserPage.roleInput.click(); + await adminCreateUserPage.page + .getByRole('option', { name: 'Delete Role', exact: true }) + .click(); + await adminCreateUserPage.createButton.click(); + await adminCreateUserPage.invitationEmailInfoAlert.waitFor({ + state: 'attached', + }); + await adminCreateUserPage.expectCreateUserSuccessAlertToBeVisible(); + }); + + await test.step('Try to delete "Delete Role" role when new user has it', async () => { + await adminRolesPage.navigateTo(); + const row = await adminRolesPage.getRoleRowByName('Delete Role'); + const modal = await adminRolesPage.clickDeleteRole(row); + await modal.deleteButton.click(); + await adminRolesPage.snackbar.waitFor({ + state: 'attached', + }); + const snackbar = await adminRolesPage.getSnackbarData( + 'snackbar-delete-role-error' + ); + await expect(snackbar.variant).toBe('error'); + await adminRolesPage.closeSnackbar(); + await modal.close(); + }); await test.step('Change the role the user has', async () => { await adminUsersPage.navigateTo(); await adminUsersPage.usersLoader.waitFor({ @@ -301,24 +287,16 @@ test.describe('Role management page', () => { .getByRole('option', { name: 'Cannot Delete Role' }) .click(); await adminCreateUserPage.createButton.click(); - await adminCreateUserPage.snackbar.waitFor({ - state: 'attached', - }); await adminCreateUserPage.invitationEmailInfoAlert.waitFor({ state: 'attached', }); - const snackbar = await adminCreateUserPage.getSnackbarData( - 'snackbar-create-user-success' - ); - await expect(snackbar.variant).toBe('success'); - await adminCreateUserPage.closeSnackbar(); + await adminCreateUserPage.expectCreateUserSuccessAlertToBeVisible(); }); await test.step('Delete this user', async () => { await adminUsersPage.navigateTo(); const row = await adminUsersPage.findUserPageWithEmail( 'user-delete-role-test@automatisch.io' ); - // await test.waitForTimeout(10000); const modal = await adminUsersPage.clickDeleteUser(row); await modal.deleteButton.click(); await adminUsersPage.snackbar.waitFor({ @@ -385,17 +363,10 @@ test('Accessibility of role management page', async ({ .getByRole('option', { name: 'Basic Test' }) .click(); await adminCreateUserPage.createButton.click(); - await adminCreateUserPage.snackbar.waitFor({ - state: 'attached', - }); await adminCreateUserPage.invitationEmailInfoAlert.waitFor({ state: 'attached', }); - const snackbar = await adminCreateUserPage.getSnackbarData( - 'snackbar-create-user-success' - ); - await expect(snackbar.variant).toBe('success'); - await adminCreateUserPage.closeSnackbar(); + await adminCreateUserPage.expectCreateUserSuccessAlertToBeVisible(); }); await test.step('Logout and login to the basic role user', async () => { @@ -409,42 +380,35 @@ test('Accessibility of role management page', async ({ await page.getByTestId('logout-item').click(); const acceptInvitationPage = new AcceptInvitation(page); - await acceptInvitationPage.open(acceptInvitatonToken); - await acceptInvitationPage.acceptInvitation('sample'); const loginPage = new LoginPage(page); - - // await loginPage.isMounted(); await loginPage.login('basic-role-test@automatisch.io', 'sample'); await expect(loginPage.loginButton).not.toBeVisible(); await expect(page).toHaveURL('/flows'); }); - await test.step( - 'Navigate to the admin settings page and make sure it is blank', - async () => { - const pageUrl = new URL(page.url()); - const url = `${pageUrl.origin}/admin-settings/users`; - await page.goto(url); - await page.waitForTimeout(750); - const isUnmounted = await page.evaluate(() => { - // eslint-disable-next-line no-undef - const root = document.querySelector('#root'); + await test.step('Navigate to the admin settings page and make sure it is blank', async () => { + const pageUrl = new URL(page.url()); + const url = `${pageUrl.origin}/admin-settings/users`; + await page.goto(url); + await page.waitForTimeout(750); + const isUnmounted = await page.evaluate(() => { + // eslint-disable-next-line no-undef + const root = document.querySelector('#root'); - if (root) { - // We have react query devtools only in dev env. - // In production, there is nothing in root. - // That's why `<= 1`. - return root.children.length <= 1; - } + if (root) { + // We have react query devtools only in dev env. + // In production, there is nothing in root. + // That's why `<= 1`. + return root.children.length <= 1; + } - return false; - }); - await expect(isUnmounted).toBe(true); - } - ); + return false; + }); + await expect(isUnmounted).toBe(true); + }); await test.step('Log back into the admin account', async () => { await page.goto('/'); diff --git a/packages/e2e-tests/tests/admin/manage-users.spec.js b/packages/e2e-tests/tests/admin/manage-users.spec.js index d6fc1507..af7f7083 100644 --- a/packages/e2e-tests/tests/admin/manage-users.spec.js +++ b/packages/e2e-tests/tests/admin/manage-users.spec.js @@ -5,281 +5,221 @@ const { test, expect } = require('../../fixtures/index'); * otherwise tests will fail since users are only *soft*-deleted */ test.describe('User management page', () => { - test.beforeEach(async ({ adminUsersPage }) => { await adminUsersPage.navigateTo(); await adminUsersPage.closeSnackbar(); }); - test( - 'User creation and deletion process', - async ({ adminCreateUserPage, adminEditUserPage, adminUsersPage }) => { - adminCreateUserPage.seed(9000); - const user = adminCreateUserPage.generateUser(); - await adminUsersPage.usersLoader.waitFor({ - state: 'detached' /* Note: state: 'visible' introduces flakiness + test('User creation and deletion process', async ({ + adminCreateUserPage, + adminEditUserPage, + adminUsersPage, + }) => { + adminCreateUserPage.seed(9000); + const user = adminCreateUserPage.generateUser(); + await adminUsersPage.usersLoader.waitFor({ + state: 'detached' /* Note: state: 'visible' introduces flakiness because visibility: hidden is used as part of the state transition in notistack, see https://github.com/iamhosseindhv/notistack/blob/122f47057eb7ce5a1abfe923316cf8475303e99a/src/transitions/Collapse/Collapse.tsx#L110 - */ + */, + }); + await test.step('Create a user', async () => { + await adminUsersPage.createUserButton.click(); + await adminCreateUserPage.fullNameInput.fill(user.fullName); + await adminCreateUserPage.emailInput.fill(user.email); + await adminCreateUserPage.roleInput.click(); + await adminCreateUserPage.page + .getByRole('option', { name: 'Admin' }) + .click(); + await adminCreateUserPage.createButton.click(); + await adminCreateUserPage.invitationEmailInfoAlert.waitFor({ + state: 'attached', }); - await test.step( - 'Create a user', - async () => { - await adminUsersPage.createUserButton.click(); - await adminCreateUserPage.fullNameInput.fill(user.fullName); - await adminCreateUserPage.emailInput.fill(user.email); - await adminCreateUserPage.roleInput.click(); - await adminCreateUserPage.page.getByRole( - 'option', { name: 'Admin' } - ).click(); - await adminCreateUserPage.createButton.click(); - await adminCreateUserPage.invitationEmailInfoAlert.waitFor({ - state: 'attached' - }); - const snackbar = await adminUsersPage.getSnackbarData( - 'snackbar-create-user-success' - ); - await expect(snackbar.variant).toBe('success'); - await adminUsersPage.navigateTo(); - await adminUsersPage.closeSnackbar(); - } + await adminCreateUserPage.expectCreateUserSuccessAlertToBeVisible(); + await adminUsersPage.navigateTo(); + }); + await test.step('Check the user exists with the expected properties', async () => { + await adminUsersPage.findUserPageWithEmail(user.email); + const userRow = await adminUsersPage.getUserRowByEmail(user.email); + const data = await adminUsersPage.getRowData(userRow); + await expect(data.email).toBe(user.email); + await expect(data.fullName).toBe(user.fullName); + await expect(data.role).toBe('Admin'); + }); + await test.step('Edit user info and make sure the edit works correctly', async () => { + await adminUsersPage.findUserPageWithEmail(user.email); + + let userRow = await adminUsersPage.getUserRowByEmail(user.email); + await adminUsersPage.clickEditUser(userRow); + await adminEditUserPage.waitForLoad(user.fullName); + const newUserInfo = adminEditUserPage.generateUser(); + await adminEditUserPage.fullNameInput.fill(newUserInfo.fullName); + await adminEditUserPage.updateButton.click(); + + const snackbar = await adminUsersPage.getSnackbarData( + 'snackbar-edit-user-success' ); - await test.step( - 'Check the user exists with the expected properties', - async () => { - await adminUsersPage.findUserPageWithEmail(user.email); - const userRow = await adminUsersPage.getUserRowByEmail(user.email); - const data = await adminUsersPage.getRowData(userRow); - await expect(data.email).toBe(user.email); - await expect(data.fullName).toBe(user.fullName); - await expect(data.role).toBe('Admin'); - } + await expect(snackbar.variant).toBe('success'); + await adminUsersPage.closeSnackbar(); + + await adminUsersPage.findUserPageWithEmail(user.email); + userRow = await adminUsersPage.getUserRowByEmail(user.email); + const rowData = await adminUsersPage.getRowData(userRow); + await expect(rowData.fullName).toBe(newUserInfo.fullName); + }); + await test.step('Delete user and check the page confirms this deletion', async () => { + await adminUsersPage.findUserPageWithEmail(user.email); + const userRow = await adminUsersPage.getUserRowByEmail(user.email); + await adminUsersPage.clickDeleteUser(userRow); + const modal = adminUsersPage.deleteUserModal; + await modal.deleteButton.click(); + + const snackbar = await adminUsersPage.getSnackbarData( + 'snackbar-delete-user-success' ); - await test.step( - 'Edit user info and make sure the edit works correctly', - async () => { - await adminUsersPage.findUserPageWithEmail(user.email); + await expect(snackbar.variant).toBe('success'); + await adminUsersPage.closeSnackbar(); + await expect(userRow).not.toBeVisible(false); + }); + }); - let userRow = await adminUsersPage.getUserRowByEmail(user.email); - await adminUsersPage.clickEditUser(userRow); - await adminEditUserPage.waitForLoad(user.fullName); - const newUserInfo = adminEditUserPage.generateUser(); - await adminEditUserPage.fullNameInput.fill(newUserInfo.fullName); - await adminEditUserPage.updateButton.click(); + test('Creating a user which has been deleted', async ({ + adminCreateUserPage, + adminUsersPage, + }) => { + adminCreateUserPage.seed(9100); + const testUser = adminCreateUserPage.generateUser(); - const snackbar = await adminUsersPage.getSnackbarData( - 'snackbar-edit-user-success' - ); - await expect(snackbar.variant).toBe('success'); - await adminUsersPage.closeSnackbar(); - - await adminUsersPage.findUserPageWithEmail(user.email); - userRow = await adminUsersPage.getUserRowByEmail(user.email); - const rowData = await adminUsersPage.getRowData(userRow); - await expect(rowData.fullName).toBe(newUserInfo.fullName); - } - ); - await test.step( - 'Delete user and check the page confirms this deletion', - async () => { - await adminUsersPage.findUserPageWithEmail(user.email); - const userRow = await adminUsersPage.getUserRowByEmail(user.email); - await adminUsersPage.clickDeleteUser(userRow); - const modal = adminUsersPage.deleteUserModal; - await modal.deleteButton.click(); - - const snackbar = await adminUsersPage.getSnackbarData( - 'snackbar-delete-user-success' - ); - await expect(snackbar.variant).toBe('success'); - await adminUsersPage.closeSnackbar(); - await expect(userRow).not.toBeVisible(false); - } - ); + await test.step('Create the test user', async () => { + await adminUsersPage.navigateTo(); + await adminUsersPage.createUserButton.click(); + await adminCreateUserPage.fullNameInput.fill(testUser.fullName); + await adminCreateUserPage.emailInput.fill(testUser.email); + await adminCreateUserPage.roleInput.click(); + await adminCreateUserPage.page + .getByRole('option', { name: 'Admin' }) + .click(); + await adminCreateUserPage.createButton.click(); + await adminCreateUserPage.expectCreateUserSuccessAlertToBeVisible(); }); - test( - 'Creating a user which has been deleted', - async ({ adminCreateUserPage, adminUsersPage }) => { - adminCreateUserPage.seed(9100); - const testUser = adminCreateUserPage.generateUser(); - - await test.step( - 'Create the test user', - async () => { - await adminUsersPage.navigateTo(); - await adminUsersPage.createUserButton.click(); - await adminCreateUserPage.fullNameInput.fill(testUser.fullName); - await adminCreateUserPage.emailInput.fill(testUser.email); - await adminCreateUserPage.roleInput.click(); - await adminCreateUserPage.page.getByRole( - 'option', { name: 'Admin' } - ).click(); - await adminCreateUserPage.createButton.click(); - const snackbar = await adminUsersPage.getSnackbarData( - 'snackbar-create-user-success' - ); - await expect(snackbar.variant).toBe('success'); - await adminUsersPage.closeSnackbar(); - } + await test.step('Delete the created user', async () => { + await adminUsersPage.navigateTo(); + await adminUsersPage.findUserPageWithEmail(testUser.email); + const userRow = await adminUsersPage.getUserRowByEmail(testUser.email); + await adminUsersPage.clickDeleteUser(userRow); + const modal = adminUsersPage.deleteUserModal; + await modal.deleteButton.click(); + const snackbar = await adminUsersPage.getSnackbarData( + 'snackbar-delete-user-success' ); + await expect(snackbar).not.toBeNull(); + await expect(snackbar.variant).toBe('success'); + await adminUsersPage.closeSnackbar(); + await expect(userRow).not.toBeVisible(false); + }); - await test.step( - 'Delete the created user', - async () => { - await adminUsersPage.navigateTo(); - await adminUsersPage.findUserPageWithEmail(testUser.email); - const userRow = await adminUsersPage.getUserRowByEmail(testUser.email); - await adminUsersPage.clickDeleteUser(userRow); - const modal = adminUsersPage.deleteUserModal; - await modal.deleteButton.click(); - const snackbar = await adminUsersPage.getSnackbarData( - 'snackbar-delete-user-success' - ); - await expect(snackbar).not.toBeNull(); - await expect(snackbar.variant).toBe('success'); - await adminUsersPage.closeSnackbar(); - await expect(userRow).not.toBeVisible(false); - } - ); + await test.step('Create the user again', async () => { + await adminUsersPage.createUserButton.click(); + await adminCreateUserPage.fullNameInput.fill(testUser.fullName); + await adminCreateUserPage.emailInput.fill(testUser.email); + await adminCreateUserPage.roleInput.click(); + await adminCreateUserPage.page + .getByRole('option', { name: 'Admin' }) + .click(); + await adminCreateUserPage.createButton.click(); + await expect(adminCreateUserPage.fieldError).toHaveCount(1); + }); + }); - await test.step( - 'Create the user again', - async () => { - await adminUsersPage.createUserButton.click(); - await adminCreateUserPage.fullNameInput.fill(testUser.fullName); - await adminCreateUserPage.emailInput.fill(testUser.email); - await adminCreateUserPage.roleInput.click(); - await adminCreateUserPage.page.getByRole( - 'option', { name: 'Admin' } - ).click(); - await adminCreateUserPage.createButton.click(); - const snackbar = await adminUsersPage.getSnackbarData('snackbar-error'); - await expect(snackbar.variant).toBe('error'); - await adminUsersPage.closeSnackbar(); - } - ); - } - ); + test('Creating a user which already exists', async ({ + adminCreateUserPage, + adminUsersPage, + page, + }) => { + adminCreateUserPage.seed(9200); + const testUser = adminCreateUserPage.generateUser(); - test( - 'Creating a user which already exists', - async ({ adminCreateUserPage, adminUsersPage, page }) => { - adminCreateUserPage.seed(9200); - const testUser = adminCreateUserPage.generateUser(); + await test.step('Create the test user', async () => { + await adminUsersPage.createUserButton.click(); + await adminCreateUserPage.fullNameInput.fill(testUser.fullName); + await adminCreateUserPage.emailInput.fill(testUser.email); + await adminCreateUserPage.roleInput.click(); + await adminCreateUserPage.page + .getByRole('option', { name: 'Admin' }) + .click(); + await adminCreateUserPage.createButton.click(); + await adminCreateUserPage.expectCreateUserSuccessAlertToBeVisible(); + }); - await test.step( - 'Create the test user', - async () => { - await adminUsersPage.createUserButton.click(); - await adminCreateUserPage.fullNameInput.fill(testUser.fullName); - await adminCreateUserPage.emailInput.fill(testUser.email); - await adminCreateUserPage.roleInput.click(); - await adminCreateUserPage.page.getByRole( - 'option', { name: 'Admin' } - ).click(); - await adminCreateUserPage.createButton.click(); - const snackbar = await adminUsersPage.getSnackbarData( - 'snackbar-create-user-success' - ); - await expect(snackbar.variant).toBe('success'); - await adminUsersPage.closeSnackbar(); - } - ); + await test.step('Create the user again', async () => { + await adminUsersPage.navigateTo(); + await adminUsersPage.createUserButton.click(); + await adminCreateUserPage.fullNameInput.fill(testUser.fullName); + await adminCreateUserPage.emailInput.fill(testUser.email); + const createUserPageUrl = page.url(); + await adminCreateUserPage.roleInput.click(); + await adminCreateUserPage.page + .getByRole('option', { name: 'Admin' }) + .click(); + await adminCreateUserPage.createButton.click(); - await test.step( - 'Create the user again', - async () => { - await adminUsersPage.navigateTo(); - await adminUsersPage.createUserButton.click(); - await adminCreateUserPage.fullNameInput.fill(testUser.fullName); - await adminCreateUserPage.emailInput.fill(testUser.email); - const createUserPageUrl = page.url(); - await adminCreateUserPage.roleInput.click(); - await adminCreateUserPage.page.getByRole( - 'option', { name: 'Admin' } - ).click(); - await adminCreateUserPage.createButton.click(); + await expect(page.url()).toBe(createUserPageUrl); + await expect(adminCreateUserPage.fieldError).toHaveCount(1); + }); + }); - await expect(page.url()).toBe(createUserPageUrl); - const snackbar = await adminUsersPage.getSnackbarData('snackbar-error'); - await expect(snackbar.variant).toBe('error'); - await adminUsersPage.closeSnackbar(); - } - ); - } - ); + test('Editing a user to have the same email as another user should not be allowed', async ({ + adminCreateUserPage, + adminEditUserPage, + adminUsersPage, + page, + }) => { + adminCreateUserPage.seed(9300); + const user1 = adminCreateUserPage.generateUser(); + const user2 = adminCreateUserPage.generateUser(); + await test.step('Create the first user', async () => { + await adminUsersPage.navigateTo(); + await adminUsersPage.createUserButton.click(); + await adminCreateUserPage.fullNameInput.fill(user1.fullName); + await adminCreateUserPage.emailInput.fill(user1.email); + await adminCreateUserPage.roleInput.click(); + await adminCreateUserPage.page + .getByRole('option', { name: 'Admin' }) + .click(); + await adminCreateUserPage.createButton.click(); + await adminCreateUserPage.expectCreateUserSuccessAlertToBeVisible(); + }); - test( - 'Editing a user to have the same email as another user should not be allowed', - async ({ - adminCreateUserPage, adminEditUserPage, adminUsersPage, page - }) => { - adminCreateUserPage.seed(9300); - const user1 = adminCreateUserPage.generateUser(); - const user2 = adminCreateUserPage.generateUser(); - await test.step( - 'Create the first user', - async () => { - await adminUsersPage.navigateTo(); - await adminUsersPage.createUserButton.click(); - await adminCreateUserPage.fullNameInput.fill(user1.fullName); - await adminCreateUserPage.emailInput.fill(user1.email); - await adminCreateUserPage.roleInput.click(); - await adminCreateUserPage.page.getByRole( - 'option', { name: 'Admin' } - ).click(); - await adminCreateUserPage.createButton.click(); - const snackbar = await adminUsersPage.getSnackbarData( - 'snackbar-create-user-success' - ); - await expect(snackbar.variant).toBe('success'); - await adminUsersPage.closeSnackbar(); - } - ); + await test.step('Create the second user', async () => { + await adminUsersPage.navigateTo(); + await adminUsersPage.createUserButton.click(); + await adminCreateUserPage.fullNameInput.fill(user2.fullName); + await adminCreateUserPage.emailInput.fill(user2.email); + await adminCreateUserPage.roleInput.click(); + await adminCreateUserPage.page + .getByRole('option', { name: 'Admin' }) + .click(); + await adminCreateUserPage.createButton.click(); + await adminCreateUserPage.expectCreateUserSuccessAlertToBeVisible(); + }); - await test.step( - 'Create the second user', - async () => { - await adminUsersPage.navigateTo(); - await adminUsersPage.createUserButton.click(); - await adminCreateUserPage.fullNameInput.fill(user2.fullName); - await adminCreateUserPage.emailInput.fill(user2.email); - await adminCreateUserPage.roleInput.click(); - await adminCreateUserPage.page.getByRole( - 'option', { name: 'Admin' } - ).click(); - await adminCreateUserPage.createButton.click(); - const snackbar = await adminUsersPage.getSnackbarData( - 'snackbar-create-user-success' - ); - await expect(snackbar.variant).toBe('success'); - await adminUsersPage.closeSnackbar(); - } - ); + await test.step('Try editing the second user to have the email of the first user', async () => { + await adminUsersPage.navigateTo(); + await adminUsersPage.findUserPageWithEmail(user2.email); + let userRow = await adminUsersPage.getUserRowByEmail(user2.email); + await adminUsersPage.clickEditUser(userRow); + await adminEditUserPage.waitForLoad(user2.fullName); + await adminEditUserPage.emailInput.fill(user1.email); + const editPageUrl = page.url(); + await adminEditUserPage.updateButton.click(); - await test.step( - 'Try editing the second user to have the email of the first user', - async () => { - await adminUsersPage.navigateTo(); - await adminUsersPage.findUserPageWithEmail(user2.email); - let userRow = await adminUsersPage.getUserRowByEmail(user2.email); - await adminUsersPage.clickEditUser(userRow); - await adminEditUserPage.waitForLoad(user2.fullName); - await adminEditUserPage.emailInput.fill(user1.email); - const editPageUrl = page.url(); - await adminEditUserPage.updateButton.click(); - - const snackbar = await adminUsersPage.getSnackbarData( - 'snackbar-error' - ); - await expect(snackbar.variant).toBe('error'); - await adminUsersPage.closeSnackbar(); - await expect(page.url()).toBe(editPageUrl); - } - ); - } - ); + const snackbar = await adminUsersPage.getSnackbarData('snackbar-error'); + await expect(snackbar.variant).toBe('error'); + await adminUsersPage.closeSnackbar(); + await expect(page.url()).toBe(editPageUrl); + }); + }); }); diff --git a/packages/e2e-tests/tests/flow-editor/create-flow.spec.js b/packages/e2e-tests/tests/flow-editor/create-flow.spec.js index 98114c27..6f46454a 100644 --- a/packages/e2e-tests/tests/flow-editor/create-flow.spec.js +++ b/packages/e2e-tests/tests/flow-editor/create-flow.spec.js @@ -7,198 +7,191 @@ test('Ensure creating a new flow works', async ({ page }) => { ); }); -test( - 'Create a new flow with a Scheduler step then an Ntfy step', - async ({ flowEditorPage, page }) => { - await test.step('create flow', async () => { - await test.step('navigate to new flow page', async () => { - await page.getByTestId('create-flow-button').click(); - await page.waitForURL( - /\/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}/ - ); +test('Create a new flow with a Scheduler step then an Ntfy step', async ({ + flowEditorPage, + page, +}) => { + await test.step('create flow', async () => { + await test.step('navigate to new flow page', async () => { + await page.getByTestId('create-flow-button').click(); + await page.waitForURL( + /\/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 test.step('has two steps by default', async () => { + await expect(page.getByTestId('flow-step')).toHaveCount(2); + }); + }); + + await test.step('setup Scheduler trigger', async () => { + await test.step('choose app and event substep', async () => { + await test.step('choose application', async () => { + await flowEditorPage.appAutocomplete.click(); + await page.getByRole('option', { name: 'Scheduler' }).click(); }); - - await test.step('has two steps by default', async () => { - await expect(page.getByTestId('flow-step')).toHaveCount(2); + + await test.step('choose and event', async () => { + await expect(flowEditorPage.eventAutocomplete).toBeVisible(); + await flowEditorPage.eventAutocomplete.click(); + await page.getByRole('option', { name: 'Every hour' }).click(); + }); + + await test.step('continue to next step', async () => { + await flowEditorPage.continueButton.click(); + }); + + await test.step('collapses the substep', async () => { + await expect(flowEditorPage.appAutocomplete).not.toBeVisible(); + await expect(flowEditorPage.eventAutocomplete).not.toBeVisible(); }); }); - await test.step('setup Scheduler trigger', async () => { - await test.step('choose app and event substep', async () => { - await test.step('choose application', async () => { - await flowEditorPage.appAutocomplete.click(); - await page - .getByRole('option', { name: 'Scheduler' }) - .click(); - }); - - await test.step('choose and event', async () => { - await expect(flowEditorPage.eventAutocomplete).toBeVisible(); - await flowEditorPage.eventAutocomplete.click(); - await page - .getByRole('option', { name: 'Every hour' }) - .click(); - }); - - await test.step('continue to next step', async () => { - await flowEditorPage.continueButton.click(); - }); - - await test.step('collapses the substep', async () => { - await expect(flowEditorPage.appAutocomplete).not.toBeVisible(); - await expect(flowEditorPage.eventAutocomplete).not.toBeVisible(); - }); + await test.step('set up a trigger', async () => { + await test.step('choose "yes" in "trigger on weekends?"', async () => { + await expect(flowEditorPage.trigger).toBeVisible(); + await flowEditorPage.trigger.click(); + await page.getByRole('option', { name: 'Yes' }).click(); }); - await test.step('set up a trigger', async () => { - await test.step('choose "yes" in "trigger on weekends?"', async () => { - await expect(flowEditorPage.trigger).toBeVisible(); - await flowEditorPage.trigger.click(); - await page.getByRole('option', { name: 'Yes' }).click(); - }); - - await test.step('continue to next step', async () => { - await flowEditorPage.continueButton.click(); - }); - - await test.step('collapses the substep', async () => { - await expect(flowEditorPage.trigger).not.toBeVisible(); - }); + await test.step('continue to next step', async () => { + await flowEditorPage.continueButton.click(); }); - await test.step('test trigger', async () => { - await test.step('show sample output', async () => { - await expect(flowEditorPage.testOutput).not.toBeVisible(); - await flowEditorPage.continueButton.click(); - await expect(flowEditorPage.testOutput).toBeVisible(); - await flowEditorPage.screenshot({ - path: 'Scheduler trigger test output.png', - }); - await flowEditorPage.continueButton.click(); - }); + await test.step('collapses the substep', async () => { + await expect(flowEditorPage.trigger).not.toBeVisible(); }); }); - await test.step('arrange Ntfy action', async () => { - await test.step('choose app and event substep', async () => { - await test.step('choose application', async () => { - await flowEditorPage.appAutocomplete.click(); - await page.getByRole('option', { name: 'Ntfy' }).click(); - }); - - await test.step('choose an event', async () => { - await expect(flowEditorPage.eventAutocomplete).toBeVisible(); - await flowEditorPage.eventAutocomplete.click(); - await page - .getByRole('option', { name: 'Send message' }) - .click(); - }); - - await test.step('continue to next step', async () => { - await flowEditorPage.continueButton.click(); - }); - - await test.step('collapses the substep', async () => { - await expect(flowEditorPage.appAutocomplete).not.toBeVisible(); - await expect(flowEditorPage.eventAutocomplete).not.toBeVisible(); - }); - }); - - await test.step('choose connection substep', async () => { - await test.step('choose connection list item', async () => { - await flowEditorPage.connectionAutocomplete.click(); - await page.getByRole('option').first().click(); - }); - - await test.step('continue to next step', async () => { - await flowEditorPage.continueButton.click(); - }); - - await test.step('collapses the substep', async () => { - await expect(flowEditorPage.connectionAutocomplete).not.toBeVisible(); - }); - }); - - await test.step('set up action substep', async () => { - await test.step('fill topic and message body', async () => { - await page - .getByTestId('parameters.topic-power-input') - .locator('[contenteditable]') - .fill('Topic'); - await page - .getByTestId('parameters.message-power-input') - .locator('[contenteditable]') - .fill('Message body'); - }); - - await test.step('continue to next step', async () => { - await flowEditorPage.continueButton.click(); - }); - - await test.step('collapses the substep', async () => { - await expect(flowEditorPage.connectionAutocomplete).not.toBeVisible(); - }); - }); - - await test.step('test trigger substep', async () => { - await test.step('show sample output', async () => { - await expect(flowEditorPage.testOutput).not.toBeVisible(); - await page - .getByTestId('flow-substep-continue-button') - .first() - .click(); - await expect(flowEditorPage.testOutput).toBeVisible(); - await flowEditorPage.screenshot({ - path: 'Ntfy action test output.png', - }); - await flowEditorPage.continueButton.click(); - }); - }); - }); - - await test.step('publish and unpublish', async () => { - await test.step('publish flow', async () => { - await expect(flowEditorPage.unpublishFlowButton).not.toBeVisible(); - await expect(flowEditorPage.publishFlowButton).toBeVisible(); - await flowEditorPage.publishFlowButton.click(); - await expect(flowEditorPage.publishFlowButton).not.toBeVisible(); - }); - - await test.step('shows read-only sticky snackbar', async () => { - await expect(flowEditorPage.infoSnackbar).toBeVisible(); + await test.step('test trigger', async () => { + await test.step('show sample output', async () => { + await expect(flowEditorPage.testOutput).not.toBeVisible(); + await flowEditorPage.continueButton.click(); + await expect(flowEditorPage.testOutput).toBeVisible(); await flowEditorPage.screenshot({ - path: 'Published flow.png', + path: 'Scheduler trigger test output.png', }); + await flowEditorPage.continueButton.click(); }); - - await test.step('unpublish from snackbar', async () => { + }); + }); + + await test.step('arrange Ntfy action', async () => { + await test.step('choose app and event substep', async () => { + await test.step('choose application', async () => { + await flowEditorPage.appAutocomplete.click(); + await page.getByRole('option', { name: 'Ntfy' }).click(); + }); + + await test.step('choose an event', async () => { + await expect(flowEditorPage.eventAutocomplete).toBeVisible(); + await flowEditorPage.eventAutocomplete.click(); + await page.getByRole('option', { name: 'Send message' }).click(); + }); + + await test.step('continue to next step', async () => { + await flowEditorPage.continueButton.click(); + }); + + await test.step('collapses the substep', async () => { + await expect(flowEditorPage.appAutocomplete).not.toBeVisible(); + await expect(flowEditorPage.eventAutocomplete).not.toBeVisible(); + }); + }); + + await test.step('choose connection substep', async () => { + await test.step('choose connection list item', async () => { + await flowEditorPage.connectionAutocomplete.click(); await page - .getByTestId('unpublish-flow-from-snackbar') + .getByRole('option') + .filter({ hasText: 'Add new connection' }) .click(); - await expect(flowEditorPage.infoSnackbar).not.toBeVisible(); }); - - await test.step('publish once again', async () => { - await expect(flowEditorPage.publishFlowButton).toBeVisible(); - await flowEditorPage.publishFlowButton.click(); - await expect(flowEditorPage.publishFlowButton).not.toBeVisible(); + + await test.step('continue to next step', async () => { + await page.getByTestId('create-connection-button').click(); }); - - await test.step('unpublish from layout top bar', async () => { - await expect(flowEditorPage.unpublishFlowButton).toBeVisible(); - await flowEditorPage.unpublishFlowButton.click(); - await expect(flowEditorPage.unpublishFlowButton).not.toBeVisible(); + + await test.step('collapses the substep', async () => { + await flowEditorPage.continueButton.click(); + await expect(flowEditorPage.connectionAutocomplete).not.toBeVisible(); + }); + }); + + await test.step('set up action substep', async () => { + await test.step('fill topic and message body', async () => { + await page + .getByTestId('parameters.topic-power-input') + .locator('[contenteditable]') + .fill('Topic'); + await page + .getByTestId('parameters.message-power-input') + .locator('[contenteditable]') + .fill('Message body'); + }); + + await test.step('continue to next step', async () => { + await flowEditorPage.continueButton.click(); + }); + + await test.step('collapses the substep', async () => { + await expect(flowEditorPage.connectionAutocomplete).not.toBeVisible(); + }); + }); + + await test.step('test trigger substep', async () => { + await test.step('show sample output', async () => { + await expect(flowEditorPage.testOutput).not.toBeVisible(); + await page.getByTestId('flow-substep-continue-button').first().click(); + await expect(flowEditorPage.testOutput).toBeVisible(); await flowEditorPage.screenshot({ - path: 'Unpublished flow.png', + path: 'Ntfy action test output.png', }); + await flowEditorPage.continueButton.click(); }); }); - - await test.step('in layout', async () => { - await test.step('can go back to flows page', async () => { - await page.getByTestId('editor-go-back-button').click(); - await expect(page).toHaveURL('/flows'); + }); + + await test.step('publish and unpublish', async () => { + await test.step('publish flow', async () => { + await expect(flowEditorPage.unpublishFlowButton).not.toBeVisible(); + await expect(flowEditorPage.publishFlowButton).toBeVisible(); + await flowEditorPage.publishFlowButton.click(); + await expect(flowEditorPage.publishFlowButton).not.toBeVisible(); + }); + + await test.step('shows read-only sticky snackbar', async () => { + await expect(flowEditorPage.infoSnackbar).toBeVisible(); + await flowEditorPage.screenshot({ + path: 'Published flow.png', }); }); - } -); \ No newline at end of file + + await test.step('unpublish from snackbar', async () => { + await page.getByTestId('unpublish-flow-from-snackbar').click(); + await expect(flowEditorPage.infoSnackbar).not.toBeVisible(); + }); + + await test.step('publish once again', async () => { + await expect(flowEditorPage.publishFlowButton).toBeVisible(); + await flowEditorPage.publishFlowButton.click(); + await expect(flowEditorPage.publishFlowButton).not.toBeVisible(); + }); + + await test.step('unpublish from layout top bar', async () => { + await expect(flowEditorPage.unpublishFlowButton).toBeVisible(); + await flowEditorPage.unpublishFlowButton.click(); + await expect(flowEditorPage.unpublishFlowButton).not.toBeVisible(); + await flowEditorPage.screenshot({ + path: 'Unpublished flow.png', + }); + }); + }); + + await test.step('in layout', async () => { + await test.step('can go back to flows page', async () => { + await page.getByTestId('editor-go-back-button').click(); + await expect(page).toHaveURL('/flows'); + }); + }); +}); diff --git a/packages/e2e-tests/tests/my-profile/profile-updates.spec.js b/packages/e2e-tests/tests/my-profile/profile-updates.spec.js index d77962e4..fc0ce7d0 100644 --- a/packages/e2e-tests/tests/my-profile/profile-updates.spec.js +++ b/packages/e2e-tests/tests/my-profile/profile-updates.spec.js @@ -33,10 +33,7 @@ publicTest.describe('My Profile', () => { .getByRole('option', { name: 'Admin' }) .click(); await adminCreateUserPage.createButton.click(); - const snackbar = await adminUsersPage.getSnackbarData( - 'snackbar-create-user-success' - ); - await expect(snackbar.variant).toBe('success'); + await adminCreateUserPage.expectCreateUserSuccessAlertToBeVisible(); }); await publicTest.step('copy invitation link', async () => {