test: add playwright e2e suite for files-inspector and streaming-chat#14
Conversation
Covers the browser-level paths the existing in-process vitest suites can't reach — DOM render, RPC results landing in the UI, client-side route navigation, live token streaming over WS, and shared-state-backed history clearing. Suite spins up the real CLI dev servers via Playwright webServer; files-inspector's cwd is pinned to a fixture dir through a new DEVFRAME_E2E_CWD env so list-files assertions stay deterministic. Wires test:e2e into the root scripts and adds an e2e job alongside unit-test in ci.yml (renamed to CI).
✅ Deploy Preview for devfra ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Each example now runs through Playwright twice — once against the live
CLI dev server (WS RPC, actions, streaming) and once against the
static-build output served as plain files (pre-computed `static` /
`query{snapshot:true}` dumps, `backend: 'static'` connection meta).
The static surface is exactly what `node bin.mjs build --out-dir ...`
ships to a CDN, so the new specs guard the deploy contract end-to-end.
Static dumps are served by a tiny zero-dep `tests/e2e/_support/
serve-static.mjs` script with SPA fallback. streaming-chat's static
specs intentionally only cover the demo-prompts list and the static
backend marker — `send`/`clear` are actions and never reach a static
dump.
The counter example was removed; it was too thin to carry useful
coverage and its dev mode runs in bridge mode (no SPA mount), so the
e2e suite couldn't drive it without bespoke wiring.
There was a problem hiding this comment.
Pull request overview
This PR introduces a Playwright E2E test suite for the repo’s two SPA-backed example apps (files-inspector, streaming-chat), running both the real CLI dev server path and a static-build + static-server path. It also wires E2E execution into CI and adjusts Vitest configuration to avoid picking up Playwright specs.
Changes:
- Add Playwright E2E specs under
tests/e2e/for dev + static modes of both example apps. - Add Playwright tooling/config (
playwright.config.ts, dependency catalog entry, root scripts) and a CIe2ejob. - Remove the
examples/counterexample and its documentation reference.
Reviewed changes
Copilot reviewed 22 out of 24 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
vitest.config.ts |
Updates Vitest multi-project setup to exclude tests/e2e/** from unit test runs. |
turbo.json |
Adds Turbo tasks for building static CLI outputs for the example apps. |
tests/e2e/streaming-chat-static.spec.ts |
Adds static-build assertions for the streaming-chat example. |
tests/e2e/streaming-chat-dev.spec.ts |
Adds dev-server E2E coverage for streaming behavior + history clearing. |
tests/e2e/files-inspector-static.spec.ts |
Adds static-build assertions for the files-inspector example. |
tests/e2e/files-inspector-dev.spec.ts |
Adds dev-server E2E coverage for deterministic fixture file listing + routing. |
tests/e2e/_support/serve-static.mjs |
Introduces a minimal static file server used by the E2E suite. |
tests/e2e/fixtures/sample.txt |
Adds deterministic fixture input for file listing assertions. |
tests/e2e/fixtures/README.md |
Adds deterministic fixture input for file listing assertions. |
tests/e2e/fixtures/package.json |
Adds deterministic fixture input for file listing assertions. |
pnpm-workspace.yaml |
Adds @playwright/test to the shared testing catalog. |
pnpm-lock.yaml |
Locks Playwright dependencies for reproducible installs. |
playwright.config.ts |
Configures Playwright test directory and starts dev/static servers via webServer. |
package.json |
Adds test:e2e / test:e2e:ui scripts and Playwright as a dev dependency. |
examples/streaming-chat/package.json |
Adds a cli:build script for producing the static output directory. |
examples/files-inspector/src/devframe.ts |
Adds DEVFRAME_E2E_CWD override so E2E file listings are deterministic. |
docs/guide/built-with.md |
Removes documentation reference to the deleted counter example. |
.gitignore |
Ignores Playwright output directories and caches. |
.github/workflows/ci.yml |
Adds an e2e job (and renames workflow to CI) to run Playwright in GitHub Actions. |
examples/counter/src/devframe.ts |
Deletes the counter example implementation. |
examples/counter/src/client/main.ts |
Deletes the counter example client entry. |
examples/counter/src/client/index.html |
Deletes the counter example HTML entry. |
examples/counter/package.json |
Deletes the counter example package definition. |
examples/counter/bin.mjs |
Deletes the counter example CLI entrypoint. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const target = normalize(join(root, relative)) | ||
| if (!target.startsWith(root)) | ||
| return null |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Implemented in e46bab7. resolveAsset() now enforces root containment using path.relative(root, target) plus isAbsolute() checks, replacing the unsafe prefix check.
| const found = resolveAsset(req.url ?? '/') | ||
| // SPA fallback — unknown routes (no file extension match) serve index.html | ||
| // so client-side routing works under the static dump. | ||
| const file = found ?? resolveAsset('/index.html') | ||
| if (!file) { |
| function resolveAsset(urlPath) { | ||
| // Strip query/hash. | ||
| const clean = urlPath.split('?')[0].split('#')[0] | ||
| const decoded = decodeURIComponent(clean) |
Summary
files-inspector,streaming-chat), exercising the real CLI dev server path — DOM render, RPC results landing in the UI, route navigation, live token streaming over WS, and shared-state history clearing.tests/e2e/; Playwright starts each example viawebServer, and files-inspector's cwd is pinned totests/e2e/fixtures/through a newDEVFRAME_E2E_CWDenv so list-files assertions stay deterministic.pnpm test:e2e(chained behindturbo run build) and ane2ejob alongsideunit-testin the workflow (renamed toCI), with chromium browser caching and a report artifact on failure.Test plan
pnpm test:e2e— 4 tests pass locallypnpm test— Vitest still green (28 files / 306 tests) after thetests/e2e/**excludepnpm lintandpnpm typecheckcleane2ejob runs green in CI on this PR