Skip to content

Commit 0a5e173

Browse files
e2e(frontend) Improve some E2E tests (#272)
1 parent 53884cb commit 0a5e173

11 files changed

+214
-61
lines changed

frontend/e2e/estimator/results.spec.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import AxeBuilder from '@axe-core/playwright';
22
import { expect, test } from '@playwright/test';
33
import { seedSessionData } from 'e2e/__supports/session-supports';
44
import { formatHtml } from 'e2e/__supports/string-utils';
5+
import { PlaywrightEstimatorPage } from 'e2e/models/PlaywrightEstimatorPage';
56

67
const stagedSession = {
78
estimator: {
@@ -26,43 +27,49 @@ const stagedSession = {
2627
};
2728

2829
test('Navigating to /en/results renders the english results page', async ({ page }) => {
30+
const estimator = new PlaywrightEstimatorPage(page);
2931
const resp = await seedSessionData(page, stagedSession);
3032
expect(resp.status()).toBe(200);
3133

3234
await page.goto('/en/results');
35+
await estimator.isLoaded('results');
3336

3437
expect(await formatHtml(await page.locator('main').innerHTML())).toMatchSnapshot();
3538
});
3639

3740
test('Navigating to /fr/resultats renders the french results page', async ({ page }) => {
41+
const estimator = new PlaywrightEstimatorPage(page);
3842
const resp = await seedSessionData(page, stagedSession);
3943
expect(resp.status()).toBe(200);
4044

4145
await page.goto('/fr/resultats');
46+
await estimator.isLoaded('results', 'fr');
4247

4348
expect(await formatHtml(await page.locator('main').innerHTML())).toMatchSnapshot();
4449
});
4550

4651
test('/en/results passes a11y checks', async ({ page }) => {
52+
const estimator = new PlaywrightEstimatorPage(page);
4753
const resp = await seedSessionData(page, stagedSession);
4854
expect(resp.status()).toBe(200);
4955

5056
await page.goto('/en/results');
51-
await page.locator('main').waitFor();
57+
await estimator.isLoaded('results');
5258

53-
const accessibilityScanResults = await new AxeBuilder({ page }).include('main').analyze();
59+
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
5460

5561
expect(accessibilityScanResults.violations).toEqual([]);
5662
});
5763

5864
test('/fr/resultats passes a11y checks', async ({ page }) => {
65+
const estimator = new PlaywrightEstimatorPage(page);
5966
const resp = await seedSessionData(page, stagedSession);
6067
expect(resp.status()).toBe(200);
6168

6269
await page.goto('/fr/resultats');
63-
await page.locator('main').waitFor();
70+
await estimator.isLoaded('results', 'fr');
6471

65-
const accessibilityScanResults = await new AxeBuilder({ page }).include('main').analyze();
72+
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
6673

6774
expect(accessibilityScanResults.violations).toEqual([]);
6875
});

frontend/e2e/estimator/step-income.spec.ts

+12-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import AxeBuilder from '@axe-core/playwright';
22
import { expect, test } from '@playwright/test';
33
import { seedSessionData } from 'e2e/__supports/session-supports';
44
import { formatHtml } from 'e2e/__supports/string-utils';
5+
import { PlaywrightEstimatorPage } from 'e2e/models/PlaywrightEstimatorPage';
56

67
const stagedSession = {
78
estimator: {
@@ -11,46 +12,49 @@ const stagedSession = {
1112
};
1213

1314
test('Navigating to /en/income renders the english income page', async ({ page }) => {
15+
const estimator = new PlaywrightEstimatorPage(page);
1416
const resp = await seedSessionData(page, stagedSession);
1517
expect(resp.status()).toBe(200);
1618

1719
await page.goto('/en/income');
18-
expect(page.url()).toContain('/en/income');
20+
await estimator.isLoaded('income');
1921

2022
expect(await formatHtml(await page.locator('main').innerHTML())).toMatchSnapshot();
2123
});
2224

2325
test('Navigating to /fr/revenus renders the french income page', async ({ page }) => {
26+
const estimator = new PlaywrightEstimatorPage(page);
2427
const resp = await seedSessionData(page, stagedSession);
2528
expect(resp.status()).toBe(200);
2629

2730
await page.goto('/fr/revenus');
28-
expect(page.url()).toContain('/fr/revenus');
31+
await estimator.isLoaded('income', 'fr');
32+
2933
expect(await formatHtml(await page.locator('main').innerHTML())).toMatchSnapshot();
3034
});
3135

3236
test('/en/income passes a11y checks', async ({ page }) => {
37+
const estimator = new PlaywrightEstimatorPage(page);
3338
const resp = await seedSessionData(page, stagedSession);
3439
expect(resp.status()).toBe(200);
3540

3641
await page.goto('/en/income');
37-
expect(page.url()).toContain('/en/income');
38-
await page.locator('main').waitFor();
42+
await estimator.isLoaded('income');
3943

40-
const accessibilityScanResults = await new AxeBuilder({ page }).include('main').analyze();
44+
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
4145

4246
expect(accessibilityScanResults.violations).toEqual([]);
4347
});
4448

4549
test('/fr/revenus passes a11y checks', async ({ page }) => {
50+
const estimator = new PlaywrightEstimatorPage(page);
4651
const resp = await seedSessionData(page, stagedSession);
4752
expect(resp.status()).toBe(200);
4853

4954
await page.goto('/fr/revenus');
50-
expect(page.url()).toContain('/fr/revenus');
51-
await page.locator('main').waitFor();
55+
await estimator.isLoaded('income', 'fr');
5256

53-
const accessibilityScanResults = await new AxeBuilder({ page }).include('main').analyze();
57+
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
5458

5559
expect(accessibilityScanResults.violations).toEqual([]);
5660
});
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,40 @@
11
import AxeBuilder from '@axe-core/playwright';
22
import { expect, test } from '@playwright/test';
33
import { formatHtml } from 'e2e/__supports/string-utils';
4+
import { PlaywrightEstimatorPage } from 'e2e/models/PlaywrightEstimatorPage';
45

56
test('Navigating to /en/marital-status renders the english marital-status page', async ({ page }) => {
7+
const estimator = new PlaywrightEstimatorPage(page);
68
await page.goto('/en/marital-status');
9+
await estimator.isLoaded('marital-status');
710

811
expect(await formatHtml(await page.locator('main').innerHTML())).toMatchSnapshot();
912
});
1013

1114
test('Navigating to /fr/etat-civil renders the french marital-status page', async ({ page }) => {
15+
const estimator = new PlaywrightEstimatorPage(page);
1216
await page.goto('/fr/etat-civil');
17+
await estimator.isLoaded('marital-status', 'fr');
1318

1419
expect(await formatHtml(await page.locator('main').innerHTML())).toMatchSnapshot();
1520
});
1621

1722
test('/en/marital-status passes a11y checks', async ({ page }) => {
23+
const estimator = new PlaywrightEstimatorPage(page);
1824
await page.goto('/en/marital-status');
19-
await page.locator('main').waitFor();
25+
await estimator.isLoaded('marital-status');
2026

21-
const accessibilityScanResults = await new AxeBuilder({ page }).include('main').analyze();
27+
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
2228

2329
expect(accessibilityScanResults.violations).toEqual([]);
2430
});
2531

2632
test('/fr/etat-civil passes a11y checks', async ({ page }) => {
33+
const estimator = new PlaywrightEstimatorPage(page);
2734
await page.goto('/fr/etat-civil');
28-
await page.locator('main').waitFor();
35+
await estimator.isLoaded('marital-status', 'fr');
2936

30-
const accessibilityScanResults = await new AxeBuilder({ page }).include('main').analyze();
37+
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
3138

3239
expect(accessibilityScanResults.violations).toEqual([]);
3340
});

frontend/e2e/index.spec.ts

+15-4
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,44 @@ import AxeBuilder from '@axe-core/playwright';
22
import { expect, test } from '@playwright/test';
33

44
import { formatHtml } from './__supports/string-utils';
5+
import { PlaywrightEstimatorPage } from './models/PlaywrightEstimatorPage';
56

67
test('Navigating to /en renders the english dashboard page', async ({ page }) => {
8+
const estimator = new PlaywrightEstimatorPage(page);
9+
710
await page.goto('/en');
11+
await estimator.isLoaded('index');
812

913
expect(await formatHtml(await page.locator('main').innerHTML())).toMatchSnapshot();
1014
});
1115

1216
test('Navigating to /fr renders the french dashboard page', async ({ page }) => {
17+
const estimator = new PlaywrightEstimatorPage(page);
18+
1319
await page.goto('/fr');
20+
await estimator.isLoaded('index', 'fr');
1421

1522
expect(await formatHtml(await page.locator('main').innerHTML())).toMatchSnapshot();
1623
});
1724

1825
test('/en passes a11y checks', async ({ page }) => {
26+
const estimator = new PlaywrightEstimatorPage(page);
27+
1928
await page.goto('/en');
20-
await page.locator('main').waitFor();
29+
await estimator.isLoaded('index');
2130

22-
const accessibilityScanResults = await new AxeBuilder({ page }).include('main').analyze();
31+
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
2332

2433
expect(accessibilityScanResults.violations).toEqual([]);
2534
});
2635

2736
test('/fr passes a11y checks', async ({ page }) => {
37+
const estimator = new PlaywrightEstimatorPage(page);
38+
2839
await page.goto('/fr');
29-
await page.locator('main').waitFor();
40+
await estimator.isLoaded('index', 'fr');
3041

31-
const accessibilityScanResults = await new AxeBuilder({ page }).include('main').analyze();
42+
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
3243

3344
expect(accessibilityScanResults.violations).toEqual([]);
3445
});
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { expect } from '@playwright/test';
2+
import type { Page } from '@playwright/test';
3+
4+
export class PlaywrightBasePage {
5+
readonly page: Page;
6+
7+
constructor(page: Page) {
8+
this.page = page;
9+
}
10+
11+
async isLoaded(url: string | RegExp, language: Language, heading: string | RegExp) {
12+
await this.page.locator('main').waitFor();
13+
14+
await expect(this.page.locator('html')).toHaveAttribute('lang', language);
15+
16+
await expect(this.page).toHaveURL(url);
17+
await expect(this.page.getByRole('heading', { level: 1, name: heading })).toBeVisible();
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { PlaywrightBasePage } from './PlaywrightBasePage';
2+
3+
export class PlaywrightEstimatorPage extends PlaywrightBasePage {
4+
async isLoaded(
5+
estimatorPage: 'index' | 'marital-status' | 'income' | 'results',
6+
language: Language = 'en',
7+
heading?: string | RegExp,
8+
) {
9+
let pageInfo: { url: string | RegExp; heading: string | RegExp } | undefined = undefined;
10+
11+
switch (estimatorPage) {
12+
case 'index':
13+
pageInfo =
14+
language === 'fr'
15+
? { url: /\/fr/, heading: 'Estimateur de la Prestation canadienne pour les personnes handicapées' }
16+
: { url: /\/en/, heading: 'Canada Disability Benefit Estimator' };
17+
break;
18+
19+
case 'marital-status':
20+
pageInfo =
21+
language === 'fr'
22+
? { url: /\/fr\/etat-civil/, heading: 'Étape 1 de 2 : État matrimonial' }
23+
: { url: /\/en\/marital-status/, heading: 'Step 1 of 2: Marital Status' };
24+
break;
25+
26+
case 'income':
27+
pageInfo =
28+
language === 'fr'
29+
? { url: /\/fr\/revenus/, heading: 'Étape 2 de 2 : Revenu' }
30+
: { url: /\/en\/income/, heading: 'Step 2 of 2: Income' };
31+
break;
32+
33+
case 'results':
34+
pageInfo =
35+
language === 'fr' //
36+
? { url: /\/fr\/resultats/, heading: 'Résultats' }
37+
: { url: /\/en\/results/, heading: 'Results' };
38+
break;
39+
40+
default:
41+
pageInfo = undefined;
42+
break;
43+
}
44+
45+
if (!pageInfo) throw Error(`estimatorPage '${estimatorPage}' not implemented.`);
46+
await super.isLoaded(pageInfo.url, language, heading ?? pageInfo.heading);
47+
}
48+
}

frontend/e2e/not-found.spec.ts

+21-6
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,52 @@ import AxeBuilder from '@axe-core/playwright';
22
import { expect, test } from '@playwright/test';
33

44
import { formatHtml } from './__supports/string-utils';
5+
import { PlaywrightBasePage } from './models/PlaywrightBasePage';
56

67
test('Navigating to /foo renders the bilingual 404 page', async ({ page }) => {
7-
await page.goto('/foo');
8+
const notFoundPage = new PlaywrightBasePage(page);
9+
10+
const notFoundResponse = await page.goto('/foo');
11+
await notFoundPage.isLoaded(/\/foo$/, 'en', /We couldn't find that web page/);
12+
await notFoundPage.isLoaded(/\/foo$/, 'en', /Nous ne pouvons trouver cette page/);
813

14+
expect(notFoundResponse?.status()).toBe(404);
915
expect(await formatHtml(await page.locator('header').innerHTML())).toMatchSnapshot();
1016
expect(await formatHtml(await page.locator('main').innerHTML())).toMatchSnapshot();
1117
expect(await formatHtml(await page.locator('footer').innerHTML())).toMatchSnapshot();
1218
});
1319

1420
test('Navigating to /en/foo renders the unilingual 404 page', async ({ page }) => {
15-
await page.goto('/en/foo');
21+
const notFoundPage = new PlaywrightBasePage(page);
1622

23+
const notFoundResponse = await page.goto('/en/foo');
24+
await notFoundPage.isLoaded(/\/en\/foo$/, 'en', /We couldn't find that web page/);
25+
26+
expect(notFoundResponse?.status()).toBe(404);
1727
expect(await formatHtml(await page.locator('header').innerHTML())).toMatchSnapshot();
1828
expect(await formatHtml(await page.locator('main').innerHTML())).toMatchSnapshot();
1929
expect(await formatHtml(await page.locator('footer').innerHTML())).toMatchSnapshot();
2030
});
2131

2232
test('Bilingual 404 page passes a11y checks', async ({ page }) => {
33+
const notFoundPage = new PlaywrightBasePage(page);
34+
2335
await page.goto('/foo');
24-
await page.locator('main').waitFor();
36+
await notFoundPage.isLoaded(/\/foo$/, 'en', /We couldn't find that web page/);
37+
await notFoundPage.isLoaded(/\/foo$/, 'en', /Nous ne pouvons trouver cette page/);
2538

26-
const accessibilityScanResults = await new AxeBuilder({ page }).include('main').analyze();
39+
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
2740

2841
expect(accessibilityScanResults.violations).toEqual([]);
2942
});
3043

3144
test('Unilingual 404 page passes a11y checks', async ({ page }) => {
45+
const notFoundPage = new PlaywrightBasePage(page);
46+
3247
await page.goto('/en/foo');
33-
await page.locator('main').waitFor();
48+
await notFoundPage.isLoaded(/\/en\/foo$/, 'en', /We couldn't find that web page/);
3449

35-
const accessibilityScanResults = await new AxeBuilder({ page }).include('main').analyze();
50+
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
3651

3752
expect(accessibilityScanResults.violations).toEqual([]);
3853
});

frontend/e2e/single-results.spec.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
11
import { expect, test } from '@playwright/test';
22

3+
import { PlaywrightEstimatorPage } from './models/PlaywrightEstimatorPage';
4+
35
test('Single person can obtain results', async ({ page }) => {
6+
const estimator = new PlaywrightEstimatorPage(page);
7+
48
// splash page
59
await page.goto('/');
10+
await page.getByText(/english/i).click();
611

712
// dashboard
8-
await page.getByText(/english/i).click();
13+
await estimator.isLoaded('index');
914
await page.getByText(/start/i).click();
1015

1116
// marital-status
17+
await estimator.isLoaded('marital-status');
1218
await page.getByRole('radio', { name: /single/i }).check();
1319
await page.getByRole('button', { name: /continue/i }).click();
1420

1521
// income
22+
await estimator.isLoaded('income');
1623
await page.getByRole('textbox', { name: /net income/i }).fill('23000.31');
1724
await page.getByRole('textbox', { name: /working income/i }).fill('0');
1825
await page.getByRole('textbox', { name: /^(?=.*uccb)(?=.*rdsp)(?=.*income).*/i }).fill('0');
1926
await page.getByRole('textbox', { name: /^(?=.*uccb)(?=.*rdsp)(?=.*repayment).*/i }).fill('0');
2027
await page.getByRole('button', { name: /estimate/i }).click();
2128

2229
// result
23-
await page.locator('html').waitFor();
30+
await estimator.isLoaded('results');
2431
await expect(page.getByRole('main')).toContainText('$199.99');
2532
});

0 commit comments

Comments
 (0)