5.6 KiB
ADDED Requirements
Requirement: ConsoleMonitor
The @suaveplan/testing-e2e package SHALL export attachConsoleMonitor(page, options?) returning an object exposing errors: ConsoleMessage[], warnings: ConsoleMessage[], assertNoErrors(): void, and assertNoWarnings(): void. The default behaviour MUST forbid all console errors and warnings; the options.failOn field MAY relax to ["error"] only. The options.ignore field MAY accept regex or string filters that exempt matching messages.
assertNoErrors() and assertNoWarnings() MUST throw TestingE2eError subclasses (code === "TESTING_E2E.CONSOLE.ERRORS_OBSERVED" / "TESTING_E2E.CONSOLE.WARNINGS_OBSERVED") carrying the captured messages on context.
Scenario: No errors observed
- WHEN a page emits only
info-level console output andmonitor.assertNoErrors()is called - THEN the call returns without throwing
Scenario: Error observed
- WHEN a page logs
console.error("boom")andmonitor.assertNoErrors()is called - THEN the call throws with
code === "TESTING_E2E.CONSOLE.ERRORS_OBSERVED"ANDcontext.messagesincludes"boom"
Scenario: Filter exempts known noise
- WHEN
attachConsoleMonitor(page, { ignore: [/Download the React DevTools/] })is used and a matching warning fires - THEN
monitor.warningsdoes not include the matching message ANDassertNoWarnings()does not throw
Requirement: NetworkMonitor with full failure-class assertions
attachNetworkMonitor(page) SHALL return an object exposing failures: Request[] and four assertion methods, each throwing a coded TestingE2eError subclass:
assertNoFailures()— fails on any request that returned 4xx, 5xx, network error, or aborted (codeTESTING_E2E.NETWORK.FAILURES_OBSERVED).assertNoMissingAssets()— fails on any 404 for an asset request whoseresourceTypeisimage | font | script | stylesheet(codeTESTING_E2E.NETWORK.MISSING_ASSETS).assertNoMixedContent()— fails when the page is HTTPS and any subresource is HTTP (codeTESTING_E2E.NETWORK.MIXED_CONTENT).assertNoCorsErrors()— fails on any request blocked by the browser's CORS rules (codeTESTING_E2E.NETWORK.CORS_BLOCKED).
Scenario: 404 image fails missing-assets check
- WHEN a
<img src="/missing.png">is rendered and the response is 404 - THEN
monitor.assertNoMissingAssets()throws withcode === "TESTING_E2E.NETWORK.MISSING_ASSETS"ANDcontext.urlsincludes the image URL
Scenario: HTTPS page loading HTTP script triggers mixed-content
- WHEN an HTTPS page loads a
<script src="http://…"> - THEN
monitor.assertNoMixedContent()throws withcode === "TESTING_E2E.NETWORK.MIXED_CONTENT"
Scenario: CORS-blocked request
- WHEN a fetch is blocked by CORS
- THEN
monitor.assertNoCorsErrors()throws withcode === "TESTING_E2E.NETWORK.CORS_BLOCKED"
Requirement: Multi-session WebRTC fixture
The package SHALL export createMultiSessionFixture(opts) returning an object that owns at least two isolated browser contexts sharing a signaling URL but with separated cookies and storage. The fixture MUST expose:
sessions: { context: BrowserContext; page: Page }[]— at least two entriesassertMessage(from: number, to: number, predicate: (data: unknown) => boolean): Promise<void>— asserts a peer-to-peer message arrivesdisableSignalingRoute(): Promise<void>— chaos hook that 5xx-responses to the signaling URL until re-enabled
Scenario: Two sessions exchange a message
- WHEN session 0 sends a payload and
assertMessage(0, 1, p => p === "hello")is awaited - THEN the assertion resolves once session 1 observes the payload
Scenario: Disabling signaling produces a deterministic failure
- WHEN
disableSignalingRoute()is called and a new session attempts to register - THEN the registration fails with a 5xx from the signaling URL
Requirement: Extension fixture
The package SHALL export extendTestWithExtension(extPath: string) that loads a Chromium extension into the persistent context and exposes popup, background, and contentScript accessors on the test fixture. The accessors MUST return Playwright Page (popup), Worker or Page (background — service worker or background page depending on manifest version), and an array of Page (one per content-script-injected frame) respectively.
Scenario: Background service worker accessible
- WHEN an MV3 extension is loaded and the test reads
background - THEN the returned value is a Playwright
Workerwhose URL begins withchrome-extension://
Requirement: Default-deny network sandbox
createPlaywrightConfig SHALL default to blocking external origins by registering page.route('**/*', …) that aborts requests whose origin is not in options.allowedOrigins. Same-origin requests to the configured baseURL MUST always be allowed. Callers MAY supply allowedOrigins: string[] to extend the allow-list. Setting options.allowedOrigins = "*" disables the sandbox (escape hatch for fully-online specs).
Scenario: External fetch blocked by default
- WHEN a page running under
createPlaywrightConfig({ baseURL: "http://localhost:3000" })issues afetch("https://api.external.com/x") - THEN the request is aborted by Playwright before it leaves the browser
Scenario: Allow-list grants access
- WHEN the same config is constructed with
allowedOrigins: ["https://api.external.com"] - THEN the same fetch resolves normally
Scenario: Escape hatch disables sandbox
- WHEN
allowedOrigins === "*" - THEN no
page.routeblock is registered AND every request proceeds