Unpublish finishes in the request, but it returned a job ID that `get-publish-job` could never find. It now returns the domains it unpublished. A missing publish job also stays a normal not-found error instead of suggesting a CLI update. Closes #6578 ## Changes - Keep filename-based E2E shard discovery. Rebalance the files across ten shards using measured CI times; each shard keeps its own test environment and the same 12-minute safety timeout. - Remove the fabricated unpublish job ID. `get-publish-job` remains for publish jobs. - Remove publish-only flags from the unpublish CLI and clarify CLI/MCP guidance. - Keep legacy optional server inputs for compatibility. The API input contract does not change; clients that read the old `jobId` result need to use `unpublishedDomains` instead. - No database migration. Existing domain-removal behavior is unchanged, including retention of other published domains. ## Checklist - [x] Reproduced both reported failures with tests before the fix. - [x] Reviewed the change for compatibility, redundant code, and retained-domain behavior. - [x] Updated the authoritative MCP docs and regenerated the CLI/MCP docs. - [x] Ran focused Builder, CLI, domain, and build tests; workspace typecheck, lint, package-boundary, generated API, and generated-doc checks. - [x] Restore filename-based shard discovery and rebalance the files across ten shards. - [x] Verify every Chromium workflow test runs in exactly one shard and update the E2E contributor docs. All 141 tests are assigned once across the ten shards. - [x] Verify parallel-safe long E2E files and the two-submission legacy form test in CI. - [x] Let independent slow E2E files run their tests concurrently; all ten shard jobs passed. - [ ] Confirm all E2E jobs finish in under five minutes. Eight did; shard 1 took 5:10 and shard 4 took 6:32. Move the long Content-mode page and shared-project bridge files to separate shards, then remeasure. - [x] Required CI checks pass. No live unpublish was run because it would change a published site. Agent evaluations were not run; they require separate approval.
4.3 KiB
Builder E2E tests
Builder E2E workflows run with Playwright Test. The Playwright setup project waits for PostgREST, resets the disposable database, and warms the login route before Chromium runs the selected tests.
Run the suite
Use the full command for CI-like validation:
pnpm e2e:builder
The first run after migrations change applies the regular migration pipeline
and writes an ignored schema cache under .cache/builder-e2e. Refresh it
explicitly with:
pnpm e2e:builder:refresh-schema-cache
The regular E2E suite uses lightweight PostgreSQL containers. Verify that the complete migration chain also applies to the pinned Supabase PostgreSQL image with:
pnpm e2e:builder:check-supabase-migrations
Pass normal Playwright Test arguments after --. For example:
pnpm e2e:builder -- --grep "Builder can copy, duplicate, and delete a page"
pnpm e2e:builder -- 'apps/builder/e2e/tests/pages-actions.[shard-3].e2e.ts'
pnpm e2e:builder -- --debug --grep "Builder can copy"
A lightweight Playwright discovery pass validates the selection before Docker, database migrations, browser installation, or the Builder build starts. A filter that matches no tests therefore fails without starting the test environment.
Fast local reruns
Keep the E2E backend and Builder development server running to avoid rebuilding Builder and restarting Docker for each edit.
Terminal 1:
pnpm e2e:builder:dev:backend
Terminal 2:
pnpm dev
Terminal 3:
pnpm e2e:builder:dev -- --grep "Builder can copy, duplicate, and delete a page"
pnpm e2e:builder:dev defaults to
E2E_BUILDER_URL=https://127.0.0.1:3000. Override it when the development
server uses another port. Chromium maps wstd.dev and its project subdomains
to loopback for local Builder URLs, so host-file changes are unnecessary.
The development backend uses E2E_DB_BOOTSTRAP=if-empty and keeps Docker
containers running. The Playwright setup project still resets test data before
each invocation.
Test organization
- Put workflows in
e2e/tests/*.e2e.tsand importtestfrome2e/test.ts. - Use Playwright's
pagefixture for the workflow under test. Playwright gives each test an isolated context and closes it automatically. - Use Playwright's
contextfixture when setup should share authentication with the workflow page. - Use
withBrowserContext(browser, callback)for isolated setup or setup that runs inbeforeAll. If cookies must survive frombeforeAllinto the tests, create an explicit context withnewBrowserContext(browser)and close it inafterAll. - Use
newIsolatedPage(browser)for identities that must not share cookies. - Keep tests in a file independent even though Playwright runs them in declaration order by default.
CI discovers isolated Playwright shards from filename tags. Each shard uses four workers, and files are assigned by measured CI duration to keep jobs near three to four minutes:
pages-actions.[shard-3].e2e.ts
Every E2E filename must contain at least one unique shard tag. CI derives its matrix from those tags, so adding or removing a shard does not require editing the workflow. Files with multiple tags are partitioned across those shards. All files selected by a shard must use the same set of tags. Rebalance by changing filename tags when measured job durations drift. Suites may opt into parallel mode only when every worker creates uniquely named setup data and the tests do not depend on each other's mutations.
Backend organization
Development, E2E, schema-cache, and Supabase compatibility commands share the
backend definition in apps/builder/backend. compose.yaml defines the common
services, and compose.<mode>.yaml defines only the differences for a named
mode. Backend commands resolve these files by convention; callers do not pass
Compose filenames.
The schema-cache fingerprint discovers migration sources and non-test backend files automatically. Adding a database image, initialization script, Compose override, or migration therefore invalidates the cache without updating a filename registry.
Failures
Failed shard jobs upload the Playwright HTML report, traces, screenshots, videos, and backend service logs.
When you need a completely clean backend locally:
E2E_SKIP_CLEANUP=false pnpm e2e:builder