Repository navigation
REQ-VISUALIZATION-005: execute the real M1/M2 DOM render path in the Pages smoke test - #407
Merged
zendev-acceptor[bot] merged 2 commits intoSep 10, 2026
Conversation
…Pages smoke test The focused M1/M2 Pages regression added by PR #368 only fetched the JSON artifacts and inspected the parsed objects; it never executed docs/index.html or observed the rendered DOM, so a broken DOM-population callback would still leave every assertion green. Load the real docs/index.html into jsdom with runScripts: "dangerously", bind window.fetch to the local static server already used by this test, and wait for the M1/M2 panels to leave their loading state before asserting on rendered DOM text. Add desktop (1280px) and narrow (360px) viewport smoke cases that instantiate window.innerWidth before render. Add a negative control per milestone that bypasses only the DOM-population write (via a targeted string mutation of the render script) while the JSON artifact and its URL string stay intact, and confirms the population step is what proves the regression — the same assertion the positive test relies on. Add jsdom + @types/jsdom as devDependencies; no other runtime or build change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Updates the sole REQ-VISUALIZATION-005 row to name this PR alongside the prior PR #244/#368 evidence, per the ledger's "name every pull request that contributed" rule. STATUS stays IMPLEMENTED: this PR strengthens the proof of an already-satisfied acceptance criterion, it does not newly satisfy one. MERGE_COMMIT is left empty since this PR has not merged yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
ACCEPT — head revision 93d1798f6378857a952172f9fc27d02a679ee490.
Verified independently, not taken from the PR body:
- Checks green at head.
typescript,build-and-test,policy-guard, and bothmergeability(write-mergeability-status) runs areSUCCESS/passat93d1798. Themergeabilitystatus text ("merges cleanly into the base branch (blocked)") reflects the pending-review gate only (mergeStateStatus: CLEAN,mergeable: MERGEABLE) — confirmed againstscripts/tests/test_mergeability.py's documented meaning of the GitHubblockedstate, not a conflict or staleness. - Re-executed all required commands myself on a worktree of the PR head:
npm ci,npm run typecheck(clean),npm test(554/554 passed, 40 files, matching the PR's claim),npm run build(succeeded),dotnet build --configuration Release(0 warnings/errors),dotnet test --configuration Release(45/45 passed). Also re-ranpython scripts/implementation_status.py --checkandpython scripts/status_lint.py --repo drevendev/trade_simulation --self 407 --base origin/master— both passed with the exact counts the PR claimed (29/49, 29 agreeing rows). - Acceptance criteria (Issue #402), checked against the diff, not the prose:
- Criterion 1/2:
loadDom/renderPageload the realdocs/index.htmlviajsdomwithrunScripts: "dangerously", bindwindow.fetchto the test's local static server, and the two "executes the real … render path" tests assert on#m1-preview-body/#m2-preview-bodytextContentsourced from the fetched JSON. Confirmed against the actualdocs/index.htmlrender script (lines 506-535, 546-576): the DOM-population markers the tests key off exist exactly where claimed. - Criterion 3: the desktop/narrow tests set
window.innerWidthviabeforeParseand assertgetComputedStyle(...).display !== "none"plus populated body text at both widths — a real instantiated viewport, not a re-fetch of JSON as the old tests did. - Criterion 4:
bypassM1Population/bypassM2Populationdo a targeted string replace of the exact `innerHTML = `` marker (single occurrence, verified against the live HTML — the catch-path uses a different literal shape so it's untouched), leaving JSON/URL intact. The negative-control tests assert the milestone tag does update (proving fetch ran) while the body stays on the loading placeholder (proving population didn't) — this is a real, targeted regression detector, not tautological. - Criterion 5: confirmed above.
- Criterion 1/2:
- Scope. Diff is confined to
src/diagnostics/m1m2-pages-render.test.ts,package.json/package-lock.json(jsdom + @types/jsdom, devDependency only, all resolutions point atregistry.npmjs.org,npm auditclean), and the ledger pair — all within Issue #402's declared scope. No.github/workflows/**,AGENTS.md, ordocs/zendev/**touched. - Ledger row.
REQ-VISUALIZATION-005's row correctly leavesMERGE_COMMITblank for this self-citing, not-yet-merged PR (the documentedstatus_lintself-pull exception) and keepsISSUEpinned to #243 while naming #407 in evidence, consistent with the ledger's existing convention. - No tests deleted/weakened. The old tests this replaces ("verifies M1/M2 rendering updates DOM elements correctly", the two fake "viewport" tests) were exactly the gap Issue #402 identified — they fetched JSON and inspected objects instead of rendering. The replacements are strictly stronger and add two new negative controls; nothing was removed without a stronger equivalent.
- No secrets, credentials, or local paths in the diff. policy-guard's scope/handoff/ledger sub-checks all passed at this head.
No standing refusal on this PR (first review, no prior reviews/comments), no other account holds the merge. Merging.
zendev-acceptor
Bot
deleted the
claude/issue-402-m1m2-dom-render-smoke
branch
September 10, 2026 21:33
4 tasks done
zendev-author Bot
pushed a commit
that referenced
this pull request
Sep 14, 2026
Updates the existing REQ-VISUALIZATION-005 row in place rather than adding a second one: STATUS stays IMPLEMENTED per the researcher's 2026-09-11 triage on #423 (the repair hardens the smoke and exposed no normal-view failure), PR moves to this pull request, MERGE_COMMIT is cleared for backfill_merge_commits.py, and EVIDENCE now names every pull request that contributed to the requirement -- #244, #368, #407, #421 and #479 -- along with what this one proves and what it deliberately leaves out of scope. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Sep 14, 2026
zendev-acceptor Bot
pushed a commit
that referenced
this pull request
Sep 15, 2026
…dability smoke (#479) * REQ-VISUALIZATION-005: observe ancestor opacity in the Pages readability smoke `isReadable()` combined Playwright's `isVisible()` with the target node's own computed `opacity`. CSS `opacity` applies to an element and all of its contents but is not inherited, so `#m1-preview { opacity: 0; }` composites the populated `#m1-preview-body` away while leaving its own computed opacity at "1" and its bounding box intact. The helper reported that fully invisible body as readable. Replace the single-node read with `effectiveOpacity()`, which multiplies the computed opacity along the ancestor chain, and add the focused negative control Issue #423 specifies: inject `#m1-preview { opacity: 0; }` after navigation, leaving the JSON artifact, fetch URL and render callback untouched, and assert that DOM population still succeeded, that `isVisible()` and the body's own computed opacity both still read as before, and that `isReadable()` now returns false while the untouched M2 panel stays readable. Verified by reverting the helper to its previous single-node form: the new control fails ("expected true to be false") and passes with the fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * ledger: record PR #479 against REQ-VISUALIZATION-005 Updates the existing REQ-VISUALIZATION-005 row in place rather than adding a second one: STATUS stays IMPLEMENTED per the researcher's 2026-09-11 triage on #423 (the repair hardens the smoke and exposed no normal-view failure), PR moves to this pull request, MERGE_COMMIT is cleared for backfill_merge_commits.py, and EVIDENCE now names every pull request that contributed to the requirement -- #244, #368, #407, #421 and #479 -- along with what this one proves and what it deliberately leaves out of scope. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5 <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.
Closes #402
Achieved outcome
src/diagnostics/m1m2-pages-render.test.tsnow executes the realdocs/index.htmlM1/M2 rendering path in a jsdom document and asserts on the actual rendered DOM after the preview fetches resolve, instead of only fetching the JSON artifacts and inspecting the parsed objects. A broken DOM-population callback now fails the regression; two negative-control tests prove that detection directly.Tested revision
93d1798f6378857a952172f9fc27d02a679ee490Changed artifacts
src/diagnostics/m1m2-pages-render.test.ts— rewritten to loaddocs/index.htmlinto jsdom (runScripts: "dangerously"), bindwindow.fetchto the test's existing local static server, and wait for the M1/M2 preview panels to leave their loading state before asserting on rendered#m1-preview-body/#m2-preview-bodytext. Adds desktop (1280px) and narrow (360px) viewport smoke cases that instantiatewindow.innerWidthbefore render. Adds one negative-control test per milestone that bypasses only the DOM-populationinnerHTMLwrite (via a targeted string mutation of the render script, insertingreturn;immediately before that assignment) while the JSON artifact and its fetch URL stay untouched, and confirms the milestone tag still updates (proving the fetch/.then()ran) while the body keeps its loading placeholder (proving the population step was skipped) — the same assertion the positive tests rely on to detect a real regression. Retains the pre-existing JSON-shape/artifact-existence/panel-markup tests, which were already legitimate.package.json,package-lock.json— addjsdomand@types/jsdomas devDependencies (test-only; no production/runtime dependency change).docs/spec/implementation_status.csv,docs/spec/IMPLEMENTATION_STATUS.md— update the soleREQ-VISUALIZATION-005ledger row to name this PR alongside prior evidence (PR Implement REQ-VISUALIZATION-005: M2 Milestone Preview with tick/phase/reconciliation visibility #244, PR PR #354 merged without the required M1/M2 DOM render smoke regression #368) and regenerate the rendered table.STATUSstaysIMPLEMENTED; this PR strengthens proof of an already-satisfied acceptance criterion rather than newly satisfying one.MERGE_COMMITis left empty since this PR has not merged yet.Acceptance criteria
From Issue #402:
loadDom/renderPageusing jsdom withrunScripts: "dangerously"against the realdocs/index.html.#m1-preview-body/#m2-preview-bodytextContentin the two "executes the real ... render path" tests.window.innerWidth(1280 / 360) before the page renders and assert both the panel's computeddisplayis notnoneand the rendered body text is populated.passed— see Checks below.Checks
npm run typechecknpm testm1m2-pages-render.test.tsnpm run buildvite buildsucceededpython scripts/implementation_status.py --checkpython scripts/status_lint.py --repo drevendev/trade_simulation --self 407 --base origin/masterdotnet build --configuration Releasedotnet test --configuration ReleaseNot checked
getComputedStyleassertions are limited to non-layout properties (display) rather than actual pixel geometry. This is a reasonable bound for a unit-level Pages smoke test, but it does not prove pixel-level visual legibility at either width — the existing CSS has no viewport-conditional rule hiding the M1/M2 panels themselves (only.boardreflows at ≤760px), so this gap does not hide a known defect.REQ-MARKET-005/REQ-ACCEPTANCE-004dependency gate).Assumptions and unknowns
ISSUEcolumn to keep naming the requirement's originating Issue (REQ-VISUALIZATION-005: Extend M2 Milestone Preview with phase/reconciliation visibility #243) rather than the QA-remediation Issue (PR #368 still does not execute the M1/M2 DOM render smoke path #402) that produced this evidence; I followed the existing pattern already used for other PARTIAL→evidence-strengthening rows in this ledger (e.g.REQ-MARKET-005,REQ-ACCEPTANCE-004) of naming every contributing PR inEVIDENCEwhile keepingISSUEpinned to the requirement's own Issue.return;before the targetinnerHTMLassignment) is an acceptable simulated-regression technique versus a reviewer's preferred approach (e.g. a second static HTML fixture file). I chose the in-test string mutation to avoid adding a parallel, driftable fixture that could silently stop mirroringdocs/index.html.Highest-risk area for review
The
beforeParsefetch shim (window.fetch = (input, init) => fetch(new URL(input, baseUrl).toString(), init)) is what makes the page's real inlinefetch("m1-preview.json")calls resolve inside jsdom. If a reviewer wants stronger confidence this isn't accidentally bypassing something the browser's ownfetchdoes differently, that binding plus thewaitForTextpolling helper (used to detect when the async.then()render callback has actually run, rather than assuming a fixed delay) are the places to scrutinize first.Remaining gate
None known.
status:needs-reviewis being set on Issue #402 and this PR is otherwise ready for ACCEPTOR review.