2.1 KiB
2.1 KiB
testing-e2e: async-span + apiContext fixture hardening
Package: @suaveplan/testing-e2e
Status: PROPOSED
Type: bug-fix
Why
Two latent defects:
extendedTest.apiContextrequests a browser it never uses.src/fixtures/extended-test.tsdestructures{ browser: _browser }from Playwright's fixture deps. Playwright's fixture system spins up the requested deps eagerly; declaringbrowsertriggers a Chromium launch even for API-only test files. API-only suites pay hundreds of ms per worker for nothing.instrumented()ends spans synchronously even for async fns. Same defect as in@suaveplan/testing-dom. Every histogram emitted by an async-wrapped helper records ~0 ms.
What changes
- MODIFIED:
src/fixtures/extended-test.ts#apiContext— changes the destructure from{ browser: _browser }to{}so Playwright doesn't materialise a browser for API-only tests. - MODIFIED:
src/observability/instrumented.ts— detects PromiseLike return values and ends the OTel span (and records the histogram) only after the promise settles. - MODIFIED:
openspec/specs/testing-e2e/spec.md— coverage gate raised from ≥95% to 100% to matchCLAUDE.md's pre-publish gate. Path reference updated frompackages/universal/testing-e2e/topackages/dev/testing-e2e/.
Out of scope
- Refactoring
instrumented()away fromtracer.startActiveSpan— keeping the same OTel surface, only fixing span lifetime. - Adding new fixtures to
extendedTest.
Verification approach
src/fixtures/extended-test.test.ts— source-level guard that the apiContext fixture body destructures an empty object, NOT one containingbrowser.src/observability/instrumented.test.ts::"ends span only after async fn settles (resolved)"— observable timing assertion (elapsed >= 10ms).src/observability/instrumented.test.ts::"ends span only after async fn settles (rejected)"and"… (rejected with non-Error)"— pin the rejection branch includingrecordExceptionfor non-Error throws.
Migration impact
None — bug-fix-only behavioural change. Consumers' existing tests continue to pass.