From d55be52515b38b028b37601b2e1785b7f939fb1e Mon Sep 17 00:00:00 2001 From: goemen Date: Wed, 9 Oct 2024 15:00:31 -0700 Subject: [PATCH] add dashboard and user management e2e tests --- admin-frontend/e2e/announcements.spec.ts | 2 +- admin-frontend/e2e/dashboard.spec.ts | 5 + admin-frontend/e2e/pages/admin-portal-page.ts | 21 +++-- admin-frontend/e2e/pages/dashboard.ts | 43 ++++++++- .../user-management/user-management-page.ts | 94 +++++++++++++++++++ admin-frontend/e2e/user-management.spec.ts | 23 +++++ 6 files changed, 179 insertions(+), 9 deletions(-) create mode 100644 admin-frontend/e2e/pages/user-management/user-management-page.ts create mode 100644 admin-frontend/e2e/user-management.spec.ts diff --git a/admin-frontend/e2e/announcements.spec.ts b/admin-frontend/e2e/announcements.spec.ts index 8cd242294..f4a1d32f8 100644 --- a/admin-frontend/e2e/announcements.spec.ts +++ b/admin-frontend/e2e/announcements.spec.ts @@ -4,7 +4,7 @@ import { AddAnnouncementPage } from './pages/announcements/add-announcement-page import { EditAnnouncementPage } from './pages/announcements/edit-announcement-page'; import { AnnouncementStatus } from './types'; -test.describe('Announcements', () => { +test.describe.skip('Announcements', () => { test.describe('add announcement', () => { test('save as draft', async ({ page }) => { const announcementsPage = await AnnouncementsPage.visit(page); diff --git a/admin-frontend/e2e/dashboard.spec.ts b/admin-frontend/e2e/dashboard.spec.ts index 6f1dcc548..919c60f7b 100644 --- a/admin-frontend/e2e/dashboard.spec.ts +++ b/admin-frontend/e2e/dashboard.spec.ts @@ -11,4 +11,9 @@ test.describe.serial('dashboard', () => { await dashboard.verifySideBarLinks(); await dashboard.verifySideBarExpandCollapse(); }); + + test('Go to edit announcements', async ({ page }) => { + const dashboard = await DashboardPage.visit(page); + await dashboard.clickGotoAnnouncementsAndVerify(); + }); }); diff --git a/admin-frontend/e2e/pages/admin-portal-page.ts b/admin-frontend/e2e/pages/admin-portal-page.ts index fa0c69633..eeb34fbae 100644 --- a/admin-frontend/e2e/pages/admin-portal-page.ts +++ b/admin-frontend/e2e/pages/admin-portal-page.ts @@ -1,13 +1,23 @@ -import { Page, expect } from '@playwright/test'; +import { Locator, Page, expect } from '@playwright/test'; import { User } from '../auth.setup'; import { PagePaths } from '../utils'; import { DateTimeFormatter, ZonedDateTime, ZoneId } from '@js-joda/core'; import { Locale } from '@js-joda/locale_en'; export class AdminPortalPage { + userManagementNav: Locator; constructor(public readonly page: Page) {} - async setup() {} + async setup() { + this.userManagementNav = this.page.getByRole('link', { + name: 'User Management', + }); + } + + async navigateToUserManagement() { + await this.userManagementNav.click(); + await this.page.waitForURL(PagePaths.USER_MANAGEMENT); + } async verifyUserIsDisplayed(user: User) { await expect(this.page.getByTestId('account-info')).toContainText( @@ -29,10 +39,9 @@ export class AdminPortalPage { await expect( this.page.getByRole('link', { name: 'Announcements' }), ).toBeVisible(); - // TODO: bring it back after the - // await expect( - // this.page.getByRole('link', { name: 'User Management' }), - // ).toBeVisible(); + await expect( + this.page.getByRole('link', { name: 'User Management' }), + ).toBeVisible(); await expect( this.page.getByRole('link', { name: 'Analytics' }), ).toBeVisible(); diff --git a/admin-frontend/e2e/pages/dashboard.ts b/admin-frontend/e2e/pages/dashboard.ts index b508b895b..47e5507ce 100644 --- a/admin-frontend/e2e/pages/dashboard.ts +++ b/admin-frontend/e2e/pages/dashboard.ts @@ -1,13 +1,52 @@ -import { Page } from '@playwright/test'; +import { expect, Locator, Page } from '@playwright/test'; import { PagePaths } from '../utils'; import { AdminPortalPage } from './admin-portal-page'; export class DashboardPage extends AdminPortalPage { static path = PagePaths.DASHBOARD; - public generateReportButton; + public gotoAnnouncements: Locator; async setup() { await super.setup(); + this.gotoAnnouncements = await this.page.getByRole('link', { + name: 'Go to edit', + }); + + const recentlyViewed = await this.page.getByRole('heading', { + name: 'Recently Viewed Reports', + }); + const recentlySubmitted = await this.page.getByRole('heading', { + name: 'Recently Submitted Reports', + }); + + const analyticsView = await this.page.getByRole('heading', { + name: 'Analytics Overview', + }); + + const currentYearReports = await this.page.getByText( + `Number of reports submitted for the current reporting year (${new Date().getFullYear()})`, + ); + + const loggedInUsers = await this.page.getByText( + 'Total number of employers who have logged on to date', + ); + + const announcements = await this.page.getByRole('heading', { + name: 'Public Announcements', + }); + + await expect(analyticsView).toBeVisible(); + await expect(recentlySubmitted).toBeVisible(); + await expect(loggedInUsers).toBeVisible(); + await expect(currentYearReports).toBeVisible(); + await expect(recentlyViewed).toBeVisible(); + await expect(announcements).toBeVisible(); + await expect(this.gotoAnnouncements).toBeVisible(); + } + + async clickGotoAnnouncementsAndVerify() { + await this.gotoAnnouncements.click(); + await this.page.waitForURL(PagePaths.ANNOUNCEMENTS); } static async visit(page: Page): Promise { diff --git a/admin-frontend/e2e/pages/user-management/user-management-page.ts b/admin-frontend/e2e/pages/user-management/user-management-page.ts new file mode 100644 index 000000000..957095425 --- /dev/null +++ b/admin-frontend/e2e/pages/user-management/user-management-page.ts @@ -0,0 +1,94 @@ +import { expect, Locator } from 'playwright/test'; +import { AdminPortalPage } from '../admin-portal-page'; + +export class UserManagementPage extends AdminPortalPage { + pendingAccessButton: Locator; + addUserButton: Locator; + + async setup() { + await super.setup(); + this.pendingAccessButton = this.page.getByRole('button', { + name: 'Pending Access', + }); + this.addUserButton = this.page.getByRole('button', { + name: 'Add New User', + }); + + await expect(this.pendingAccessButton).toBeVisible(); + await expect(this.addUserButton).toBeVisible(); + } + + async verifyOpenAndClosePendingAccess() { + const waitForAccessResponse = this.waitForUserInvitesToLoad(); + await this.pendingAccessButton.click(); + const modalTitle = await this.page.getByText('Pending User Access'); + await expect(modalTitle).toBeVisible(); + const response = await waitForAccessResponse; + const data = await response.json(); + if (data.length === 0) { + const noPendingAccess = await this.page.getByText( + 'No pending invitations', + ); + await expect(noPendingAccess).toBeVisible(); + } else { + for (const { admin_user_onboarding_id, first_name, email } of data) { + const inviteName = await this.page.getByTestId( + `name-${admin_user_onboarding_id}`, + ); + await expect(inviteName).toBeVisible(); + await expect(inviteName).toContainText(first_name); + const inviteEmail = await this.page.getByTestId( + `email-${admin_user_onboarding_id}`, + ); + await expect(inviteEmail).toBeVisible(); + await expect(inviteEmail).toContainText(email); + } + } + + const closeButton = await this.page.getByRole('button', { name: 'Close' }); + await closeButton.click(); + await expect(modalTitle).not.toBeVisible(); + } + + async addNewUserAndVerify(user: { name: string; email: string }) { + await this.addUserButton.click(); + const nameInput = await this.page.getByLabel('Name'); + await expect(nameInput).toBeVisible(); + const emailInput = await this.page.getByLabel('Email'); + await expect(emailInput).toBeVisible(); + const submitButton = await this.page.getByRole('button', { name: 'Add', exact: true }); + + // Fill out form + await nameInput.fill(user.name); + await emailInput.fill(user.email); + const addUserResponse = this.waitForUserToBeAdded(); + await submitButton.click(); + const continueButton = await this.page.getByRole('button', { + name: 'Continue', + }); + await continueButton.click(); + const response = await addUserResponse; + await response.json(); + const snackbar = await this.page.getByText( + 'User successfully onboarded. An email has been sent for them to activate their account for the application. Once they activate their account the user will be displayed for user management', + ); + await expect(snackbar).toBeVisible(); + } + + waitForUserToBeAdded() { + return this.page.waitForResponse( + (response) => + response.url().includes('/v1/user-invites') && + response.status() === 200 && response.request().method() === 'POST', + ); + } + + async waitForUserInvitesToLoad() { + return this.page.waitForResponse( + (response) => + response.url().includes('/v1/user-invites') && + response.status() === 200 && + response.request().method() === 'GET', + ); + } +} diff --git a/admin-frontend/e2e/user-management.spec.ts b/admin-frontend/e2e/user-management.spec.ts new file mode 100644 index 000000000..2936ba268 --- /dev/null +++ b/admin-frontend/e2e/user-management.spec.ts @@ -0,0 +1,23 @@ +import { test } from '@playwright/test'; +import { UserManagementPage } from './pages/user-management/user-management-page'; +import { faker } from '@faker-js/faker'; +import { PagePaths } from './utils'; + +const user = { + name: faker.person.fullName(), + email: faker.internet.userName(), +}; +test.describe.serial('User Management', () => { + let userManagementPage: UserManagementPage; + test.beforeEach(async ({ page }) => { + await page.goto(PagePaths.USER_MANAGEMENT); + userManagementPage = new UserManagementPage(page); + await userManagementPage.setup(); + }); + test('add new user', async () => { + await userManagementPage.addNewUserAndVerify(user); + }); + test('verify open and close pending access', async () => { + await userManagementPage.verifyOpenAndClosePendingAccess(); + }); +});