Skip to content

Deepen TUI and web smoke coverage, and run the browser smokes cross-engine #2031

Description

@cliffhall

Problem

npm run smoke completes in under a minute, and the reason is that only one of the six smokes is deep. The TUI and web smokes are boot/first-paint checks, and every browser-driving script pins Chromium — so a regression in a real TUI interaction, or in a connected web tab other than Apps, or in a non-Chromium engine, passes npm run smoke cleanly.

Where the coverage actually sits today

Smoke Depth What it asserts
smoke:launcher (79 ln) Dispatch only --help, --cli --help, --tui --help exit 0 with each mode's banner. No connect.
smoke:cli (500 ln) Deep 10 numbered cases — real tools/list over stdio through the launcher, catalog/config resolution and seeding rules, --server selection, --header merge, an HTTP-transport case with config-file headers lifted onto the wire, the JSON error envelope, and the exit-3 no_stored_token code.
smoke:tui (267 ln) Boot only Waits for MCP Servers in the first frame, then SIGTERM. Self-skips when CI is set (needs a real TTY).
smoke:web (70 ln) HTTP only GET / → 200 with the injected __INSPECTOR_API_TOKEN__. Never executes the bundle.
smoke:web:browser (216 ln) First paint Prod bundle in headless Chromium; "Add Servers" renders with no uncaught error. Never connects.
smoke:web:app (358 ln) One real flow Deep-link connect → open app → data-app-status="ready".

So the launcher → CLI → core → transport path is genuinely covered end to end, and the TUI/web are not.

Gaps to close

1. TUI is effectively unsmoked. Boot-and-render locally, and nothing at all in CI. No keypress, no connect, no tool call. The self-skip is justified (Ink needs raw mode), but it means the entire TUI ships on unit tests alone in CI. Worth evaluating a pty (node-pty) so the CI skip can be lifted, then driving at least: select a server → connect → tools/list renders → run a tool → result renders.

2. Web has exactly one connected flow, and it is the Apps tab. Nothing smokes Tools / Resources / Prompts / Network / Protocol / Logs / Tasks against a live server through the real prod bundle. Those surfaces are carried entirely by unit tests, Storybook play functions, and the integration project — all of which mock or bypass the prod server. smoke:web:app already shows the shape to copy (deep-link connect + a data-* readiness contract); the composable test servers under test-servers/configs/ supply the servers.

3. Chromium only. No Firefox, no WebKit anywhere:

  • scripts/smoke-web-browser.mjs:107 and scripts/smoke-web-app.mjs:208 both loadChromium().
  • package.json:72-73npx playwright install chromium.
  • clients/web/vite.config.ts:378 — Storybook browser: "chromium"; package.json:42 installs only chromium.
  • .github/workflows/main.yml:89npx playwright install --with-deps chromium.

Both smoke scripts already share scripts/lib/prod-web-server.mjs, so parameterizing them over a browser list needs no server-side work. Note Playwright's WebKit is not Safari proper — it approximates the engine, not the browser — so this buys engine coverage, not Safari-bug coverage. Also weigh the CI cost: three engines installed and three runs of each browser smoke against a gate that is already several minutes.

Suggested scope

Reasonable to split into sub-issues once sized:

  • TUI: pty-driven interaction smoke, and lift the CI self-skip
  • Web: connected-flow smokes for the core tabs beyond Apps
  • Cross-engine: parameterize the two browser smokes over chromium/firefox/webkit, decide what CI runs vs. what stays local

Out of scope

Tarball-level coverage — that is pack:verify's dimension, tracked separately (#2003).

Metadata

Metadata

Assignees

No one assigned

    Labels

    choreMaintenance: deps, build tooling, CI, cleanup — no user-facing behavior changev2Issues and PRs for v2

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions