From ceb9ca86bc7a003998c5eb013d881272323b7529 Mon Sep 17 00:00:00 2001 From: "Christopher S. Aondona" Date: Thu, 12 Nov 2026 12:58:18 +0100 Subject: [PATCH 1/7] test: allow full browser suite to run under Firefox and WebKit --- vitest.browser.config.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vitest.browser.config.ts b/vitest.browser.config.ts index c1e468d..ad34f2e 100644 --- a/vitest.browser.config.ts +++ b/vitest.browser.config.ts @@ -1,6 +1,14 @@ import { playwright } from "@vitest/browser-playwright"; import { defineConfig } from "vitest/config"; +// Main quality CI uses Chromium. The separate release QA workflow exercises +// the identical browser suite in Firefox and WebKit without changing defaults. +const requestedBrowser = process.env.THROUGHLINE_QA_BROWSER ?? "chromium"; +if (!["chromium", "firefox", "webkit"].includes(requestedBrowser)) { + throw new Error("Unsupported Throughline QA browser: " + requestedBrowser); +} +const browser = requestedBrowser as "chromium" | "firefox" | "webkit"; + export default defineConfig({ test: { css: true, @@ -9,7 +17,7 @@ export default defineConfig({ browser: { enabled: true, provider: playwright(), - instances: [{ browser: "chromium" }], + instances: [{ browser }], }, }, }); From 80ecedc75489e0a4db909a60f6f73da3bb89b8cb Mon Sep 17 00:00:00 2001 From: "Christopher S. Aondona" Date: Thu, 12 Nov 2026 12:58:31 +0100 Subject: [PATCH 2/7] test(ci): run release candidate browser regressions in Firefox and WebKit --- .github/workflows/release-qa-browsers.yml | 45 +++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .github/workflows/release-qa-browsers.yml diff --git a/.github/workflows/release-qa-browsers.yml b/.github/workflows/release-qa-browsers.yml new file mode 100644 index 0000000..4b35dd9 --- /dev/null +++ b/.github/workflows/release-qa-browsers.yml @@ -0,0 +1,45 @@ +name: Throughline release QA browsers + +# Additional, read-only release-candidate verification. The regular CI +# retains Chromium and the distributable/consumer checks. +on: + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: throughline-release-browser-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + cross-browser: + name: Browser regressions (${{ matrix.browser }}) + runs-on: ubuntu-latest + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + browser: [firefox, webkit] + steps: + - name: Checkout source + uses: actions/checkout@v6 + - name: Setup pnpm + uses: pnpm/action-setup@v6 + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 24 + cache: pnpm + cache-dependency-path: pnpm-lock.yaml + - name: Install locked dependencies + run: pnpm install --frozen-lockfile + - name: Verify lockfile unchanged + run: git diff --exit-code -- pnpm-lock.yaml + - name: Install tested browser and system dependencies + run: pnpm exec playwright install --with-deps ${{ matrix.browser }} + - name: Run the complete browser regression suite + env: + THROUGHLINE_QA_BROWSER: ${{ matrix.browser }} + run: pnpm test:browser:run From 05fefb62526aed97dc7010c56d47d07e89835fd7 Mon Sep 17 00:00:00 2001 From: "Christopher S. Aondona" Date: Thu, 12 Nov 2026 12:59:56 +0100 Subject: [PATCH 3/7] docs(qa): record post-v0.0.2 release verification evidence and open gates --- docs/release-qa-post-v0.0.2.md | 102 +++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 docs/release-qa-post-v0.0.2.md diff --git a/docs/release-qa-post-v0.0.2.md b/docs/release-qa-post-v0.0.2.md new file mode 100644 index 0000000..a8f0a2f --- /dev/null +++ b/docs/release-qa-post-v0.0.2.md @@ -0,0 +1,102 @@ +# Release-candidate verification — changes after v0.0.2 + +**Assessment date:** 2026-11-12 +**Outcome:** **INCONCLUSIVE — release acceptance is not established.** +**Execution boundary:** Verification and test tooling only. No production fix, merge, release, npm stage, tag, or approval. + +## 1. Exact scope + +- **Published baseline:** signed `v0.0.2` tag, commit `ab62dd02661701bb2e26014732f765c73bd4e9f7`. +- **Candidate observed:** `main` at `26d4e81756e28a6c28ac9f0c4b3dbc2e86b6f8c9` (post-PR #30). +- GitHub `v0.0.2...main` reports **251 commits**. This is the source comparison, not a claim of 251 independently reviewed commits. +- Includes reference traces, UI shell, scene projection, viewport/zoom, hierarchy, scenarios and explanations, Remark/MDX, packed framework/Markdown integrations, adaptive footer and captions, persistent workflow trail, opt-in step sounds and opt-in speech narration. +- `package.json` remains at version `0.0.2`; this is not a new registry release candidate or published build. + +The source architecture, API, `AGENTS.md`, `RELEASING.md`, `docs/release-hardening.md` and applicable acceptance gates govern this verification. Private planning materials are not copied into this public repository. + +## 2. Checks actually observed + +The exact candidate commit has a **successful GitHub Actions push run**, [Throughline CI #43212453210](https://github.com/0xbuffdev/throughline/actions/runs/43212453210), on 2026-11-12. The run's job and decoded logs were inspected. + +| Check | Observed result | +| --- | --- | +| Node 24, pnpm 11.2.2, frozen lockfile, unchanged lockfile | Passed | +| Public-source boundary audit, workflow YAML parse | Passed | +| TypeScript typecheck; playground typecheck and Vite build | Passed | +| Unit/compiler suite | **235 passed, 33 files** | +| Chromium browser suite | **82 passed, 14 files**, headless Chrome for Testing 158 | +| Distributable exports, declarations, build smoke checks | Passed | +| Runtime and peer licenses | Passed | +| Packed Node, TypeScript, React SSR and MDX consumers | Passed | +| Packed Vite React SSR/hydration, keyboard/touch/mobile | Passed | +| Isolated Fumadocs, Next.js and Astro consumers | Passed | +| `react-markdown`, `mdx-bundler`, `markdown-to-jsx` consumers | Passed | +| Firefox and WebKit browser regression suites | **Not established at report creation; see QA workflow on this PR** | +| Real audio output, physical devices, screen readers, real documentation app | **Not executed / not evidenced here** | + +**Provenance:** The checks above were executed by the linked CI runner, not in a separate local checkout. The local execution environment had no route to clone GitHub or install repository dependencies; no unexecuted command is counted as a pass. The additional browser workflow in this PR runs the **same 82-test suite** under Firefox/WebKit on GitHub-hosted runners; verify its actual conclusions before updating this record. + +## 3. Acceptance coverage and limitations + +| Area | Automated evidence | Limit / remaining work | +| --- | --- | --- | +| Version-1 compatibility, compiler limits, deterministic frames and seek | Unit fixtures, baseline-contract, snapshot/projection tests | Compare known fixture outputs with the prior published package in a clean external consumer if an exact binary-compatibility decision is needed | +| Reference cases and truthful causal/transfer events | Reference and scenario tests | Human comprehension comparison V-10 not done | +| Responsive layout and visual presentation | Chromium DOM geometry, dense graphs, 260–420px embeds, titles/controls, bounded caption details | Human visual review on Firefox/WebKit/Safari, text zoom, real mobile devices | +| Keyboard, touch, focus, inspector, fullscreen and reduced motion | Chromium/browser and packed Vite smoke checks | NVDA/JAWS/VoiceOver/TalkBack validation and keyboard-only manual audit | +| Narration and sound ownership/lifecycle | Browser tests with mocked Web Speech and Web Audio boundaries | Real voice availability, permissions, quality, interruption and speaker output remain unverified | +| React, SSR, Markdown/MDX and deployment compatibility | Locked disposable consumers and built distributable | No validation of the live documentation app or deployed host integration | +| Security, inert source, source-size and work limits | Source audit, parser tests, literal MDX/Remark and pack checks | Serialized external traces are not exhaustively validated by the player; host must validate untrusted serialized inputs | +| Performance | Diagnostic dense-layout samples in existing tests | No calibrated, repeatable thresholds or cross-device memory/latency acceptance | +| Licenses and distribution | CI license/package/source checks | Historical source rights and public Git-history exposure review are separate | + +## 4. Findings (absence of evidence is not a reproduced implementation defect) + +**QA-01 — P1 / release gate:** V-10 real-participant comprehension study is unverified. Compare matched static and interactive material on structure, transfers and failure causes; record recruitment, tasks, scoring, raw anonymized results, and limitations. Do not invent participants or equate visual approval with comprehension. + +**QA-02 — P1 / release gate:** Real speech, screen-reader and physical-device tests are unverified. Mocked `speechSynthesis` verifies control flow but not speech intelligibility, hardware interruption behavior, browser audio permission, queue interaction with third-party players, or mobile operating-system assistive technology. Manually test opt-in, pause/resume, seeking, same-step restart, two simultaneously mounted players, source changes, unmount and silent fallback. + +**QA-03 — P1 / integration gate:** Locked fixture builds do not verify the actual documentation application, its plugin order, rendered MDX pages and React bridge. The separately owned documentation integration is required before claiming end-to-end docs acceptance. + +**QA-04 — P2 / browser coverage:** Initial green CI ran Chromium only. This PR adds an opt-in browser selector and independent Firefox/WebKit matrix over the **existing full browser suite**. CI execution on the PR must be inspected; an installed browser or a triggered workflow alone does not constitute a pass. + +**QA-05 — P2 / performance evidence:** Existing single-run layout/heap diagnostics do not establish repeatable thresholds. Collect warm and cold samples on fixed hardware, at small/moderate/near-limit graph sizes and 320/720px widths. Record median, tail, heap, layout crossings and version deltas; investigate meaningful regressions before setting a gate. + +**QA-06 — P1 / design-decision gate:** Proposed Markdown/Remark and hierarchical group compatibility decisions must receive explicit maintainer acceptance. A merged source PR or a merged proposal does not change the document's own proposal status. + +**QA-07 — P1 / source-history and publication gate:** Historical public-source references and distribution rights must be reviewed separately. Update SemVer/changelog, verify package archive, and follow the signed-tag/manual staged-publication process only after authorized review. The published `0.0.2` version cannot be reused for a new package. + +These findings describe **unclosed verification/release gates**. The checks inspected did not establish a reproducible regression defect in the reviewed candidate. **Do not infer absence of defects from passing tests.** + +## 5. Reproducible retest instructions + +On the exact reviewed candidate with Node 24+, pnpm 11.2.2 and a clean lockfile: + +```sh +pnpm install --frozen-lockfile +pnpm audit:source +pnpm typecheck +pnpm preview:typecheck +pnpm preview:build +pnpm test:run +pnpm exec playwright install --with-deps chromium firefox webkit +pnpm test:browser:run +THROUGHLINE_QA_BROWSER=firefox pnpm test:browser:run +THROUGHLINE_QA_BROWSER=webkit pnpm test:browser:run +pnpm build +pnpm audit:licenses +pnpm audit:pack +pnpm audit:browser +pnpm audit:frameworks +pnpm audit:markdown-hosts +``` + +In each of Chromium, Firefox, WebKit and on actual devices, review the source-backed playground (`pnpm dev`) at 260, 300, 320, 360, 375, 768, 960 and 1600px available widths. Confirm no clipped toolbar controls, no horizontal overflow, readable node labels, stable diagram/control positions when long explanations expand, consistent contrast, reduced motion and keyboard focus. Test both themes, two audio controls, no audio, narration only and sonification only. Inspect screenshot differences as evidence rather than silently updating snapshots. + +Perform keyboard-only and screen-reader passes on the caption disclosure, timeline, chapter selector, entity selector, fullscreen failure, scenario changes, status announcements and narration errors. Test with 200% and 400% page zoom, high contrast and device-level reduced-motion settings. Document browser/OS/device/assistive-technology versions, exact inputs and observed outcomes. + +For reproducible bugs, record the fixture, preconditions, numbered actions, expected behavior, observed behavior, severity and a screenshot/log or trace reference. Separate regressions from `v0.0.2`, existing issues and infrastructure failures. + +## 6. Decision and next actions + +**Result: INCONCLUSIVE / NOT CLEARED FOR RELEASE.** The candidate's standard CI is green. The extra cross-browser checks and manual/human/integration/performance/governance gates have no completed evidence in this report. Review the QA workflow outcomes, address any defects on separate production-fix PRs, retest the exact new revision, and close or explicitly re-scope the remaining gates through maintainer review before preparing a signed package release. This QA PR does not approve, merge or publish anything. From 8307f9e854347ab1aa86b26348783ba9ad345e43 Mon Sep 17 00:00:00 2001 From: "Christopher S. Aondona" Date: Thu, 12 Nov 2026 13:05:13 +0100 Subject: [PATCH 4/7] docs(qa): record reproducible WebKit failure and full three-browser results --- docs/release-qa-post-v0.0.2.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/release-qa-post-v0.0.2.md b/docs/release-qa-post-v0.0.2.md index a8f0a2f..5bf6e3c 100644 --- a/docs/release-qa-post-v0.0.2.md +++ b/docs/release-qa-post-v0.0.2.md @@ -1,7 +1,7 @@ # Release-candidate verification — changes after v0.0.2 **Assessment date:** 2026-11-12 -**Outcome:** **INCONCLUSIVE — release acceptance is not established.** +**Outcome:** **FAIL — one repeatable WebKit layout assertion fails and release acceptance is not established.** **Execution boundary:** Verification and test tooling only. No production fix, merge, release, npm stage, tag, or approval. ## 1. Exact scope @@ -31,10 +31,12 @@ The exact candidate commit has a **successful GitHub Actions push run**, [Throug | Packed Vite React SSR/hydration, keyboard/touch/mobile | Passed | | Isolated Fumadocs, Next.js and Astro consumers | Passed | | `react-markdown`, `mdx-bundler`, `markdown-to-jsx` consumers | Passed | -| Firefox and WebKit browser regression suites | **Not established at report creation; see QA workflow on this PR** | +| Firefox full browser regression suite | **82 passed, 14 files** — [QA matrix #43214005524](https://github.com/0xbuffdev/throughline/actions/runs/43214005524), twice | +| WebKit full browser regression suite | **81 passed, 1 failed** — same matrix, **two executions** both fail with a 56px toolbar exceeding the existing \`<55px\` assertion | +| QA branch normal unit/Chromium/packed CI | **Passed** — [PR CI #43214005254](https://github.com/0xbuffdev/throughline/actions/runs/43214005254) | | Real audio output, physical devices, screen readers, real documentation app | **Not executed / not evidenced here** | -**Provenance:** The checks above were executed by the linked CI runner, not in a separate local checkout. The local execution environment had no route to clone GitHub or install repository dependencies; no unexecuted command is counted as a pass. The additional browser workflow in this PR runs the **same 82-test suite** under Firefox/WebKit on GitHub-hosted runners; verify its actual conclusions before updating this record. +**Provenance:** The checks above were executed by the linked CI runner, not in a separate local checkout. The local execution environment had no route to clone GitHub or install repository dependencies; no unexecuted command is counted as a pass. The additional QA matrix ran the **same 82-test suite** under Firefox/WebKit; the WebKit failure was reproduced on the rerun, not waived. ## 3. Acceptance coverage and limitations @@ -58,7 +60,7 @@ The exact candidate commit has a **successful GitHub Actions push run**, [Throug **QA-03 — P1 / integration gate:** Locked fixture builds do not verify the actual documentation application, its plugin order, rendered MDX pages and React bridge. The separately owned documentation integration is required before claiming end-to-end docs acceptance. -**QA-04 — P2 / browser coverage:** Initial green CI ran Chromium only. This PR adds an opt-in browser selector and independent Firefox/WebKit matrix over the **existing full browser suite**. CI execution on the PR must be inspected; an installed browser or a triggered workflow alone does not constitute a pass. +**QA-04 — P2 / reproduced cross-browser toolbar-layout assertion (failed):** On Linux GitHub Actions WebKit 27.2 with the 1,600 × 900 viewport, \`src/react/__tests__/toolbar.browser.test.tsx:30\` fails \`expect(bottom.getBoundingClientRect().height).toBeLessThan(55)\`: **observed 56px**. Steps: (1) checkout QA branch \`05fefb6\` with Node 24/pnpm 11.2.2, (2) \`pnpm install --frozen-lockfile\`, (3) \`pnpm exec playwright install --with-deps webkit\`, (4) \`THROUGHLINE_QA_BROWSER=webkit pnpm test:browser:run\`. Both independent workflow attempts gave **81/82 passed and this same failure**: [release-browser run #43214005524](https://github.com/0xbuffdev/throughline/actions/runs/43214005524). Firefox gave **82/82 passed** in both attempts. This is a real, repeatable **test failure**; its cause may be a WebKit-native control metric vs. intended CSS spacing. The assertion alone does not prove overlap, clipping or an accessibility violation. Inspect the WebKit screenshot and component/control geometry and determine whether CSS should be corrected or the strict pixel assumption is unsupported. Do **not** relax the check merely to make CI green. **QA-05 — P2 / performance evidence:** Existing single-run layout/heap diagnostics do not establish repeatable thresholds. Collect warm and cold samples on fixed hardware, at small/moderate/near-limit graph sizes and 320/720px widths. Record median, tail, heap, layout crossings and version deltas; investigate meaningful regressions before setting a gate. @@ -66,7 +68,7 @@ The exact candidate commit has a **successful GitHub Actions push run**, [Throug **QA-07 — P1 / source-history and publication gate:** Historical public-source references and distribution rights must be reviewed separately. Update SemVer/changelog, verify package archive, and follow the signed-tag/manual staged-publication process only after authorized review. The published `0.0.2` version cannot be reused for a new package. -These findings describe **unclosed verification/release gates**. The checks inspected did not establish a reproducible regression defect in the reviewed candidate. **Do not infer absence of defects from passing tests.** +The WebKit cross-browser check is **reproducibly failing**, while the remaining items are **unclosed verification/release gates**. The source and logs do not yet establish the WebKit discrepancy as a user-visible layout defect rather than a too-strict test assertion; it must be triaged. **Do not infer absence of defects from passing tests.** ## 5. Reproducible retest instructions @@ -99,4 +101,4 @@ For reproducible bugs, record the fixture, preconditions, numbered actions, expe ## 6. Decision and next actions -**Result: INCONCLUSIVE / NOT CLEARED FOR RELEASE.** The candidate's standard CI is green. The extra cross-browser checks and manual/human/integration/performance/governance gates have no completed evidence in this report. Review the QA workflow outcomes, address any defects on separate production-fix PRs, retest the exact new revision, and close or explicitly re-scope the remaining gates through maintainer review before preparing a signed package release. This QA PR does not approve, merge or publish anything. +**Result: FAIL / NOT CLEARED FOR RELEASE.** The candidate's standard CI and Firefox browser suite are green, but **the WebKit 56px vs. <55px check failed twice**. The manual/human/integration/performance/governance gates remain unclosed. Triage the discrepancy on its merits, fix confirmed product defects on separate production-fix PRs if needed, and retest the exact new revision. Close or explicitly re-scope the remaining gates through maintainer review before preparing a signed package release. This QA PR does not approve, merge or publish anything. From ef2e48fde11ad9bb784651221757b92773a7b9ae Mon Sep 17 00:00:00 2001 From: "Christopher S. Aondona" Date: Thu, 12 Nov 2026 13:05:36 +0100 Subject: [PATCH 5/7] docs(qa): format exact WebKit reproduction commands --- docs/release-qa-post-v0.0.2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/release-qa-post-v0.0.2.md b/docs/release-qa-post-v0.0.2.md index 5bf6e3c..61fc024 100644 --- a/docs/release-qa-post-v0.0.2.md +++ b/docs/release-qa-post-v0.0.2.md @@ -32,7 +32,7 @@ The exact candidate commit has a **successful GitHub Actions push run**, [Throug | Isolated Fumadocs, Next.js and Astro consumers | Passed | | `react-markdown`, `mdx-bundler`, `markdown-to-jsx` consumers | Passed | | Firefox full browser regression suite | **82 passed, 14 files** — [QA matrix #43214005524](https://github.com/0xbuffdev/throughline/actions/runs/43214005524), twice | -| WebKit full browser regression suite | **81 passed, 1 failed** — same matrix, **two executions** both fail with a 56px toolbar exceeding the existing \`<55px\` assertion | +| WebKit full browser regression suite | **81 passed, 1 failed** — same matrix, **two executions** both fail with a 56px toolbar exceeding the existing `<55px` assertion | | QA branch normal unit/Chromium/packed CI | **Passed** — [PR CI #43214005254](https://github.com/0xbuffdev/throughline/actions/runs/43214005254) | | Real audio output, physical devices, screen readers, real documentation app | **Not executed / not evidenced here** | @@ -60,7 +60,7 @@ The exact candidate commit has a **successful GitHub Actions push run**, [Throug **QA-03 — P1 / integration gate:** Locked fixture builds do not verify the actual documentation application, its plugin order, rendered MDX pages and React bridge. The separately owned documentation integration is required before claiming end-to-end docs acceptance. -**QA-04 — P2 / reproduced cross-browser toolbar-layout assertion (failed):** On Linux GitHub Actions WebKit 27.2 with the 1,600 × 900 viewport, \`src/react/__tests__/toolbar.browser.test.tsx:30\` fails \`expect(bottom.getBoundingClientRect().height).toBeLessThan(55)\`: **observed 56px**. Steps: (1) checkout QA branch \`05fefb6\` with Node 24/pnpm 11.2.2, (2) \`pnpm install --frozen-lockfile\`, (3) \`pnpm exec playwright install --with-deps webkit\`, (4) \`THROUGHLINE_QA_BROWSER=webkit pnpm test:browser:run\`. Both independent workflow attempts gave **81/82 passed and this same failure**: [release-browser run #43214005524](https://github.com/0xbuffdev/throughline/actions/runs/43214005524). Firefox gave **82/82 passed** in both attempts. This is a real, repeatable **test failure**; its cause may be a WebKit-native control metric vs. intended CSS spacing. The assertion alone does not prove overlap, clipping or an accessibility violation. Inspect the WebKit screenshot and component/control geometry and determine whether CSS should be corrected or the strict pixel assumption is unsupported. Do **not** relax the check merely to make CI green. +**QA-04 — P2 / reproduced cross-browser toolbar-layout assertion (failed):** On Linux GitHub Actions WebKit 27.2 with the 1,600 × 900 viewport, `src/react/__tests__/toolbar.browser.test.tsx:30` fails `expect(bottom.getBoundingClientRect().height).toBeLessThan(55)`: **observed 56px**. Steps: (1) checkout QA branch `05fefb6` with Node 24/pnpm 11.2.2, (2) `pnpm install --frozen-lockfile`, (3) `pnpm exec playwright install --with-deps webkit`, (4) `THROUGHLINE_QA_BROWSER=webkit pnpm test:browser:run`. Both independent workflow attempts gave **81/82 passed and this same failure**: [release-browser run #43214005524](https://github.com/0xbuffdev/throughline/actions/runs/43214005524). Firefox gave **82/82 passed** in both attempts. This is a real, repeatable **test failure**; its cause may be a WebKit-native control metric vs. intended CSS spacing. The assertion alone does not prove overlap, clipping or an accessibility violation. Inspect the WebKit screenshot and component/control geometry and determine whether CSS should be corrected or the strict pixel assumption is unsupported. Do **not** relax the check merely to make CI green. **QA-05 — P2 / performance evidence:** Existing single-run layout/heap diagnostics do not establish repeatable thresholds. Collect warm and cold samples on fixed hardware, at small/moderate/near-limit graph sizes and 320/720px widths. Record median, tail, heap, layout crossings and version deltas; investigate meaningful regressions before setting a gate. From 43b958217013da5f72adee7ec6439872b0c97805 Mon Sep 17 00:00:00 2001 From: "Christopher S. Aondona" Date: Thu, 12 Nov 2026 13:06:58 +0100 Subject: [PATCH 6/7] test(ui): verify toolbar bounds and non-overlap independently of native control height --- .../cross-browser-geometry.browser.test.tsx | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/react/__tests__/cross-browser-geometry.browser.test.tsx diff --git a/src/react/__tests__/cross-browser-geometry.browser.test.tsx b/src/react/__tests__/cross-browser-geometry.browser.test.tsx new file mode 100644 index 0000000..7f22e46 --- /dev/null +++ b/src/react/__tests__/cross-browser-geometry.browser.test.tsx @@ -0,0 +1,55 @@ +import { expect, it } from "vitest"; +import { page } from "vitest/browser"; +import { render } from "vitest-browser-react"; +import { compile } from "../../domains/registry.js"; +import { CHECKOUT_GUIDANCE, CHECKOUT_SCENARIOS } from "../../examples.js"; +import { ThroughlinePlayer } from "../index.js"; +import "../../styles/throughline.css"; + +/** + * Complement the compact-height assertion: browser-native select metrics + * differ, but controls must remain visible, non-overlapping and inside the + * player's own bounds. Keep the original size regression check unchanged. + */ +it("keeps all desktop, tablet and phone toolbar controls inside their bounds without overlap", async () => { + const trace = compile(CHECKOUT_SCENARIOS[2].source); + await page.viewport(1600, 900); + await render(); + const player = document.querySelector(".thl")!; + const bottom = player.querySelector(".thl-bottom")!; + const controls = () => [...bottom.querySelectorAll("button, select, input")]; + + for (const [width, height] of [[1600, 900], [960, 850], [375, 850], [320, 750]] as const) { + await page.viewport(width, height); + await expect.poll(() => Math.round(document.documentElement.clientWidth)).toBe(width); + await expect.poll(() => player.scrollWidth <= player.clientWidth).toBe(true); + + const boundary = bottom.getBoundingClientRect(); + const interactive = controls(); + expect(interactive.length).toBeGreaterThan(8); + const rects = interactive.map((element) => ({ + name: element.getAttribute("aria-label") ?? element.tagName.toLowerCase(), + rect: element.getBoundingClientRect(), + })); + for (const { name, rect } of rects) { + expect(rect.width, name + " has no width").toBeGreaterThan(0); + expect(rect.height, name + " has no height").toBeGreaterThan(0); + expect(rect.left, name + " escapes left boundary").toBeGreaterThanOrEqual(boundary.left - 1); + expect(rect.right, name + " escapes right boundary").toBeLessThanOrEqual(boundary.right + 1); + expect(rect.top, name + " escapes top boundary").toBeGreaterThanOrEqual(boundary.top - 1); + expect(rect.bottom, name + " escapes bottom boundary").toBeLessThanOrEqual(boundary.bottom + 1); + } + for (let left = 0; left < rects.length; left++) { + for (let right = left + 1; right < rects.length; right++) { + const a = rects[left].rect; + const b = rects[right].rect; + const horizontal = Math.min(a.right, b.right) - Math.max(a.left, b.left); + const vertical = Math.min(a.bottom, b.bottom) - Math.max(a.top, b.top); + expect( + horizontal > 1 && vertical > 1, + width + "px: " + rects[left].name + " overlaps " + rects[right].name, + ).toBe(false); + } + } + } +}); From fa38735a11c8f50e1d40dd419b748441842d1b2d Mon Sep 17 00:00:00 2001 From: "Christopher S. Aondona" Date: Thu, 12 Nov 2026 13:09:34 +0100 Subject: [PATCH 7/7] docs(qa): add third WebKit repro and independent responsive control-geometry results --- docs/release-qa-post-v0.0.2.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/release-qa-post-v0.0.2.md b/docs/release-qa-post-v0.0.2.md index 61fc024..65e5e97 100644 --- a/docs/release-qa-post-v0.0.2.md +++ b/docs/release-qa-post-v0.0.2.md @@ -31,12 +31,12 @@ The exact candidate commit has a **successful GitHub Actions push run**, [Throug | Packed Vite React SSR/hydration, keyboard/touch/mobile | Passed | | Isolated Fumadocs, Next.js and Astro consumers | Passed | | `react-markdown`, `mdx-bundler`, `markdown-to-jsx` consumers | Passed | -| Firefox full browser regression suite | **82 passed, 14 files** — [QA matrix #43214005524](https://github.com/0xbuffdev/throughline/actions/runs/43214005524), twice | -| WebKit full browser regression suite | **81 passed, 1 failed** — same matrix, **two executions** both fail with a 56px toolbar exceeding the existing `<55px` assertion | -| QA branch normal unit/Chromium/packed CI | **Passed** — [PR CI #43214005254](https://github.com/0xbuffdev/throughline/actions/runs/43214005254) | +| Firefox full browser regression suite | **83 passed, 15 files**, including added non-overlap geometry — [QA matrix #43214998502](https://github.com/0xbuffdev/throughline/actions/runs/43214998502); earlier 82/82 twice | +| WebKit full browser regression suite | **82 passed, 1 failed (15 files)** — [QA matrix #43214998502](https://github.com/0xbuffdev/throughline/actions/runs/43214998502); same original compact-height failure reproduced on three executions; added non-overlap geometry test passes | +| QA branch normal unit/Chromium/packed CI | **Passed on earlier QA commit** — [PR CI #43214005254](https://github.com/0xbuffdev/throughline/actions/runs/43214005254); the later geometry commit's [CI #43214998532](https://github.com/0xbuffdev/throughline/actions/runs/43214998532) must be checked separately | | Real audio output, physical devices, screen readers, real documentation app | **Not executed / not evidenced here** | -**Provenance:** The checks above were executed by the linked CI runner, not in a separate local checkout. The local execution environment had no route to clone GitHub or install repository dependencies; no unexecuted command is counted as a pass. The additional QA matrix ran the **same 82-test suite** under Firefox/WebKit; the WebKit failure was reproduced on the rerun, not waived. +**Provenance:** The checks above were executed by the linked CI runner, not in a separate local checkout. The local execution environment had no route to clone GitHub or install repository dependencies; no unexecuted command is counted as a pass. The QA matrix ran the original 82 tests and subsequently an additional geometry regression in Firefox/WebKit. The WebKit failure reproduced on the rerun and again with the new geometry test; it was not waived. ## 3. Acceptance coverage and limitations @@ -60,7 +60,7 @@ The exact candidate commit has a **successful GitHub Actions push run**, [Throug **QA-03 — P1 / integration gate:** Locked fixture builds do not verify the actual documentation application, its plugin order, rendered MDX pages and React bridge. The separately owned documentation integration is required before claiming end-to-end docs acceptance. -**QA-04 — P2 / reproduced cross-browser toolbar-layout assertion (failed):** On Linux GitHub Actions WebKit 27.2 with the 1,600 × 900 viewport, `src/react/__tests__/toolbar.browser.test.tsx:30` fails `expect(bottom.getBoundingClientRect().height).toBeLessThan(55)`: **observed 56px**. Steps: (1) checkout QA branch `05fefb6` with Node 24/pnpm 11.2.2, (2) `pnpm install --frozen-lockfile`, (3) `pnpm exec playwright install --with-deps webkit`, (4) `THROUGHLINE_QA_BROWSER=webkit pnpm test:browser:run`. Both independent workflow attempts gave **81/82 passed and this same failure**: [release-browser run #43214005524](https://github.com/0xbuffdev/throughline/actions/runs/43214005524). Firefox gave **82/82 passed** in both attempts. This is a real, repeatable **test failure**; its cause may be a WebKit-native control metric vs. intended CSS spacing. The assertion alone does not prove overlap, clipping or an accessibility violation. Inspect the WebKit screenshot and component/control geometry and determine whether CSS should be corrected or the strict pixel assumption is unsupported. Do **not** relax the check merely to make CI green. +**QA-04 — P2 / reproduced cross-browser toolbar-layout assertion (failed):** On Linux GitHub Actions WebKit 27.2 with the 1,600 × 900 viewport, `src/react/__tests__/toolbar.browser.test.tsx:30` fails `expect(bottom.getBoundingClientRect().height).toBeLessThan(55)`: **observed 56px**. Steps: (1) checkout QA branch `05fefb6` with Node 24/pnpm 11.2.2, (2) `pnpm install --frozen-lockfile`, (3) `pnpm exec playwright install --with-deps webkit`, (4) `THROUGHLINE_QA_BROWSER=webkit pnpm test:browser:run`. The two initial workflow attempts gave **81/82 passed and the same failure**: [release-browser run #43214005524](https://github.com/0xbuffdev/throughline/actions/runs/43214005524). The subsequent [matrix run #43214998502](https://github.com/0xbuffdev/throughline/actions/runs/43214998502) with an independent bounds/overlap test gave WebKit **82/83 passed** and Firefox **83/83 passed**. The new geometry test passes in WebKit at 1600, 960, 375 and 320px viewport widths: interactive controls are within toolbar bounds and do not overlap. Therefore this finding is **a cross-browser compact-height threshold failure**, not demonstrated control clipping or overlap in the widths checked. This is a real, repeatable **test failure**; its cause may be a WebKit-native control metric vs. intended CSS spacing. The assertion alone does not prove overlap, clipping or an accessibility violation. Inspect the WebKit screenshot and component/control geometry and determine whether CSS should be corrected or the strict pixel assumption is unsupported. Do **not** relax the check merely to make CI green. **QA-05 — P2 / performance evidence:** Existing single-run layout/heap diagnostics do not establish repeatable thresholds. Collect warm and cold samples on fixed hardware, at small/moderate/near-limit graph sizes and 320/720px widths. Record median, tail, heap, layout crossings and version deltas; investigate meaningful regressions before setting a gate. @@ -68,7 +68,7 @@ The exact candidate commit has a **successful GitHub Actions push run**, [Throug **QA-07 — P1 / source-history and publication gate:** Historical public-source references and distribution rights must be reviewed separately. Update SemVer/changelog, verify package archive, and follow the signed-tag/manual staged-publication process only after authorized review. The published `0.0.2` version cannot be reused for a new package. -The WebKit cross-browser check is **reproducibly failing**, while the remaining items are **unclosed verification/release gates**. The source and logs do not yet establish the WebKit discrepancy as a user-visible layout defect rather than a too-strict test assertion; it must be triaged. **Do not infer absence of defects from passing tests.** +The WebKit cross-browser check is **reproducibly failing**, while the additional cross-browser control-bounds test **passes** and remaining items are **unclosed verification/release gates**. The source and logs do not yet establish the WebKit discrepancy as a user-visible layout defect rather than a too-strict test assertion; it must be triaged. **Do not infer absence of defects from passing tests.** ## 5. Reproducible retest instructions @@ -101,4 +101,4 @@ For reproducible bugs, record the fixture, preconditions, numbered actions, expe ## 6. Decision and next actions -**Result: FAIL / NOT CLEARED FOR RELEASE.** The candidate's standard CI and Firefox browser suite are green, but **the WebKit 56px vs. <55px check failed twice**. The manual/human/integration/performance/governance gates remain unclosed. Triage the discrepancy on its merits, fix confirmed product defects on separate production-fix PRs if needed, and retest the exact new revision. Close or explicitly re-scope the remaining gates through maintainer review before preparing a signed package release. This QA PR does not approve, merge or publish anything. +**Result: FAIL / NOT CLEARED FOR RELEASE.** The candidate's standard CI and Firefox browser suite are green, but **the WebKit 56px vs. <55px check failed three times, even though the separate non-overlap/control-bounds test passed**. The manual/human/integration/performance/governance gates remain unclosed. Triage the discrepancy on its merits, fix confirmed product defects on separate production-fix PRs if needed, and retest the exact new revision. Close or explicitly re-scope the remaining gates through maintainer review before preparing a signed package release. This QA PR does not approve, merge or publish anything.