Files
ipx/playwright.config.js
rays b509ea4b35 Coverage for the Rust and the page, and tests for the offline gaps (#390, #391)
Nothing measured what the tests reach. scripts/coverage.sh runs the
cargo tests under cargo-llvm-cov in the ipx-coverage image
(Dockerfile.coverage, built by build-image.sh coverage), in a container
held to the image builder's 6 GB and six threads, one crate at a time,
with the same room and load checks: an instrumented build rebuilds every
dependency, the kind of build that took Tower down on 2026-11-04. The
first run stayed under load 8 with 11 GB free; 69% of lines. web.rs and
daemon.rs read low because the browser suite drives them against a
daemon that is not instrumented.

npm run coverage:page runs the browser suite on a build of the page
(IPX_COVERAGE=1) whose script keeps a source map to each web/src file:
web/concat-map.mts maps the joined files line by line and swc takes it
as its input map. Each test's page records V8's coverage
(tests/ui/coverage.ts, which the specs now take test and expect from),
and monocart-coverage-reports writes it file by file: 73% of lines.
build.mjs requires the map helper only for that build, since
Dockerfile.web's Node does not run TypeScript, and not with a top-level
await, which stopped the CommonJS tests requiring build.mjs.

The offline tests move to offline.spec.ts, in TypeScript, and stand
alone (they add their feed and set the read state they need), with what
#391 found untested: another account signing in clears what was kept, a
position saved offline waits and is sent, and pictures past the budget
go oldest first (keepPictures takes the budget, and trims whether or
not anything new came). The fixture JPEGs were a few bytes no browser
could draw; they are real now, and the artwork test checks one draws.
tsconfig.tools.json type-checks the tests' and build's TypeScript, in
npm run typecheck.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 01:55:19 +00:00

77 lines
3.3 KiB
JavaScript

const { defineConfig } = require('@playwright/test');
const setup = require('./tests/ui/global-setup');
// Before anything else, including the servers below.
setup.prepare();
// Real browser against a real daemon. The stub-DOM smoke test catches a script that
// fails to load; it cannot catch a wrong selector, a handler that runs but does nothing,
// or a page that renders empty -- which is exactly what has slipped through before.
module.exports = defineConfig({
testDir: './tests/ui',
timeout: 30_000,
expect: { timeout: 10_000 },
fullyParallel: false, // one daemon, one database
workers: 1,
// The page's coverage, with IPX_COVERAGE=1 (#390): cleared first, written last.
globalSetup: './tests/ui/coverage-setup.ts',
globalTeardown: './tests/ui/coverage-teardown.ts',
reporter: process.env.CI ? 'line' : [['list']],
use: {
baseURL: 'http://127.0.0.1:8791',
trace: 'retain-on-failure',
screenshot: 'only-on-failure',
// The offline service worker (#389) answers requests before page.route sees them, which the
// tests that fake an answer rely on. The offline tests allow it for themselves.
serviceWorkers: 'block',
},
webServer: [
{
command: 'node tests/ui/fixtures/serve.js',
port: 8792,
reuseExistingServer: false,
stdout: 'ignore',
},
{
// The directory the Directory shows (#205), on SQLite in the scratch directory.
command: `cargo build -q -p ipx-directory && exec ./target/debug/ipx-directory --config ${setup.root}/directory.toml`,
url: `${setup.DIRECTORY}/healthz`,
reuseExistingServer: false,
timeout: 180_000,
stdout: 'ignore',
env: { DIRECTORY_DATABASE_URL: `sqlite://${setup.root}/directory.db?mode=rwc` },
},
{
// The frontend as production serves it (#203): built from web/, served by Caddy on the
// suite's port, the API passed to the daemon behind it.
command: `node web/build.mjs ${setup.root}/web && exec caddy run --config web/Caddyfile --adapter caddyfile`,
url: 'http://127.0.0.1:8791/favicon.png',
reuseExistingServer: false,
timeout: 60_000,
stdout: 'ignore',
env: { IPX_COVERAGE: process.env.IPX_COVERAGE ?? '', WEB_BIND: '127.0.0.1:8791', WEB_ROOT: `${setup.root}/web`, IPX_UPSTREAM: '127.0.0.1:8796', HOME: setup.root, XDG_DATA_HOME: setup.root, XDG_CONFIG_HOME: setup.root },
},
{
// Build first so the tests always run against current source.
command: 'cargo build -q && exec ./target/debug/ipx daemon',
port: 8796,
reuseExistingServer: false,
timeout: 180_000,
stdout: 'pipe',
env: {
IPX_CONFIG: `${setup.root}/config/config.toml`,
IPX_DATA_DIR: `${setup.root}/data`,
IPX_LOG: 'ipx=info',
// Blank, whatever the shell running the suite has: the test daemon sends no traces to
// production's Tempo and never opens production's database.
OTEL_EXPORTER_OTLP_ENDPOINT: '',
IPX_DATABASE_URL: '',
// The server's TypeSafe key is the shell's: /src/.envrc's is a development key, for this.
// Without one, the tests of the server paying for Signals see that it cannot.
TYPESAFE_KEY: process.env.TYPESAFE_KEY ?? '',
IPX_TYPESAFE_URL: 'http://127.0.0.1:8792/jev',
},
},
],
});