Skip to content

Add test/vitest suite#3

Merged
DustinVK merged 10 commits into
mainfrom
test/vitest-suite
Jul 1, 2026
Merged

Add test/vitest suite#3
DustinVK merged 10 commits into
mainfrom
test/vitest-suite

Conversation

@DustinVK

@DustinVK DustinVK commented Jul 1, 2026

Copy link
Copy Markdown
Owner

No description provided.

DustinVK and others added 10 commits June 30, 2026 22:31
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stands up the walking skeleton from plan/testing-plan.md: a Vitest runner with
v8 coverage, and full coverage of the shipped pure modules (finding #13). The
draft gate and opt-out generation get crown-jewel rigor since a bug there mails
PII to the wrong place.

- vitest.config.ts: two projects (node unit / happy-dom for later), v8 coverage
  scoped to src/shared with 100/95/100 thresholds on gate.ts + templates.ts.
- gate.test.ts: evaluateGate (not_hit / no_verified_channel / first-valid-wins /
  expired+broken skipped) and channelExpiryState (warn/expired thresholds).
- transforms.test.ts: normalizeAkas (legacy split #6, object coercion #4) with
  fast-check property tests (never throws, first+last invariant); renderUrl.
- templates.test.ts: buildDraft CA/general/form + mailto/.eml/copy serializers
  (structural asserts — legal copy is still TODO Q-010).
- brokers.test.ts: getBroker + dataset invariants.
- npm scripts test/test:watch/coverage/lint:ext; .github/workflows/ci.yml
  (Node 22: typecheck, coverage, build, web-ext lint).

43 tests green, 100% coverage on src/shared, typecheck + build clean. Coordinator
and DOM tiers (T3/T4) and the reserved M7/M9 dataset-verify tiers are next.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move the run-state transitions out of background/index.ts (which registers
listeners at import and so can't be imported under test) into a side-effect-free
src/background/coordinator.ts: buildItems, withVerdict, applySkip, applyStop,
applyMarkSent, and selectBatch (the ≤1-tab-per-broker batch selection). index.ts
imports and wires them; the storage/tab I/O stays there. Behavior is identical —
typecheck + build clean.

buildItems gains an injectable `brokers` param (defaults to BROKERS) so the
non-active-broker branch is testable. coordinator.test.ts covers variant
expansion, missing-field skips (incl. array fields), the no-wedge skip guard,
run-stop, mark-sent idempotency, and batch selection (slots, one-per-broker,
already-open accounting). 65 tests, 100% coverage on src/shared + coordinator.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move the cross-site page classification out of content/index.ts (which runs
init() and binds DOM/browser at import) into a pure, DOM-only src/content/classify.ts:
detectChallenge (Cloudflare interstitial / Turnstile solved-vs-unsolved / standalone
CF iframe / hCaptcha / reCAPTCHA / DataDome) plus isResultsPage and brokerHostname.
index.ts imports and wires them; behavior unchanged (typecheck + build clean).

classify.test.ts (DOM env) covers every challenge selector and the results/details
+ hostname parsing, incl. malformed-URL fallbacks.

Swapped happy-dom → jsdom for the DOM project: happy-dom throws when materializing
<iframe> elements (even with page-loading disabled), which the challenge fixtures
need; jsdom creates them inertly (no subresource fetch). 82 tests, 100% coverage
across src/shared + coordinator.ts + classify.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move the also_known_as dynamic-row helpers out of options/index.ts (which binds
the whole page and runs init() at import) into a pure DOM module,
src/options/aka-form.ts: buildAkaRow, addAkaRow, ensureOneAkaRow, resetAkaRows,
readAkaRow, firstIncompleteAkaRow, readAkaRows. index.ts imports and wires them
into the form/save/nav paths; behavior unchanged (typecheck + build clean).

aka-form.test.ts (jsdom, against a bare #aka-rows element) locks the review
fixes from earlier this branch: the ≥1-row invariant (#5/#12), incomplete-row
detection + drop-on-read (#1), focus following add/remove (#9), and the
buildAkaRow used by the Enter-adds-row path (#2). 97 tests, 100% coverage across
src/shared + coordinator + classify + aka-form.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Record Phase 1/2a/2b/2c as done (97 tests, 100% coverage on the covered
modules) and add a cold-start "Next steps" checklist: finish T4 (overlay PII
invariant), the reserved M7/M9 dataset-verify + schema tiers, and infra
housekeeping (local web-ext lint on Node 22, coverage include, PR sequencing).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New entry 2026-07-01-test-suite-buildout: test shipped M0–M6 now and reserve the
M7/M9 dataset-verify + schema tiers (built test-first with the feature);
extract-for-testability (coordinator/classify/aka-form) over mock-importing
entrypoints; jsdom over happy-dom (iframe materialization); web-ext lint CI-only
(local Node 25.8.1 SIGBUS). Extends 2026-06-30-vitest-test-runner (not superseded).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`npm ci` failed in CI: the committed package-lock.json was generated by the local
npm 11 (Node 25), which resolves a different tree than CI's npm 10 (Node 22) and
omitted the transitive esbuild@0.28.1 (+ its platform packages) that vite/vitest
pulls in. Regenerated the lock with npm 10 so it matches CI (validated locally
with `npx npm@10 ci` → clean; 97 tests + build still green).

Add .nvmrc (22) and point setup-node at node-version-file so local (`nvm use`)
and CI share one Node/npm version — preventing this lock drift from recurring.
Also unbreaks `npm run lint:ext` locally, which SIGBUSes on Node 25.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Correctness (source bugs the tests had enshrined):
- mailtoUrl: encode per RFC 6068 (spaces → %20, not URLSearchParams' '+').
- toEml: normalize the body to CRLF (no bare LF under CRLF headers).
- isResultsPage: take a pathname (callers pass window.location.pathname) so the
  extraction no longer parses currentUrl — restores the original non-throwing left
  operand.
- content/index.ts: rename the buildGuidancePanel `brokerHostname` param to
  `hostname` so it no longer shadows the imported classifier.

Test-suite integrity (vitest.config.ts):
- Single project + `// @vitest-environment jsdom` docblocks → every src/**/*.test.ts
  is discovered (no per-dir allow-list; src/popup etc. can't silently run zero tests).
- Coverage is opt-out: include src/** minus the DOM/browser entrypoints (excluded
  explicitly + visibly), so a new tested module is covered by default.
- Add `statements: 100` to the gate.ts/templates.ts crown-jewel thresholds; note the
  literal-path glob fragility. html reporter is dev-only (CI uses text).

Test quality:
- gate.test.ts: deterministic exact-boundary tests via vi.setSystemTime (the >=6/>=12mo
  edges were never exercised).
- transforms.test.ts: fast-check property returns a boolean (shrinkable; expect-in-
  property defeated shrinking).
- coordinator.test.ts: default-BROKERS test compares to BROKERS instead of pinning the
  single shipped broker id (stays green when brokers are added).
- brokers.test.ts: look up by stable id (not the mutable name); add a trust-hygiene
  invariant (verified channels carry provenance).
- Share Broker/Channel/Profile/Item/Run fixtures via src/test-support/fixtures.ts.
- classify.test.ts: unique it.each titles; fix stale happy-dom comments.

Housekeeping:
- Remove unused @testing-library/dom + user-event; drop the dead AkaName import.
- CI: note it does not enforce the M9 contributed-record trust gate.

100 tests, 100% coverage on the covered modules; typecheck + build clean.
(Not changed: firstIncompleteAkaRow's Array.from — required by this tsconfig's lib for
NodeList for-of; .nvmrc pins Node not npm — CI's npm ci still catches lock drift.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@DustinVK DustinVK changed the title Test/vitest suite Add test/vitest suite Jul 1, 2026
@DustinVK DustinVK merged commit a632f34 into main Jul 1, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant