deckhearth/test/components
Randall Stillwell 237870c17e convoy: render-test regression-lock for ScanDisambiguationDialog (PR #144)
PR #144 (`31da384`, 2026-06-13) shipped a runtime
`ReferenceError: useFocusTrap is not defined` to production because
the component called the hook without importing it. The sibling
`enable-no-undef-eslint-rule` convoy closes that bug class at LINT
time. This PR locks the same regression at RENDER time so the bug
would still fail CI even if the lint rule were dropped or disabled.

## What changes

- `test/components/ScanDisambiguationDialog.test.js` — 8 tests:

  1. `renders without crashing (PR #144 regression-lock)` — the
     direct lock-in. Mutation-tested: commenting out the
     `useFocusTrap` import causes all 8 tests to fail with the same
     `ReferenceError` shape that hit prod.
  2. `returns null when disambiguation is falsy`
  3. ARIA shape (`role`, `aria-modal`, `aria-labelledby`)
  4. One button per candidate with accessible labels
  5. `onPick` callback receives the selected candidate
  6. Vision-hint branch renders when provided
  7. Submitting state disables the "send for review" button
  8. `onCancel` callback fires on Cancel click

## Why vitest + jsdom and not Playwright smoke

| Path | Catches PR #144 | Setup | Runtime |
|------|-----------------|-------|---------|
| Playwright smoke | ✓ if disambiguation mounts in the smoke run | High (auth bypass, stable multi-candidate fixture image) | ~10s + browser |
| Vitest render | ✓ directly — render-throw → test fail | Low | <100ms |

Re-scoped the queued `scanner-disambiguation-smoke-test` task to the
vitest shape because a render test catches the exact same bug class
at 1/100th the cost and matches the existing `test/components/*.test.js`
pattern (`Modal.test.js`, `ScannedCardItem.test.js`, etc.). A Playwright
disambiguation smoke is still useful as integration-layer coverage and
is queued as `scanner-disambiguation-playwright-smoke`.

## Verification

- [x] `npm run test:run` — 26 files / 131 tests pass (up from 25/123)
- [x] Mutation test: with `useFocusTrap` import commented out, all 8
      tests fail with `ReferenceError`. With import restored, all pass.

## Test plan

- [ ] CI on this PR green
- [ ] Squash + merge
- [ ] Smoke test post-merge: scan a card that triggers disambiguation
      in prod and confirm no console errors (the original PR #144 bug
      shape)

## Convoy doc

`.convoys/scanner-disambiguation-render-test.md` documents D1 (cover
the early-return branch explicitly), D2 (`fireEvent` not `userEvent`),
D3 (do NOT mock `useFocusTrap` — the missing-hook is exactly what
we're locking), and the two queued follow-ups
(`add-component-render-smoke-pattern`, `scanner-disambiguation-playwright-smoke`).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 01:20:21 -05:00
..
DailyEmberWidget.test.js feat(design-system): redesign v2 #2 + #5 — sidebar pill, wordmark, Daily Ember (#103) 2026-06-04 10:59:44 -05:00
Layout.test.js refactor(layout): migrate 3 floating popovers to .glass-panel-strong (#124) 2026-06-04 16:25:14 -05:00
Modal.test.js feat(design-system): Liquid Glass redesign portfolio — foundation + primitives + Layout (#95) 2026-06-03 20:12:33 -05:00
ScanDisambiguationDialog.test.js convoy: render-test regression-lock for ScanDisambiguationDialog (PR #144) 2026-06-13 01:20:21 -05:00
ScannedCardItem.test.js test(scanner): cover redesign API and component surfaces (#47) 2026-05-27 14:28:04 -05:00
ScannerDestinationPicker.test.js Align UI copy: My Collection vs Lists (#54) 2026-05-29 09:53:40 -05:00
StatCard.test.js feat(design-system): redesign v2 #4 — StatCard primitive + dashboard wiring (#104) 2026-06-04 10:59:53 -05:00
ui-primitives.test.js feat(GlassSurface): add cornerLights prop (subtle | chrome | none) (#123) 2026-06-04 15:30:32 -05:00