Release/v1.0.0#15
Merged
Merged
Conversation
…ffer Phase 1 of broader test coverage. The DB layer (better-sqlite3) is built for Electron's ABI and can't load under vitest's node env, so these mock the DB/OpenAI boundaries with vi.mock and test the pure logic + edge cases (40 new tests, 20→60): - models: preset resolution + override precedence, isReasoningModel, reasoningParam (only attached to reasoning models), reasoningEffort defaults, Custom-divergence inputs. - questions (classify): defensive defaulting (fails closed on uncertainty), input-text echo, malformed-JSON behavior. - answer: per-length max_output_tokens caps (220/800), prompt assembly (format, type, pronunciation, context tagging, no-context note), streamed delta/usage/meta events. - codingMode: multi-image buffer cap at 8 (drops oldest), clear, and solve-all-then-clear. Also: vitest.config now mirrors the tsconfig path aliases (@shared/@main/@Renderer) so modules with value imports from @shared (e.g. EVENTS) are testable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
More Phase 1 coverage (60→77 tests): - parsing: resume/JD/company defensive defaulting (empty → safe defaults, partial → fill rest, overview defaults to "" not []), and the 24k input cap sent to the model. - Extract the Cue Card answer-history logic out of Overlay.tsx into answerCards.ts (makeCard/patchLast/addCard/removeCard/toggleCollapsed) so it's unit-testable, and cover the edge cases: history OFF replaces, history ON collapses + keeps prior (answers preserved), patchLast no-ops on empty + doesn't mutate, remove/toggle by id. Overlay.tsx now imports these (behavior unchanged). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 2 foundation — runs against the BUILT app (real main + SQLite + IPC) for what unit tests can't reach. You run it locally; CI-safe without a key. - playwright.config.ts + e2e/fixtures.ts: launch out/main/index.js via _electron, resolve the dashboard window (the one without ?view=), auto-skip the first-run tour, load .env, and a key-gated `hasKey`/`setApiKey` helper. - e2e/smoke.spec.ts: app launches, dashboard renders, navigation. - e2e/data-integrity.spec.ts (no key): drives window.api against the real DB — interview-delete FK cascade (the flagged gap), profile-delete cascade, and a model preset + per-task override round-trip. - e2e/live-openai.spec.ts (key-gated): load samples → real résumé parse + embeddings + RAG retrieval; structural assertions only. - src/main/index.ts: honor E2E_USER_DATA so tests use an isolated data dir (never the real user DB). No effect in normal use. - package.json: @playwright/test + dotenv devDeps, test:e2e / test:e2e:only scripts. - e2e/README.md: setup, tiers, coverage, and gotchas. gitignore Playwright output. NOTE: e2e specs are written but NOT yet executed here (no display/network in this env). Run `npm install && npx playwright install && npm run test:e2e` and we iterate on any selector/timing failures from the output. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ran the suite and fixed what was broken: - Playwright's _electron.launch() is broken on Electron 30+ (passes --remote-debugging-port=0, which Electron rejects — microsoft/playwright#39008). Replace it: the app opens a fixed CDP port via appendSwitch under BRAINCUE_E2E (src/main/index.ts), and the fixture spawns out/main/index.js directly + connects with chromium.connectOverCDP. - global-setup copies drizzle/ → out/main/drizzle so the built app finds its migrations (else: "no such table: settings"). electron-builder does this when packaging; a bare out/ run didn't. - Strip ELECTRON_RUN_AS_NODE from the spawned env (the Playwright runner sets it, which made Electron boot as plain Node → electron.app undefined). - Skip the guided tour by setting the flag then reloading (it auto-starts on mount and its full-screen overlay intercepted clicks). - Await Electron exit in teardown so the shared CDP port frees before the next test (fixes intermittent "target closed"). - Fix selectors/assertions: heading-scoped Settings checks; live test asserts via exposed APIs (loadSamples + reindexProfile) since window.api.rag isn't in the preload. Result: 7/7 pass — smoke + data-integrity (incl. FK cascade) and the live OpenAI tier (real résumé parse + embeddings, ~31s with the .env key). 77 unit tests still green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two utilities, excluded from the default run (testIgnore *.capture.spec.ts; opt in with E2E_CAPTURE=1): - screenshots.capture.spec.ts — drives the app to generate README screenshots. - audit.capture.spec.ts — logs console/page errors per route + first-run/empty-state snapshots (used to verify the app boots clean). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The two most likely real-world live failures were invisible and left the Cue Card stuck: - B1: when a detected question's answer stream threw (auth, quota, network, or a model-not-found), generateAnswer re-threw with only a log — no sessionError, and answerDone never fired, so the card spun forever. Now the non-abort catch broadcasts sessionError (clean, key-redacted) + answerDone before re-throwing. Also moved retrieve() (the embeddings call) inside the try so a failure there is surfaced too. - B2: a clean transcription WebSocket close (server drops after 401/quota, or a network drop with no 'error' event) only logged a warning while the mic kept streaming into a dead socket. Now it reports onError → the user is told to restart. Regression test (e2e/error-handling.spec.ts): launches with the key stripped (new noApiKey fixture option) so the first OpenAI call fails deterministically offline, and asserts both sessionError AND answerDone fire — i.e. the failure surfaces and the card stops spinning. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cleanup + GA polish for v1.0: - Remove the always-empty "expanded mode" meta panel (talking points / resume match / follow-up) from the Cue Card — that data was a permanent stub, so it rendered nothing. The streamed answer, risk warning, transcript, and audio meter stay. - Remove the unwired `rag:search` channel (constant + IPC-map section): it had no handler and no preload method. - a11y: Cue Card icon buttons get aria-labels; the Modal sets role="dialog"/aria-modal, moves focus in and restores it on close; the Ask box ignores Enter mid-IME-composition. - MockPage: inline error banner instead of blocking alert()s. - Coding-solve errors use normalizeOpenAIError (clean, key-redacted) not String(e). - HiDPI screen capture: factor in scaleFactor so small code text stays legible. - Cap the in-memory transcript (store + overlay) so long sessions don't grow unbounded. - CI: add a typecheck · test · build gate on push/PR. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First stable release. Bump package.json 0.9.0 → 1.0.0, add the MIT LICENSE file, and changelog/1.0.0.md (drives in-app "What's New" + APP_VERSION). Theme: reliability — live failures now surface instead of hanging — plus a11y/UX polish and dead-code cleanup. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A multi-agent review of the diff caught a real regression + polish items: - BLOCKER: the new Modal focus effect depended on `onClose` (a fresh inline arrow each render), so during a live session the Cue Card's per-frame re-renders (audio meter) re-ran it and yanked focus out of the settings dropdowns — and corrupted the focus-restore target. Now it reads onClose via a ref and depends only on `open`, so focus-in/restore happens once per open/close. - SHOULD: the realtime ws fires 'error' THEN 'close' for the same failure, so the new close→onError clobbered the specific message (e.g. 401) with the generic "disconnected" one. Now close skips it when a specific error already surfaced. - Nits: failed manual ask no longer leaves an unhandled rejection (renderer .catch) and keeps its transcript line; removed stale `rag:search` references in docs/09-MVP-PLAN.md and e2e/README.md; collapsed a leftover double blank line. typecheck · 77 unit · build · 7 e2e all green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.