test(console): render the panes - #184
Merged
Merged
Conversation
Eleven persona PRs today, and every bug that reached the live console lived in the one layer nothing could test: a `ref` callback that looped the renderer to a blank page, a form that opened empty because a selection was never passed to it, a screen that never came back because its mode was decided once, a field asking for an identifier the context did not have. The models under all of them — `identity-graph`, `profile-entries`, `persona-flow`, `persona-candidates` — passed throughout, because each was correct. Rendering is the only thing that sees the rest. `tests/harness/` adds module hooks and a DOM so `node --test` can mount a pane, with no change to how tests are run or written elsewhere. **The hooks** resolve a `./thing.js` import to `thing.tsx` — the sources use TypeScript's `Bundler` resolution, which the bundler honours and Node does not — and transform JSX with esbuild. Not `typescript`: this repo is on TypeScript 7, whose JS API is the native port's small surface, with no `transpileModule` and no `JsxEmit` on it. A hook written against the 5.x compiler API fails with an undefined enum and names nothing. **The fake agent** answers by task URI, returns the relay's real envelope so a pane that mishandles a real response cannot pass, and **throws** on a task the test did not name — a pane asking something unexpected is exactly what a test should notice, so that is a failure rather than an empty answer. Nine tests, each written against the symptom a person saw rather than the fix, so they keep meaning something if the fix is rewritten. Mutation-checked against three of the real bugs: restoring the scrape-from-a-ref fails three of them, dropping the create offer fails one, ignoring the selection fails one. Two harness details worth knowing, both of which quietly made a test lie before they were fixed: a checkbox must be clicked rather than have `checked` assigned, because React reads the click; and text matching takes the *innermost* element, because document order returns an ancestor and clicking a card where a test meant a row inside it selects the wrong thing and then asserts against the wrong screen. Signed-off-by: Glenn Gore <glenn.g@affinidi.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.
Eleven persona PRs today, and every bug that reached the live console lived in the one layer nothing could test:
refcallback that looped the renderer to a blank page (#179)The models under all of them —
identity-graph,profile-entries,persona-flow,persona-candidates— passed throughout, because each was correct. Rendering is the only thing that sees the rest.What this adds
tests/harness/— module hooks and a DOM sonode --testcan mount a pane. Nothing changes about how tests elsewhere are run or written.The hooks do two things that are not obvious:
./thing.jsimport tothing.tsx. The sources use TypeScript'sBundlerresolution, which the bundler honours and Node does not; existing tests sidestepped it by importing../src/.../thing.tswith the real extension, which a component cannot do because its own imports are written the other way.typescript. This repo is on TypeScript 7, whose JS API is the native port's small surface —transpileModuleandJsxEmitare simply not on it, and a hook written against the 5.x compiler API fails with an undefined enum that names nothing.The fake agent answers by task URI, returns the relay's real envelope (
{ok, result: {kind: "accepted", …}}) so a pane that mishandles a real response cannot pass, and throws on a task the test did not name — a pane asking something unexpected is exactly what a test should notice, so that is a failure rather than an empty answer.The tests
Nine, each written against the symptom a person saw rather than the fix, so they keep meaning something if the fix is rewritten. Every negative is paired: "a context with no identifier offers to create one" sits beside "a context with identifiers lists them", because the first alone passes against a form that always offers to create.
Mutation-checked against three of the real bugs:
ref→ 3 tests fail (the loop takes the whole pane down, which is what it did)Two harness details that quietly made a test lie
Both cost me a false pass before they were fixed, and both are written down:
checked. React reads the click. A hand-set value plus a syntheticchangelooks like a tick to the test and like nothing to the component — the test passed while proving nothing about the handler.Cost
One devDependency (
happy-dom), scoped to the extension package. The extension'stestscript gainstsc -b, matchingpackages/core's, because the render tests import through the real package and need itsdist.Verification
npm run lint,npm run build,npm test— 865 across four workspaces (extension 260 → 269). All sixci.ymlassertions against the real build.