Skip to content

CHI-3227 Case View UI tests #2931

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
51 changes: 51 additions & 0 deletions e2e-tests/case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,54 @@ export const caseHome = (page: Page) => {
saveCaseAndEnd,
};
};

// Add utility functions moved from caseList.ts
export async function viewClosePrintView(page: Page) {
const openPrintButton = page.locator('[data-testid="CasePrint-Button"]');
await openPrintButton.waitFor({ state: 'visible' });
await openPrintButton.click();
console.log('Opened Case Print');
const closePrintButton = page.locator('[data-testid="NavigableContainer-CloseCross"]');
await closePrintButton.waitFor({ state: 'visible' });
await closePrintButton.click();
console.log('Close Case Print');
}

export async function clickEditCase(page: Page) {
const editButton = page.locator('[data-testid="Case-EditButton"]');
await editButton.waitFor({ state: 'visible' });
await editButton.click();
}

export async function updateCaseSummary(page: Page) {
const summaryInput = page.locator('[data-testid="CaseSummary-Input"]');
await summaryInput.waitFor({ state: 'visible' });
await summaryInput.fill('Updated summary');
const saveButton = page.locator('[data-testid="CaseSummary-SaveButton"]');
await saveButton.waitFor({ state: 'visible' });
await saveButton.click();
}

export async function verifyCaseSummaryUpdated(page: Page) {
const summaryContent = page.locator('[data-testid="CaseSummary-Content"]');
await summaryContent.waitFor({ state: 'visible' });
expect(await summaryContent.textContent()).toContain('Updated summary');
}

export async function verifyCasePrintButtonIsVisible(page: Page) {
const printButton = page.locator('[data-testid="CasePrint-Button"]');
await printButton.waitFor({ state: 'visible' });
expect(await printButton.isVisible()).toBe(true);
}

export async function verifyCategoryTooltipIsVisible(page: Page) {
const tooltip = page.locator('[data-testid="Category-Tooltip"]');
await tooltip.waitFor({ state: 'visible' });
expect(await tooltip.isVisible()).toBe(true);
}

export async function closeModal(page: Page) {
const closeCaseButton = page.locator('[data-testid="NavigableContainer-CloseCross"]');
await closeCaseButton.waitFor({ state: 'visible' });
await closeCaseButton.click();
}
101 changes: 17 additions & 84 deletions e2e-tests/caseList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type CaseSectionForm<T = Record<string, string>> = {

export const caseList = (page: Page) => {
const caseListPage = page.locator('div.Twilio-ViewCollection');
console.log('Case List table is visible.');

const selectors = {
caseListRowIdButton: caseListPage.locator(
Expand Down Expand Up @@ -94,6 +95,21 @@ export const caseList = (page: Page) => {
console.log(`Filtered cases by: ${filter} filter with selection of: ${option}`);
}

async function verifyCaseIdsAreInListInOrder(expectedIds: string[]) {
const rows = await page.locator('tr[data-testid^="CaseList-TableRow"]').all();

const ids = await Promise.all(
rows.map(async (row) => {
const button = row.locator('[data-testid="CaseList-CaseID-Button"]');
const buttonText = (await button.textContent())?.trim() || '';
const caseId = buttonText.replace(/OpenCase/, '').trim(); //extract case id
return caseId;
}),
);

expect(ids).toEqual(expectedIds);
}

//Open Case
async function openFirstCaseButton() {
const openCaseButton = selectors.openFirstCaseButton;
Expand All @@ -105,94 +121,11 @@ export const caseList = (page: Page) => {
return caseHome(page);
}

//Check print view
// TODO: Move to case.ts
async function viewClosePrintView() {
const openPrintButton = selectors.casePrintButton;
await openPrintButton.waitFor({ state: 'visible' });
await openPrintButton.click();
console.log('Opened Case Print');

const closePrintButton = selectors.modalCloseButton;
await closePrintButton.waitFor({ state: 'visible' });
await closePrintButton.click();
console.log('Close Case Print');
}

//Edit Case
// TODO: Move to case.ts
async function editCase() {
const editCaseButton = selectors.caseEditButton;
await editCaseButton.waitFor({ state: 'visible' });
await expect(editCaseButton).toContainText('Edit');
await editCaseButton.click();
console.log('Edit Case');
}

const currentTime = new Date();

// Add/Update Summary
// TODO: Move to case.ts
async function updateCaseSummary() {
const summaryTextArea = selectors.caseSummaryTextArea;
await summaryTextArea.waitFor({ state: 'visible' });
await summaryTextArea.fill(`E2E Case Summary Test Edited on ${currentTime}`);

const updateCaseButton = selectors.updateCaseButton;
await updateCaseButton.waitFor({ state: 'visible' });
await expect(updateCaseButton).toContainText('Save');
const responsePromise = page.waitForResponse('**/cases/**');
await updateCaseButton.click();
await responsePromise;

console.log('Updated Case Summary');
}

// Verify case summary update
async function verifyCaseSummaryUpdated() {
const summaryText = selectors.caseSummaryText;
await summaryText.waitFor({ state: 'visible' });
await expect(summaryText).toContainText(`E2E Case Summary Test Edited on ${currentTime}`);
}

async function verifyCasePrintButtonIsVisible() {
const printButton = selectors.casePrintButton;
await printButton.waitFor({ state: 'visible' });
await expect(printButton).toBeVisible();
}

async function verifyCategoryTooltipIsVisible() {
const categoryTooltip = selectors.categoryTooltip;
await categoryTooltip.waitFor({ state: 'visible' });
await expect(categoryTooltip).toBeVisible();
}

async function verifyCaseIdsAreInListInOrder(ids: string[]) {
await selectors.caseListRowIdButton.first().waitFor({ state: 'visible' });
const caseListIdButtons = await selectors.caseListRowIdButton.all();
expect(caseListIdButtons.length).toBe(ids.length);
await Promise.all(caseListIdButtons.map((l, idx) => expect(l).toContainText(ids[idx])));
}

//Close Modal (probably can move this to more generic navigation file now we have more standardised navigation)
async function closeModal() {
const closeCaseButton = selectors.modalCloseButton;
await closeCaseButton.waitFor({ state: 'visible' });
await closeCaseButton.click();
}

return {
openFilter,
closeFilter,
filterCases,
openFirstCaseButton,
viewClosePrintView,
editCase,
updateCaseSummary,
verifyCaseSummaryUpdated,
verifyCasePrintButtonIsVisible,
verifyCategoryTooltipIsVisible,
closeModal,
verifyCaseIdsAreInListInOrder,
openFirstCaseButton,
};
};
26 changes: 18 additions & 8 deletions e2e-tests/tests/caselist.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@

import { Page, request, test } from '@playwright/test';
import { caseList } from '../caseList';
import {
viewClosePrintView,
clickEditCase,
verifyCaseSummaryUpdated,
verifyCasePrintButtonIsVisible,
verifyCategoryTooltipIsVisible,
closeModal,
updateCaseSummary,
} from '../case';
import { skipTestIfNotTargeted, skipTestIfDataUpdateDisabled } from '../skipTest';
import { notificationBar } from '../notificationBar';
import { setupContextAndPage, closePage } from '../browser';
Expand Down Expand Up @@ -51,13 +60,14 @@ test.describe.serial('Open and Edit a Case in Case List page', () => {
let page = caseList(pluginPage);

await page.filterCases('status', 'Open');
// await page.filterCases('Counselor', 'Aselo Alerts');
await page.filterCases('counselor', 'Aselo Alerts');

const caseHomePage = await page.openFirstCaseButton();

// Open notifications cover up the print icon :facepalm
await notificationBar(pluginPage).dismissAllNotifications();

await page.viewClosePrintView();
await viewClosePrintView(pluginPage);

await caseHomePage.addCaseSection({
sectionTypeId: 'note',
Expand All @@ -79,16 +89,16 @@ test.describe.serial('Open and Edit a Case in Case List page', () => {
},
});

await page.editCase();
await clickEditCase(pluginPage);

await page.updateCaseSummary();
await updateCaseSummary(pluginPage);

await page.verifyCaseSummaryUpdated();
await verifyCaseSummaryUpdated(pluginPage);

await page.verifyCasePrintButtonIsVisible();
await page.verifyCategoryTooltipIsVisible();
await verifyCasePrintButtonIsVisible(pluginPage);
await verifyCategoryTooltipIsVisible(pluginPage);

await page.closeModal();
await closeModal(pluginPage);
console.log('Closed Case');
});
});
68 changes: 41 additions & 27 deletions e2e-tests/ui-tests/tests/case-list.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,28 @@ test.describe.serial('Case List', () => {
let page: Page;
const cases = hrmCases();
const permissions = hrmPermissions();
// Define the filters array for easy access and modification
const filters: Filter[] = ['status', 'counselor', 'createdAtFilter', 'updatedAtFilter'];
let caseListPage: ReturnType<typeof caseList>;

const warnViolations = (results: AxeResults, componentDescription: string) => {
if (results.violations.length) {
console.warn(
`${results.violations.length} accessibility violations found in ${componentDescription}.`,
);
}
};

const scanFilterDialogue = async (filter: Filter) => {
console.debug(`Scanning the '${filter}' filter dialog...`);
await caseListPage.openFilter(filter);
const filterAccessibilityScanResults = await new AxeBuilder({ page })
.include(`div[data-testid='CaseList-Filters-Panel']`)
.analyze();
// expect(filterAccessibilityScanResults.violations).toEqual([]);
warnViolations(filterAccessibilityScanResults, `the '${filter}' filter dialog`);
await caseListPage.openFilter(filter);
};

test.beforeAll(async ({ browser }) => {
await mockServer.start();
Expand All @@ -43,8 +65,14 @@ test.describe.serial('Case List', () => {
await mockServer.stop();
});

test('Case list loads items', async () => {
test.beforeEach(async () => {
await page.goto('/case-list', { waitUntil: 'networkidle' });
await page.waitForSelector('div.Twilio-View-case-list', { state: 'visible', timeout: 10000 });
caseListPage = caseList(page);
});

test('Case list loads items', async () => {
await page.waitForTimeout(10000);
await caseList(page).verifyCaseIdsAreInListInOrder(
cases
.getMockCases()
Expand All @@ -58,27 +86,20 @@ test.describe.serial('Case List', () => {
.include('div.Twilio-View-case-list')
.analyze();
expect(accessibilityScanResults.violations).toEqual([]);
const caseListPage = caseList(page);

const warnViolations = (results: AxeResults, componentDescription: string) => {
if (results.violations.length) {
console.warn(
`${results.violations.length} accessibility violations found in ${componentDescription}.`,
);
}
};

const scanFilterDialogue = async (filter: Filter) => {
console.debug(`Scanning the '${filter}' filter dialog...`);
await caseListPage.openFilter(filter);
const filterAccessibilityScanResults = await new AxeBuilder({ page })
.include(`div[data-testid='CaseList-Filters-Panel']`)
.analyze();
// expect(filterAccessibilityScanResults.violations).toEqual([]);
warnViolations(filterAccessibilityScanResults, `the '${filter}' filter dialog`);
await caseListPage.openFilter(filter);
};
for (const filter of filters) {
await scanFilterDialogue(filter);
}
});

test('Case list accessibility: screen reader labels', async () => {
// Check that filter buttons have aria-label or accessible name
const filterButtons = await page.$$('[data-testid^="CaseList-Filter-"]');
for (const btn of filterButtons) {
const ariaLabel = await btn.getAttribute('aria-label');
const label = await btn.evaluate((el) => el.textContent?.trim() || '');
expect(ariaLabel || label.length > 0).toBeTruthy();
}
await scanFilterDialogue('status');
await scanFilterDialogue('counselor');
await scanFilterDialogue('createdAtFilter');
Expand All @@ -89,12 +110,5 @@ test.describe.serial('Case List', () => {
.analyze();
expect(caseHomeAccessibilityScanResults.violations).toEqual([]);
warnViolations(caseHomeAccessibilityScanResults, `the case home page`);
await caseListPage.editCase();
const caseEditAccessibilityScanResults = await new AxeBuilder({ page })
.include('div.Twilio-View-case-list')
.analyze();
//expect(caseHomeAccessibilityScanResults.violations).toEqual([]);
warnViolations(caseEditAccessibilityScanResults, `the case summary edit page`);
await caseListPage.closeModal();
});
});
Loading
Loading