Skip to content

fix(frontend-e2e): the nightly's two causes — the rail transition split the model-choice spec's reads, and Vite never pre-bundled the lazy mermaid import (#2705) - #2714

Merged
vybe merged 4 commits into
devfrom
feature/2705-e2e-nightly-red
Sep 11, 2026
Merged

vybe merged 4 commits into
devfrom
feature/2705-e2e-nightly-red

Conversation

@webmixgamer

Copy link
Copy Markdown
Contributor

Summary

  • The nightly frontend-e2e red (frontend-e2e nightly @smoke suite is red on dev #2705) had two independent causes. This PR fixes both and claims only these.
  • workspace-model-choice.spec.js read the composer's boxes across several round-trips while the rail column's 300 ms width transition (The Workspace rail column steps discretely when a voice call ends (#2640 follow-up) #2676) moved them: the two Send reads straddled it, the stale send.x made the Send-skip miss Send itself, and the assertion fired on Send's own right edge, 3 of 3 attempts at 768 and 1280 in some CI stacks. It now reads every box in one page.evaluate under reduced motion and clicks the shell as an element action. 41 of 41 across ten local repeats, against 4 failures in 6 before.
  • Vite 8's dependency scanner tree-shakes each script block before it records imports, so CanvasDiagram.vue's lazy import('mermaid') in an unexported helper was never pre-bundled; the first served page that included it re-optimised and full-reloaded every open tab (the dedupe spec's x2-of-everything flake, and every developer's tabs after a container start). optimizeDeps.include now lists every dynamic bare import, enforced by a scanner script plus a vitest guard against the resolved config.

Changes

  • src/frontend/vite.config.js: optimizeDeps.include: ['mermaid', 'qrcode'], with the why.
  • src/frontend/scripts/scan-dynamic-imports.mjs: finds dynamic bare imports (script blocks only; comments and regex literals blanked, strings kept; non-literal specifiers reported as unscannable).
  • src/frontend/tests/unit/optimizeDepsIncludeGuard.spec.js: extractor fixtures plus the rule against resolveConfig; red on the previous config.
  • src/frontend/e2e/workspace-model-choice.spec.js: reduced motion, one-frame snapshot, element click.
  • Docs: docs/memory/architecture/frontend.md (the rule), workspace-model-choice.md and its index row, three learnings.md entries, the cso --diff report (no findings).

What this does not fix

Test Plan

  • npm run test:unit: 2705 passed with the new guard in the suite (the one failing file is the known host-only missing @vue/compiler-sfc).
  • Guard red on the previous config (names mermaid and qrcode), green now; vite optimize --force lists both as pre-bundled.
  • Live dev container (bind mount verified as this tree): restarted on the config change, re-optimised at start, and serves CanvasDiagram.vue against /node_modules/.vite/deps/mermaid.js with no later re-optimisation in the log.
  • workspace-model-choice.spec.js --repeat-each 10: 41 passed. agent-detail-request-dedupe.spec.js: 3 passed locally with no reload.
  • frontend-e2e green on this PR; the nightly's report job closes frontend-e2e nightly @smoke suite is red on dev #2705 on the first green night.

Fixes #2705

🤖 Generated with Claude Code

webmixgamer and others added 2 commits September 11, 2026 16:06
… never re-optimises mid-session (#2705)

Vite 8's dependency scanner tree-shakes each script block before it records
imports, so CanvasDiagram.vue's `import('mermaid')` inside an unexported helper
in a plain <script> block was never pre-bundled. The first served page whose
module graph included the file registered the missing dep, re-optimised, and
sent a full reload to every open tab — every developer's, and every Playwright
page mid-run, which is why agent-detail-request-dedupe.spec.js saw every /api
request twice.

- vite.config.js: optimizeDeps.include lists every package a dynamic
  import('…') under src/ names (mermaid, qrcode).
- scripts/scan-dynamic-imports.mjs: finds them (script blocks only; comments
  and regex literals blanked, strings kept; non-literal specifiers reported).
- tests/unit/optimizeDepsIncludeGuard.spec.js: checks the list against the
  RESOLVED config via resolveConfig; red on the previous config, green now.
- docs/memory/architecture/frontend.md: the rule, in the owning area file.

Refs #2705

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… reduced motion (#2705)

Since #2676 the workspace rail column enters through a 300 ms width transition
once the roster arrives, and everything left of it moves with it. The spec read
Send's box, then each button's, then clicked at remembered coordinates; the two
Send reads straddled the transition, the stale send.x made the Send-skip miss
Send itself, and "an icon button sits right of the picker" fired on Send's own
right edge — 3 of 3 attempts at 768 and 1280 in some CI stacks, while 375 passed
only because the column is hidden below sm.

Every box now comes from ONE page.evaluate (the locators choose the elements,
the page returns the geometry in one frame), the page emulates reduced motion so
the entry is instant, and the shell click is an element action. 41 of 41 across
ten repeats locally, against 4 failures in 6 before.

Also: the feature-flow rows for the spec, three learnings-ledger entries (the
one-frame rule, the scanner class, and "read the summary line before attributing
a red"), and the cso --diff report (no findings).

The dedupe spec's older compatibility-x2 double fetch remains and is #2710; the
rail column's load-time shift is #2711; e2e on the production image is #2712.

Fixes #2705

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@webmixgamer webmixgamer added the ui PR touches the frontend UI — triggers Playwright e2e tests label Sep 11, 2026
Comment thread src/frontend/scripts/scan-dynamic-imports.mjs Fixed
…losing tag's > (#2705)

CodeQL's js/bad-tag-filter flagged the <script> block regex for not matching
`</script >`. The regex extracts script blocks from SFC source rather than
sanitising anything, but a closing tag with whitespace before its `>` is valid
HTML and the extractor should read it, so the pattern now allows it, with a
fixture that closes one block that way.

Refs #2705

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Comment thread src/frontend/scripts/scan-dynamic-imports.mjs Fixed
…ing before its > (#2705)

CodeQL's js/bad-tag-filter re-flagged the pattern on the previous head with
`</script\t\n bar>`: the rule wants the end tag to accept any attribute-like
noise before `>`, the same `[^>]*` shape the opening tag already uses. A
browser closes the block on such a tag too, so the extractor should read it.

Refs #2705

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@vybe vybe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge-train: batch validated on train/20260911-1635 (#2729)

@vybe
vybe merged commit a38d3d2 into dev Sep 11, 2026
27 checks passed
@webmixgamer
webmixgamer deleted the feature/2705-e2e-nightly-red branch September 11, 2026 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ui PR touches the frontend UI — triggers Playwright e2e tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants