Skip to content

test(frontend): add jsdom + React Testing Library harness - #78

Merged
tyler-rich merged 1 commit into
devfrom
claude/frontend-test-harness-el4nev
Jul 20, 2026
Merged

test(frontend): add jsdom + React Testing Library harness#78
tyler-rich merged 1 commit into
devfrom
claude/frontend-test-harness-el4nev

Conversation

@tyler-rich

@tyler-rich tyler-rich commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Summary

Adds the frontend DOM test infrastructure that was missing, so component- and page-level render tests are now possible. Previously Vitest ran only in the node environment, limiting coverage to the pure src/lib/ helpers — which blocked proper tests for four already-shipped fixes (P3-3, M19, M20, M21). See docs/reviews/STATUS.md § "Test debt on already-shipped fixes."

This lands the harness and proves it works end-to-end. It deliberately does not backfill the M19/M20/M21/P3-3 page-level tests — that is follow-up work, now unblocked.

What changed

  • Vitest two-project split by file extension (frontend/vite.config.ts):
    • *.test.tsnode (the existing src/lib/ helper tests, untouched)
    • *.test.tsxjsdom + React Testing Library
  • New exact-pinned dev dependencies: [email protected], @testing-library/[email protected], @testing-library/[email protected], @testing-library/[email protected], @testing-library/[email protected].
  • src/test/setup.ts — jest-dom matchers, per-test unmount, and the matchMedia/ResizeObserver/scrollIntoView polyfills Mantine needs under jsdom (loaded only by the jsdom project).
  • src/test/render.tsx — shared renderWithProviders wrapping MantineProvider + a router, re-exporting the Testing Library surface.
  • src/pages/NewScanPage.test.tsx — one smoke test proving render, query, and a Retry click against the shipped P3-3 credential-load-failure warning.
  • eslint.config.js — override turning off react-refresh/only-export-components for test files/utilities (outside the Fast-Refresh graph).
  • CONTRIBUTING.md — documents the .test.ts→node / .test.tsx→jsdom convention and the renderWithProviders pattern.

Verification

  • npm test — 22 passed (both node and jsdom projects)
  • npm run lint — clean (0 errors, 0 warnings)
  • npm run format:check — clean
  • npm run buildtsc -b (type-checks the new test files) + vite build pass
  • npm ci — lockfile in sync

See docs/ARCHIVE.md § Deviations for the dated entry added in this change.

Add the DOM test infrastructure the frontend suite was missing so
component- and page-level render tests are possible. Vitest now runs two
projects split by file extension: *.test.ts under node (existing src/lib
helper tests, untouched) and *.test.tsx under jsdom with React Testing
Library.

- Pin jsdom, @testing-library/{react,dom,user-event,jest-dom} as exact
  dev dependencies.
- Add src/test/setup.ts (jest-dom matchers, per-test unmount, Mantine DOM
  polyfills) and src/test/render.tsx (MantineProvider + router wrapper).
- Prove the harness end-to-end with a smoke test over the shipped P3-3
  credential-load-failure warning (src/pages/NewScanPage.test.tsx).
- Exempt test files from react-refresh/only-export-components.
- Document the .test.ts/.test.tsx convention and renderWithProviders
  pattern in CONTRIBUTING.md; log the harness in docs/ARCHIVE.md §14.

Infrastructure only — the M19/M20/M21/P3-3 page-level tests remain
follow-up work, now unblocked. See docs/reviews/STATUS.md test-debt.
@tyler-rich
tyler-rich merged commit 8ed79e4 into dev Jul 20, 2026
4 checks passed
tyler-rich added a commit that referenced this pull request Jul 26, 2026
…s structure, correct a false CVE claim in the CHANGELOG (#102)

* docs(archive): make §14 contiguous, add a newest-first index, and add the finding-ID decoder

Twelve dated §14 entries — every one from 2026-07-09 onward, including all the
recent work — sat underneath `## Build performance` rather than under §14, so
anyone scrolling §14 to the end stopped short of them. Moved the Build
performance section to the end of the file instead of re-parenting the entries:
it is self-contained and cross-referenced by heading name (from CLAUDE.md and
four workflows), not by position, so nothing breaks. All 104 dated entries are
now under §14.

Added a newest-first index at the top of §14, one anchored line per entry. The
entries themselves are deliberately NOT reordered: sixteen of them refer to each
other relatively ("the entry below", "superseded by the entry above"), and a
sort would silently invert every one. The three ordering regimes are documented
instead, and the index is sorted by date regardless of physical position, so
lookup no longer depends on the scroll order.

Added §15, a finding-ID index: one row per SEC/SC/APIR/CON/P1-P3/D/R/QUA/INF/
FE/API/FEAT/DOC/SCN id with a one-line description and its resolving PR. §14
cites these ids bare and never re-explains them; this is the decoder that
replaces the docs/reviews/ reports. It also records the SEC-* prefix collision
between the two reviews that reused it.

Corrected §0 locked decision #7: it said CVE-2025-15366 and CVE-2025-15367 are
both unfixable on 3.14. That is true of released 3.14.6 but not of the 3.14
line — the imaplib backport landed on the maintenance branch and closes on
3.14.7 (issue #98). Only the poplib CVE remains 3.15-only (#52).

* docs(changelog): correct the CVE-2025-15366 claim under [Unreleased]

The Python 3.14 entry said all four waived CPython CVEs remain unfixable until
3.15 because upstream declined the backport to 3.10-3.14, and pointed at issue
#52 for all of them. Both halves are false, and this text ships verbatim as the
next release's notes.

Checked against ci/grype.yaml and the two 2026-07-26 §14 entries: the imaplib
backport for CVE-2025-15366 merged onto the CPython 3.14 branch on 2026-07-07 —
18 days before the entry was written — so it closes on 3.14.7, not 3.15, and it
was regrouped into Group A alongside CVE-2026-15308 and CVE-2026-12003, tracked
in issue #98. Only CVE-2025-15367 (poplib) is genuinely 3.15-only and still
tracked in #52.

What was true and is kept: released 3.14.6 carries neither guard, so the upgrade
cleared nothing at the pinned version.

* docs: strike completed roadmap items, surface the settings-level work, add two process rules

ROADMAP:
- Struck "Pin GitHub Actions to commit SHAs" (done in #57 — ci.yml has 8
  SHA-pinned uses:, dev-nightly 3, publish 3, rescan 2) and "Frontend test
  runner" (done in #78 — vitest 3.2.7, "test": "vitest run", 20 test files).
- Rewrote "Row-bound secret AAD", which was false as stated: row binding is
  implemented (secret_store.py row_aad(), L1/SEC-7, #64) and every write is
  row-bound. What remains is only the bulk re-encryption of legacy column-only
  ciphertext so the read fallback can be dropped, so it is folded into the
  existing "Admin bulk secret re-encryption" item.
- Extended the public-repo governance checklist with five settings-level items
  that existed only in §14 prose and were therefore invisible: Actions workflow
  permissions -> read-only, confirm GHCR package visibility is public (the
  original check asked for Private and its premise inverted when the repo went
  public), delete the unused DOCKERHUB_* secrets, set the GitHub profile display
  name to tyler-rich, and confirm Dependabot security alerts are on.

CLAUDE.md § Git & PR conventions gains two rules learned the hard way: a stacked
child PR retargeted after its parent was squash-merged needs git rebase --onto
(flipping the base in the UI re-computes the merge base and balloons the diff),
and on: pull_request does not fire on 'edited', so a base change never re-runs
CI and the green check you are looking at is from the old base.

CONTRIBUTING § Releasing gains a "Before you tag" checklist — CHANGELOG
[Unreleased] reviewed (it ships verbatim), THIRD_PARTY_LICENSES verified against
the versions actually pulled, Dependabot PRs triaged, requirements.lock
regenerated — plus the two after-tag steps: back-merge main into dev, and re-run
rescan.yml.

* docs: delete docs/reviews and docs/upgrades, sweep every inbound reference

The twelve review reports and the Python 3.14 handoff doc held only closed
findings, and sat at the same directory level as the two live documents. They
are removed rather than moved to a docs/history/ subtree: the only real argument
against deleting them was that §14 cites their finding ids bare and never
re-explains them, and §15 (previous commit) answers that directly. Git is the
archive for the rest. docs/ now contains exactly ARCHIVE.md, ROADMAP.md, and
screenshots/.

The originals stay retrievable — the pre-deletion commit is
0780b07, and the §14 entry records the
git show incantation. Nothing was rewritten before deletion.

Swept every inbound reference the audit enumerated, plus the ones it did not:
CONTRIBUTING § Project layout (both directories dropped, screenshots/ added),
CONTRIBUTING § API conventions, CHANGELOG's L13/APIR-8 citation, and both
dependabot.yml D3 comments now point at ARCHIVE §15. Inside §14, 59
docs/reviews/ and 7 docs/upgrades/ path prefixes were stripped so the entries
name the reports as documents rather than as paths that no longer resolve, with
a note at the top of §14 sending the reader to §15. Fixed the dead
claude-md-compliance-review.md link (a filename that never existed). Left one
docs/upgrades/ mention deliberately: the 2026-07-25 entry's record of what
CONTRIBUTING's layout listing omitted is a statement about that date, marked
'(as it then was)'.

Verified no workflow, test, or source file referenced either directory, and that
the four '§ Build performance' cross-references are by heading name and survive
that section's move.

Added the dated §14 entry recording all of it, including that docs/history/ was
considered and rejected, and two corrections to the audit: twelve entries were
misfiled under Build performance (not fourteen — the other two are that
section's own sub-headings), and there are 42 remote branches with 36 prunable
(not 39/33).
@tyler-rich
tyler-rich deleted the claude/frontend-test-harness-el4nev branch July 31, 2026 04:59
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