diff --git a/packages/e2e-tests/fixtures/base-page.js b/packages/e2e-tests/fixtures/base-page.js index 6d7dbcff..35442781 100644 --- a/packages/e2e-tests/fixtures/base-page.js +++ b/packages/e2e-tests/fixtures/base-page.js @@ -14,11 +14,12 @@ export class BasePage { */ constructor(page) { this.page = page; - this.snackbar = this.page.locator('.notistack-MuiContent'); + this.snackbar = page.locator('*[data-test^="snackbar"]'); } /** * Finds the latest snackbar message and extracts relevant data + * @param {string | undefined} testId * @returns {( * null | { * variant: SnackbarVariant, @@ -27,25 +28,13 @@ export class BasePage { * } * )} */ - async getSnackbarData () { - if (await this.snackbar.count() === 0) { - return null; - } - const snack = this.snackbar.first(); // uses flex: column-reverse - const classList = await snack.evaluate(node => Array.from(node.classList)); - /** @type SnackbarVariant */ - let variant = 'default'; - if (classList.includes('notistack-MuiContent-success')) { - variant = 'success' - } else if (classList.includes('notistack-MuiContent-warning')) { - variant = 'warning' - } else if (classList.includes('notistack-MuiContent-error')) { - variant = 'error' - } else if (classList.includes('notistack-MuiContent-info')) { - variant = 'info' + async getSnackbarData (testId) { + if (!testId) { + testId = 'snackbar'; } + const snack = this.page.getByTestId(testId); return { - variant, + variant: await snack.getAttribute('data-snackbar-variant'), text: await snack.evaluate(node => node.innerText), dataset: await snack.evaluate(node => { function getChildren (n) { diff --git a/packages/e2e-tests/tests/admin/manage-users.spec.js b/packages/e2e-tests/tests/admin/manage-users.spec.js index 9d6aef40..97870c75 100644 --- a/packages/e2e-tests/tests/admin/manage-users.spec.js +++ b/packages/e2e-tests/tests/admin/manage-users.spec.js @@ -35,10 +35,9 @@ test.describe('User management page', () => { 'option', { name: 'Admin' } ).click(); await adminCreateUserPage.createButton.click(); - await adminUsersPage.snackbar.waitFor({ - state: 'attached' - }); - const snackbar = await adminUsersPage.getSnackbarData(); + const snackbar = await adminUsersPage.getSnackbarData( + 'snackbar-create-user-success' + ); await expect(snackbar.variant).toBe('success'); await adminUsersPage.closeSnackbar(); } @@ -65,10 +64,9 @@ test.describe('User management page', () => { await adminEditUserPage.fullNameInput.fill(newUserInfo.fullName); await adminEditUserPage.updateButton.click(); - await adminUsersPage.snackbar.waitFor({ - state: 'attached' - }); - const snackbar = await adminUsersPage.getSnackbarData(); + const snackbar = await adminUsersPage.getSnackbarData( + 'snackbar-edit-user-success' + ); await expect(snackbar.variant).toBe('success'); await adminUsersPage.closeSnackbar(); @@ -86,10 +84,10 @@ test.describe('User management page', () => { await adminUsersPage.clickDeleteUser(userRow); const modal = adminUsersPage.deleteUserModal; await modal.deleteButton.click(); - await adminUsersPage.snackbar.waitFor({ - state: 'attached' - }); - const snackbar = await adminUsersPage.getSnackbarData(); + + const snackbar = await adminUsersPage.getSnackbarData( + 'snackbar-delete-user-success' + ); await expect(snackbar.variant).toBe('success'); await adminUsersPage.closeSnackbar(); await expect(userRow).not.toBeVisible(false); @@ -115,10 +113,9 @@ test.describe('User management page', () => { 'option', { name: 'Admin' } ).click(); await adminCreateUserPage.createButton.click(); - await adminUsersPage.snackbar.waitFor({ - state: 'attached' - }); - const snackbar = await adminUsersPage.getSnackbarData(); + const snackbar = await adminUsersPage.getSnackbarData( + 'snackbar-create-user-success' + ); await expect(snackbar.variant).toBe('success'); await adminUsersPage.closeSnackbar(); } @@ -132,10 +129,9 @@ test.describe('User management page', () => { await adminUsersPage.clickDeleteUser(userRow); const modal = adminUsersPage.deleteUserModal; await modal.deleteButton.click(); - await adminUsersPage.snackbar.waitFor({ - state: 'attached' - }); - const snackbar = await adminUsersPage.getSnackbarData(); + const snackbar = await adminUsersPage.getSnackbarData( + 'snackbar-delete-user-success' + ); await expect(snackbar).not.toBeNull(); await expect(snackbar.variant).toBe('success'); await adminUsersPage.closeSnackbar(); @@ -163,6 +159,7 @@ test.describe('User management page', () => { happen here, i.e. if this should create a new user, stay the same, un-delete the user, or something else */ + // await adminUsersPage.getSnackbarData('snackbar-error'); await adminUsersPage.closeSnackbar(); } ); @@ -187,10 +184,9 @@ test.describe('User management page', () => { 'option', { name: 'Admin' } ).click(); await adminCreateUserPage.createButton.click(); - await adminUsersPage.snackbar.waitFor({ - state: 'attached' - }); - const snackbar = await adminUsersPage.getSnackbarData(); + const snackbar = await adminUsersPage.getSnackbarData( + 'snackbar-create-user-success' + ); await expect(snackbar.variant).toBe('success'); await adminUsersPage.closeSnackbar(); } @@ -209,11 +205,9 @@ test.describe('User management page', () => { 'option', { name: 'Admin' } ).click(); await adminCreateUserPage.createButton.click(); - await adminCreateUserPage.snackbar.waitFor({ - state: 'attached' - }); + await expect(page.url()).toBe(createUserPageUrl); - const snackbar = await adminUsersPage.getSnackbarData(); + const snackbar = await adminUsersPage.getSnackbarData('snackbar-error'); await expect(snackbar.variant).toBe('error'); await adminUsersPage.closeSnackbar(); } @@ -241,10 +235,9 @@ test.describe('User management page', () => { 'option', { name: 'Admin' } ).click(); await adminCreateUserPage.createButton.click(); - await adminUsersPage.snackbar.waitFor({ - state: 'attached' - }); - const snackbar = await adminUsersPage.getSnackbarData(); + const snackbar = await adminUsersPage.getSnackbarData( + 'snackbar-create-user-success' + ); await expect(snackbar.variant).toBe('success'); await adminUsersPage.closeSnackbar(); } @@ -262,10 +255,9 @@ test.describe('User management page', () => { 'option', { name: 'Admin' } ).click(); await adminCreateUserPage.createButton.click(); - await adminUsersPage.snackbar.waitFor({ - state: 'attached' - }); - const snackbar = await adminUsersPage.getSnackbarData(); + const snackbar = await adminUsersPage.getSnackbarData( + 'snackbar-create-user-success' + ); await expect(snackbar.variant).toBe('success'); await adminUsersPage.closeSnackbar(); } @@ -282,10 +274,9 @@ test.describe('User management page', () => { const editPageUrl = page.url(); await adminEditUserPage.updateButton.click(); - await adminUsersPage.snackbar.waitFor({ - state: 'attached' - }); - const snackbar = await adminUsersPage.getSnackbarData(); + 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/web/src/components/AdminApplicationSettings/index.tsx b/packages/web/src/components/AdminApplicationSettings/index.tsx index 515eac15..1a323282 100644 --- a/packages/web/src/components/AdminApplicationSettings/index.tsx +++ b/packages/web/src/components/AdminApplicationSettings/index.tsx @@ -6,13 +6,13 @@ import Paper from '@mui/material/Paper'; import Stack from '@mui/material/Stack'; import LoadingButton from '@mui/lab/LoadingButton'; import { useMutation } from '@apollo/client'; -import { useSnackbar } from 'notistack'; import { CREATE_APP_CONFIG } from 'graphql/mutations/create-app-config'; import { UPDATE_APP_CONFIG } from 'graphql/mutations/update-app-config'; import Form from 'components/Form'; import { Switch } from './style'; +import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar'; type AdminApplicationSettingsProps = { appKey: string; @@ -36,7 +36,7 @@ function AdminApplicationSettings( ); const formatMessage = useFormatMessage(); - const { enqueueSnackbar } = useSnackbar(); + const enqueueSnackbar = useEnqueueSnackbar(); const handleSubmit = async (values: any) => { try { @@ -55,6 +55,9 @@ function AdminApplicationSettings( } enqueueSnackbar(formatMessage('adminAppsSettings.successfullySaved'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-save-admin-apps-settings-success' + } }); } catch (error) { throw new Error('Failed while saving!'); diff --git a/packages/web/src/components/ApolloProvider/index.tsx b/packages/web/src/components/ApolloProvider/index.tsx index 3b2b47e3..ff276bd0 100644 --- a/packages/web/src/components/ApolloProvider/index.tsx +++ b/packages/web/src/components/ApolloProvider/index.tsx @@ -15,7 +15,12 @@ const ApolloProvider = (props: ApolloProviderProps): React.ReactElement => { const onError = React.useCallback( (message) => { - enqueueSnackbar(message, { variant: 'error' }); + enqueueSnackbar(message, { + variant: 'error', + SnackbarProps: { + 'data-test': 'snackbar-error' + } + }); }, [enqueueSnackbar] ); diff --git a/packages/web/src/components/AppConnectionRow/index.tsx b/packages/web/src/components/AppConnectionRow/index.tsx index ef6f1a6c..1fd578ab 100644 --- a/packages/web/src/components/AppConnectionRow/index.tsx +++ b/packages/web/src/components/AppConnectionRow/index.tsx @@ -82,6 +82,9 @@ function AppConnectionRow(props: AppConnectionRowProps): React.ReactElement { enqueueSnackbar(formatMessage('connection.deletedMessage'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-delete-connection-success' + } }); } else if (action.type === 'test') { setVerificationVisible(true); diff --git a/packages/web/src/components/DeleteRoleButton/index.ee.tsx b/packages/web/src/components/DeleteRoleButton/index.ee.tsx index 90f7d298..2a07fac6 100644 --- a/packages/web/src/components/DeleteRoleButton/index.ee.tsx +++ b/packages/web/src/components/DeleteRoleButton/index.ee.tsx @@ -31,6 +31,9 @@ export default function DeleteRoleButton(props: DeleteRoleButtonProps) { setShowConfirmation(false); enqueueSnackbar(formatMessage('deleteRoleButton.successfullyDeleted'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-delete-role-success' + } }); } catch (error) { throw new Error('Failed while deleting!'); diff --git a/packages/web/src/components/DeleteUserButton/index.ee.tsx b/packages/web/src/components/DeleteUserButton/index.ee.tsx index a3147e0e..353af591 100644 --- a/packages/web/src/components/DeleteUserButton/index.ee.tsx +++ b/packages/web/src/components/DeleteUserButton/index.ee.tsx @@ -29,6 +29,9 @@ export default function DeleteUserButton(props: DeleteUserButtonProps) { setShowConfirmation(false); enqueueSnackbar(formatMessage('deleteUserButton.successfullyDeleted'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-delete-user-success' + } }); } catch (error) { throw new Error('Failed while deleting!'); diff --git a/packages/web/src/components/FlowContextMenu/index.tsx b/packages/web/src/components/FlowContextMenu/index.tsx index 25469778..d0e9463e 100644 --- a/packages/web/src/components/FlowContextMenu/index.tsx +++ b/packages/web/src/components/FlowContextMenu/index.tsx @@ -36,6 +36,9 @@ export default function ContextMenu( enqueueSnackbar(formatMessage('flow.successfullyDuplicated'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-duplicate-flow-success' + } }); onClose(); diff --git a/packages/web/src/components/ResetPasswordForm/index.ee.tsx b/packages/web/src/components/ResetPasswordForm/index.ee.tsx index 2052792f..c2954ba1 100644 --- a/packages/web/src/components/ResetPasswordForm/index.ee.tsx +++ b/packages/web/src/components/ResetPasswordForm/index.ee.tsx @@ -43,6 +43,9 @@ export default function ResetPasswordForm() { enqueueSnackbar(formatMessage('resetPasswordForm.passwordUpdated'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-reset-password-success' + } }); navigate(URLS.LOGIN); diff --git a/packages/web/src/hooks/useEnqueueSnackbar.ts b/packages/web/src/hooks/useEnqueueSnackbar.ts index 078166a1..356ec8e0 100644 --- a/packages/web/src/hooks/useEnqueueSnackbar.ts +++ b/packages/web/src/hooks/useEnqueueSnackbar.ts @@ -20,7 +20,11 @@ export default function useEnqueueSnackbar() { ...(options || {}) as Record, SnackbarProps: { onClick: () => closeSnackbar(key), - ...(options.SnackbarProps || {}) as Record + ...({ + 'data-test': 'snackbar', // keep above options.snackbarProps + 'data-snackbar-variant': `${options.variant}` || 'default', + }) as Record, + ...(options.SnackbarProps || {}) as Record, } } ); diff --git a/packages/web/src/pages/Authentication/RoleMappings.tsx b/packages/web/src/pages/Authentication/RoleMappings.tsx index 50346b4f..f93bccfd 100644 --- a/packages/web/src/pages/Authentication/RoleMappings.tsx +++ b/packages/web/src/pages/Authentication/RoleMappings.tsx @@ -64,6 +64,9 @@ function RoleMappings({ provider, providerLoading }: RoleMappingsProps) { }); enqueueSnackbar(formatMessage('roleMappingsForm.successfullySaved'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-update-role-mappings-success' + } }); } } catch (error) { diff --git a/packages/web/src/pages/Authentication/SamlConfiguration.tsx b/packages/web/src/pages/Authentication/SamlConfiguration.tsx index e1f72d34..3909170a 100644 --- a/packages/web/src/pages/Authentication/SamlConfiguration.tsx +++ b/packages/web/src/pages/Authentication/SamlConfiguration.tsx @@ -93,6 +93,9 @@ function SamlConfiguration({ enqueueSnackbar(formatMessage('authenticationForm.successfullySaved'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-save-saml-provider-success' + } }); } catch (error) { throw new Error('Failed while saving!'); diff --git a/packages/web/src/pages/CreateRole/index.ee.tsx b/packages/web/src/pages/CreateRole/index.ee.tsx index 468f904f..4ba49e6e 100644 --- a/packages/web/src/pages/CreateRole/index.ee.tsx +++ b/packages/web/src/pages/CreateRole/index.ee.tsx @@ -43,6 +43,9 @@ export default function CreateRole(): React.ReactElement { enqueueSnackbar(formatMessage('createRole.successfullyCreated'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-create-role-success' + } }); navigate(URLS.ROLES); diff --git a/packages/web/src/pages/CreateUser/index.tsx b/packages/web/src/pages/CreateUser/index.tsx index ff6e69bb..7d0f002d 100644 --- a/packages/web/src/pages/CreateUser/index.tsx +++ b/packages/web/src/pages/CreateUser/index.tsx @@ -47,6 +47,10 @@ export default function CreateUser(): React.ReactElement { enqueueSnackbar(formatMessage('createUser.successfullyCreated'), { variant: 'success', + persist: true, + SnackbarProps: { + 'data-test': 'snackbar-create-user-success', + } }); navigate(URLS.USERS); diff --git a/packages/web/src/pages/EditRole/index.ee.tsx b/packages/web/src/pages/EditRole/index.ee.tsx index 93db3f8c..098d32cb 100644 --- a/packages/web/src/pages/EditRole/index.ee.tsx +++ b/packages/web/src/pages/EditRole/index.ee.tsx @@ -53,6 +53,9 @@ export default function EditRole(): React.ReactElement { enqueueSnackbar(formatMessage('editRole.successfullyUpdated'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-edit-role-success' + } }); navigate(URLS.ROLES); diff --git a/packages/web/src/pages/EditUser/index.tsx b/packages/web/src/pages/EditUser/index.tsx index 6a9c49f0..9d6c32bd 100644 --- a/packages/web/src/pages/EditUser/index.tsx +++ b/packages/web/src/pages/EditUser/index.tsx @@ -55,6 +55,10 @@ export default function EditUser(): React.ReactElement { enqueueSnackbar(formatMessage('editUser.successfullyUpdated'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-edit-user-success', + persist: true + } }); navigate(URLS.USERS); diff --git a/packages/web/src/pages/ProfileSettings/index.tsx b/packages/web/src/pages/ProfileSettings/index.tsx index bf41f04c..fc4abe7a 100644 --- a/packages/web/src/pages/ProfileSettings/index.tsx +++ b/packages/web/src/pages/ProfileSettings/index.tsx @@ -78,6 +78,9 @@ function ProfileSettings() { enqueueSnackbar(formatMessage('profileSettings.updatedProfile'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-update-profile-settings-success' + } }); }; diff --git a/packages/web/src/pages/UserInterface/index.tsx b/packages/web/src/pages/UserInterface/index.tsx index 88057cd9..565882cf 100644 --- a/packages/web/src/pages/UserInterface/index.tsx +++ b/packages/web/src/pages/UserInterface/index.tsx @@ -128,6 +128,9 @@ export default function UserInterface(): React.ReactElement { enqueueSnackbar(formatMessage('userInterfacePage.successfullyUpdated'), { variant: 'success', + SnackbarProps: { + 'data-test': 'snackbar-update-user-interface-success' + } }); } catch (error) { throw new Error('Failed while updating!');