Skip to content

test(web-ui): cover api.ts request layer + consolidate split Jest roots (#774) - #881

Merged
frankbria merged 1 commit into
mainfrom
test/frontend-contract-consolidate-774
Jul 23, 2026
Merged

test(web-ui): cover api.ts request layer + consolidate split Jest roots (#774)#881
frankbria merged 1 commit into
mainfrom
test/frontend-contract-consolidate-774

Conversation

@frankbria

Copy link
Copy Markdown
Owner

Closes #774 — Frontend contract test-trust (P3.3).

What & why

The 1225-line src/lib/api.ts request layer is module-mocked in every other suite, so wrong-endpoint / renamed-param / reshaped-body drift passes green everywhere. The web-ui/e2e Playwright suite was orphaned (no CI job, fully-mocked backend, drifted fixtures), and 7 test files were duplicated across two divergent Jest roots.

Acceptance criteria

  • A msw/axios-stub test pins method+URL+params+body for critical endpointssrc/__tests__/lib/api.contract.test.ts swaps the shared client's adapter for a capturing stub (runs after axios applies the auth interceptor, URL building, and body serialization) and asserts method+URL+params+body for workspaceApi, tasksApi, eventsApi, plus the Bearer-token request interceptor. Axios-stub over msw: msw was installed but unwired, and the repo already tests the interceptors off the axios instance — no new jsdom/polyfill infra.
  • web-ui/e2e wired to CI against a real backend OR deleteddeleted (web-ui/e2e/ + web-ui/playwright.config.ts + test:e2e* scripts + the now-transitive @playwright/test devDep). The real-backend Playwright harness at tests/e2e/ is already CI-wired (e2e-browser-smoke + e2e-browser-full, [P6.8.5] Rewrite Playwright browser E2E suite against current Phase-3+ UI #684/feat(e2e): rewrite Playwright browser suite for Phase-3+ UI (#684) #703) and covers the same pages, so the mocked orphan was pure dead weight.
  • The two Jest roots consolidated under src/__tests__ — legacy web-ui/__tests__ root removed; jest.config.js ignore patterns updated (dropped the dead /e2e/ ignore).

Key decision: the 7 "duplicates" were divergent, not redundant

Picking one copy per pair by recency would have silently dropped half the coverage — the opposite of a test-trust fix. 6 of 7 pairs test disjoint concerns:

Component copy A copy B
PRDHeader header actions (upload/discovery/generate/loading) stress-test button (#562)
TaskDetailModal execute/mark-ready/fetch/action-buttons timestamp/tooltip/transition-guidance/GitHub (#565)
TaskCard full card (click/cost/selection/a11y/status variants) status-badge tooltip
PRStatusPanel PROOF9 merge gate (#731) CI checks / SWR / review badges
useTaskStream event dispatch stream-ticket wiring (#745)
AppSidebar nav items / session badge / Capture Glitch logout control (#336)

Both copies are kept under focus-suffixed names (X.actions/.tooltip/.checks/.events/.navigation.test), matching the repo's existing multi-file-per-component convention (TaskBoardView.githubImport.test.tsx, …). Only AssociatedTasksSummary (src was a strict superset) collapsed to one file.

Verification

  • npm test95 suites, 1065 tests, all green (baseline 1052; +13 from the new contract test, −4 from the one redundant collapse).
  • npm run lint → clean · npm run build → succeeds.
  • npm ci --dry-run resolves (lockfile in sync after the devDep removal; @playwright/test remains transitively via next).

Known limitations

  • The contract test pins the critical/most-drift-prone endpoints, not all 24 api objects — the pattern is trivially extensible if a specific endpoint later warrants pinning.

…ts (#774)

Frontend test-trust hardening (P3.3):

1. api.ts contract test — src/__tests__/lib/api.contract.test.ts pins
   method+URL+params+body for the critical endpoints (workspace/tasks/events
   + the auth request interceptor) via an axios-stub adapter, so wrong-endpoint
   / renamed-param / reshaped-body drift fails here instead of passing green
   under the module mocks every other suite uses.

2. Orphaned e2e suite removed — web-ui/e2e (no CI job, fully mocked backend,
   drifted fixtures) and its web-ui/playwright.config.ts are deleted. The
   real-backend Playwright harness at tests/e2e/ (CI-wired: e2e-browser-smoke
   + e2e-browser-full, #684/#703) already covers these pages. Dropped the dead
   test:e2e* scripts and the now-transitive @playwright/test devDep.

3. Jest roots consolidated under src/__tests__ — the legacy web-ui/__tests__
   root is gone. The 7 "duplicated" files were divergent, not redundant: 6
   pairs test disjoint concerns (e.g. PRDHeader header-actions vs stress-test
   button; TaskCard full-card vs status-tooltip; PRStatusPanel merge-gate vs
   CI/SWR/review). Kept both copies under focus-suffixed names
   (X.navigation/.actions/.events/.checks/.tooltip.test), matching the repo's
   existing multi-file-per-component convention — no coverage dropped. Only
   AssociatedTasksSummary (src ⊇ root) collapsed to a single file.

Suite: 95 → 95 suites, 1052 → 1065 tests, all green. Lint + build pass.

Closes #774
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @frankbria's task in 12m 35s —— View job


GLM precision bug review — complete ✅

Scoped to concrete defects only (logic errors, null/unhandled paths, security, data loss, race conditions, breaking contract changes, resource leaks). Style/architecture/naming/coverage are covered by the separate general review — not commented here.

  • Review jest.config.js ignore-pattern change
  • Review package.json script/dep removal (check CI workflows referencing them)
  • Review new api.contract.test.ts for assertion correctness
  • Review modified PRStatusPanel.test.tsx / TaskCard.test.tsx
  • Review added PRStatusPanel.checks.test.tsx / TaskCard.tooltip.test.tsx
  • Confirm renames are pure moves (no dropped tests)

✅ GLM review: no defects found.

What I verified against the checked-out code:

  • api.contract.test.ts — Every pinned assertion matches the real web-ui/src/lib/api.ts: method, URL, params, and body for workspaceApi/tasksApi/eventsApi, including init's detect ?? true default, startExecution's {} body + execute: true param, getRecent's default limit: 20, and stopExecution's encodeURIComponent. The capturing adapter runs after axios's request interceptor + body serialization, and the auth wiring is real: interceptor at api.ts:134-140 calls config.headers.set('Authorization', Bearer ${token}) from the same localStorage store that setToken writes (auth.ts:28-41), so the Bearer/no-token assertions are valid.
  • jest.config.js — Dropping /e2e/ is safe: web-ui/e2e/ is deleted and no other e2e test path exists under web-ui; the CI-wired tests/e2e/ lives at repo root, outside web-ui's Jest <rootDir>, so Jest never scanned it even with the old ignore. The test-helpers ignore was just re-scoped to the new path (still a substring match, still effective).
  • package.json — No CI breakage. frontend-tests runs npm run test:coverage (script kept). The e2e-browser-smoke/e2e-browser-full jobs use working-directory: tests/e2e with their own npm ci + npx playwright — they never invoke web-ui's removed test:e2e* scripts. @playwright/test remains in the lockfile (optional/peer via next), so npm ci resolves.
  • Modified/added suites (PRStatusPanel.test.tsx, PRStatusPanel.checks.test.tsx, TaskCard.test.tsx, TaskCard.tooltip.test.tsx) — assertions are correctly oriented (disabled/enabled, presence/absence, call args, SWR keys); no vacuous or inverted checks.
  • security-headers.test.js — import path ../../security-headers is correct for its new src/__tests__/ location.

@frankbria
frankbria merged commit 6543904 into main Jul 23, 2026
10 of 11 checks passed
@frankbria
frankbria deleted the test/frontend-contract-consolidate-774 branch July 23, 2026 03:37
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.

[P3.3] Frontend contract test-trust: cover src/lib/api.ts and consolidate split test roots

1 participant