Skip to content

Commit 922799a

Browse files
VIA-474 AS/MD Increase browsers in E2E and Snapshot tests
- Only checking LCP for Chromium
1 parent a7eece8 commit 922799a

File tree

4 files changed

+109
-28
lines changed

4 files changed

+109
-28
lines changed

e2e/general/app.spec.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { expect, test } from "@playwright/test";
2-
import { accessibilityCheck, benchmark, clickLinkAndExpectPageTitle } from "@project/e2e/helpers";
1+
import { TestInfo, expect, test } from "@playwright/test";
2+
import { accessibilityCheck, benchmarkIfChromium, clickLinkAndExpectPageTitle } from "@project/e2e/helpers";
33

44
import {
55
COOKIE_POLICY_PAGE_TITLE,
@@ -21,32 +21,32 @@ test.describe.configure({ mode: "parallel", retries: 3 });
2121
test.describe("Application", () => {
2222
test.use({ storageState: `./e2e/.auth/default.json` });
2323

24-
test("Hub page", async ({ page }) => {
24+
test("Hub page", async ({ page }, testInfo: TestInfo) => {
2525
await page.goto(HUB_PAGE_URL);
2626
await expect(page).toHaveTitle(HUB_PAGE_TITLE);
2727
await accessibilityCheck(page);
28-
expect.soft(await benchmark(page, HUB_PAGE_URL)).toBeLessThanOrEqual(MAX_AVG_LCP_DURATION_MS);
28+
await benchmarkIfChromium(page, HUB_PAGE_URL, MAX_AVG_LCP_DURATION_MS, testInfo);
2929
});
3030

31-
test("RSV page", async ({ page }) => {
31+
test("RSV page", async ({ page }, testInfo: TestInfo) => {
3232
await page.goto(RSV_PAGE_URL);
3333
await expect(page).toHaveTitle(RSV_PAGE_TITLE);
3434
await accessibilityCheck(page);
35-
expect.soft(await benchmark(page, RSV_PAGE_URL)).toBeLessThanOrEqual(MAX_AVG_LCP_DURATION_MS);
35+
await benchmarkIfChromium(page, RSV_PAGE_URL, MAX_AVG_LCP_DURATION_MS, testInfo);
3636
});
3737

38-
test("RSV in pregnancy page", async ({ page }) => {
38+
test("RSV in pregnancy page", async ({ page }, testInfo: TestInfo) => {
3939
await page.goto(RSV_PREGNANCY_PAGE_URL);
4040
await expect(page).toHaveTitle(RSV_PREGNANCY_PAGE_TITLE);
4141
await accessibilityCheck(page);
42-
expect.soft(await benchmark(page, RSV_PREGNANCY_PAGE_URL)).toBeLessThanOrEqual(MAX_AVG_LCP_DURATION_MS);
42+
await benchmarkIfChromium(page, RSV_PREGNANCY_PAGE_URL, MAX_AVG_LCP_DURATION_MS, testInfo);
4343
});
4444

45-
test("Cookie policy page", async ({ page }) => {
45+
test("Cookie policy page", async ({ page }, testInfo: TestInfo) => {
4646
await page.goto(COOKIE_POLICY_PAGE_URL);
4747
await expect(page).toHaveTitle(COOKIE_POLICY_PAGE_TITLE);
4848
await accessibilityCheck(page);
49-
expect.soft(await benchmark(page, COOKIE_POLICY_PAGE_URL)).toBeLessThanOrEqual(MAX_AVG_LCP_DURATION_MS);
49+
await benchmarkIfChromium(page, COOKIE_POLICY_PAGE_URL, MAX_AVG_LCP_DURATION_MS, testInfo);
5050
});
5151

5252
test("Back link navigation", async ({ page }) => {

e2e/general/eligibility.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import { Locator, expect, test } from "@playwright/test";
1+
import { Locator, TestInfo, expect, test } from "@playwright/test";
22
import { MAX_AVG_LCP_DURATION_MS, RSV_PAGE_URL } from "@project/e2e/constants";
33
import { UserCopy, elidCopyThatDiffersByEnvironment } from "@project/e2e/elid-copy-helper";
4-
import { accessibilityCheck, benchmark, getEnv } from "@project/e2e/helpers";
4+
import { accessibilityCheck, benchmarkIfChromium, getEnv } from "@project/e2e/helpers";
55

66
const environment = getEnv("DEPLOY_ENVIRONMENT");
77
const elidCopyForEnvironment: UserCopy =
88
environment === "preprod"
99
? elidCopyThatDiffersByEnvironment["integration"]
1010
: elidCopyThatDiffersByEnvironment["sandpit"];
1111

12-
test.describe.configure({ mode: "parallel", retries: 0 });
12+
test.describe.configure({ mode: "parallel", retries: 3 });
1313

1414
test.describe("Eligibility", () => {
15-
test.afterEach(async ({ page }) => {
15+
test.afterEach(async ({ page }, testInfo: TestInfo) => {
1616
await accessibilityCheck(page);
17-
expect.soft(await benchmark(page, RSV_PAGE_URL)).toBeLessThanOrEqual(MAX_AVG_LCP_DURATION_MS);
17+
await benchmarkIfChromium(page, RSV_PAGE_URL, MAX_AVG_LCP_DURATION_MS, testInfo);
1818
});
1919

2020
test.describe("Not Eligible", () => {

e2e/helpers.ts

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import AxeBuilder from "@axe-core/playwright";
2-
import { Page, expect } from "@playwright/test";
2+
import { Page, TestInfo, expect } from "@playwright/test";
33
import { snapshotPathTemplate } from "@project/playwright.config";
44

5+
declare global {
6+
interface Window {
7+
__lcp: number;
8+
}
9+
}
10+
511
export const getEnv = (name: string) => {
612
const value = process.env[name];
713
if (value === undefined || value === null) {
@@ -15,25 +21,50 @@ export const clickLinkAndExpectPageTitle = async (page: Page, linkText: string,
1521
await expect(page).toHaveTitle(expectedPageTitle);
1622
};
1723

18-
const lcpDuration = async (): Promise<number> => {
19-
return new Promise((resolve) => {
24+
export const benchmark = async (page: Page, target: string) => {
25+
const isLcpSupported = await page.evaluate(() => {
26+
return (
27+
typeof PerformanceObserver === "function" &&
28+
PerformanceObserver.supportedEntryTypes?.includes("largest-contentful-paint")
29+
);
30+
});
31+
32+
if (!isLcpSupported) {
33+
console.warn("⚠️ LCP is not supported in this browser — skipping LCP measurement.");
34+
return 0;
35+
}
36+
37+
// Inject LCP observer once — before page load
38+
await page.addInitScript(() => {
39+
window.__lcp = -1;
40+
2041
new PerformanceObserver((entryList) => {
2142
const entries = entryList.getEntries();
22-
const lcpDuration = entries[entries.length - 1].startTime;
23-
console.log("LCP: " + lcpDuration);
24-
resolve(lcpDuration);
43+
const lastEntry = entries[entries.length - 1];
44+
if (lastEntry) {
45+
window.__lcp = lastEntry.startTime;
46+
}
2547
}).observe({ type: "largest-contentful-paint", buffered: true });
2648
});
27-
};
2849

29-
export const benchmark = async (page: Page, target: string) => {
3050
const pageLoadTimes: number[] = [];
31-
for (let i = 0; i < 5; i++) {
51+
52+
for (let i = 0; i < 3; i++) {
3253
await page.goto(target, { waitUntil: "load" });
33-
pageLoadTimes.push(await page.evaluate(lcpDuration));
54+
55+
// Let LCP settle
56+
await page.waitForTimeout(1000);
57+
58+
const lcp = await page.evaluate(() => window.__lcp);
59+
if (typeof lcp !== "number" || lcp < 0) {
60+
throw new Error(`⚠️ LCP not collected for iteration ${i}`);
61+
}
62+
63+
pageLoadTimes.push(lcp);
3464
}
35-
const sumPageLoadTimes = pageLoadTimes.reduce((sum, cur) => sum + cur, 0);
36-
return sumPageLoadTimes / pageLoadTimes.length;
65+
66+
const averageLCP = pageLoadTimes.reduce((sum, cur) => sum + cur, 0) / pageLoadTimes.length;
67+
return averageLCP;
3768
};
3869

3970
export const accessibilityCheck = async (page: Page) => {
@@ -65,3 +96,9 @@ export const openExpanders = async (page: Page) => {
6596

6697
await page.mouse.click(0, 0);
6798
};
99+
100+
export const benchmarkIfChromium = async (page: Page, url: string, maxDuration: number, testInfo: TestInfo) => {
101+
if (testInfo.project.name === "chromium") {
102+
expect.soft(await benchmark(page, url)).toBeLessThanOrEqual(maxDuration);
103+
}
104+
};

playwright.config.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,57 @@ export default defineConfig({
6363
testMatch: /.*\.setup\.ts/,
6464
},
6565
{
66-
name: "chromium",
66+
name: "Chromium",
6767
use: {
6868
...devices["Desktop Chrome"],
6969
viewport: { width: 1920, height: 1080 },
7070
},
7171
dependencies: ['setup']
7272
},
73+
{
74+
name: "Edge",
75+
use: {
76+
...devices["Desktop Edge"],
77+
viewport: { width: 1920, height: 1080 },
78+
},
79+
dependencies: ['setup']
80+
},
81+
{
82+
name: "Firefox",
83+
use: {
84+
...devices["Desktop Firefox"],
85+
viewport: { width: 1920, height: 1080 },
86+
},
87+
dependencies: ['setup']
88+
},
89+
{
90+
name: "Safari",
91+
use: {
92+
...devices["Desktop Safari"],
93+
viewport: { width: 1920, height: 1080 },
94+
},
95+
dependencies: ['setup']
96+
},
97+
{
98+
name: 'ChromeAndroid',
99+
use: { ...devices['Pixel 5'] },
100+
dependencies: ['setup']
101+
},
102+
{
103+
name: 'SamsungInternetAndroid',
104+
use: { ...devices['Pixel 5'] },
105+
dependencies: ['setup']
106+
},
107+
{
108+
name: 'SafariIos',
109+
use: { ...devices['iPhone 12'] },
110+
dependencies: ['setup']
111+
},
112+
{
113+
name: 'ChromeIos',
114+
use: { ...devices['iPhone 12'] },
115+
dependencies: ['setup']
116+
},
73117

74118
/* Test against mobile viewports. */
75119
// {

0 commit comments

Comments
 (0)