3.1 KiB
Capability Spec Delta: testing-e2e (testing-e2e-async-and-fixtures-hardening)
Package: @suaveplan/testing-e2e
Status: PROPOSED
ADDED Requirements
Requirement: extendedTest.apiContext is browser-free
The apiContext fixture in extendedTest SHALL NOT request the browser fixture from Playwright's dependency graph. Playwright spins up requested deps eagerly, so destructuring browser would launch a Chromium instance for every API-only test, blowing the per-suite startup budget.
Scenario: Source-level guard
- WHEN
src/fixtures/extended-test.tsis parsed - THEN the apiContext fixture body destructures an empty object AND its destructure list contains no
browsertoken
Scenario: extendedTest export shape
- WHEN a consumer imports
extendedTestfrom@suaveplan/testing-e2e/fixtures - THEN the value is a callable Playwright test extension exposing
.extend(...)
Verified by: src/fixtures/extended-test.test.ts::"apiContext fixture does not destructure \browser`"ANDsrc/fixtures/extended-test.test.ts::"extendedTest is exported as a Playwright test extension"`
Requirement: instrumented() ends spans only after async fns settle
instrumented(name, fn) SHALL detect when the wrapped function returns a PromiseLike value and SHALL defer span.end() and the duration histogram record until the returned promise settles. On rejection, the span SHALL recordException (wrapping non-Error rejections in new Error(String(reason))) before ending. On resolution, the duration recorded SHALL reflect the wall-clock interval between invocation and settlement.
Scenario: async resolve
- WHEN the wrapped fn awaits ≥10ms before returning
- THEN the awaited result equals the inner return value AND the elapsed wall-clock time is ≥10ms
Scenario: async reject
- WHEN the wrapped async fn throws an
Error - THEN the returned promise rejects with the same error
Scenario: async reject with non-Error reason
- WHEN the wrapped async fn rejects with a string
- THEN the returned promise rejects with the same string AND
recordExceptionis invoked with a wrappedError
Verified by: src/observability/instrumented.test.ts::"ends span only after async fn settles (resolved)" AND src/observability/instrumented.test.ts::"ends span only after async fn settles (rejected)" AND src/observability/instrumented.test.ts::"ends span only after async fn settles (rejected with non-Error)"
MODIFIED Requirements
Requirement: Coverage and docs gates
Istanbul statement + branch + function + line coverage across packages/dev/testing-e2e/src/ (excluding *.bench.ts, *.schemas.ts, barrel index.ts files) MUST be 100% on every dimension. Every implementation file MUST have a sibling .md (≥ 200 words, simple + advanced examples).
Scenario: CI coverage gate
- WHEN
bunx turbo test:coverage --filter=@suaveplan/testing-e2eruns - THEN statement / branch / function / line coverage all = 100%
Verified by: CI gate (bunx turbo test:coverage --filter=@suaveplan/testing-e2e exits non-zero on regression)