Files
sencho/e2e/global-setup.ts
Anso a5b938ab93 ci: shard E2E, skip docs-only PRs, and drop the inert visual-regression gate (#2013)
* ci: shard E2E, skip docs-only PRs, and drop the inert visual-regression gate

The visual-regression workflow never had committed baselines, so every run
skipped its comparison and passed. Remove it with its spec and Playwright
project.

E2E now runs as four parallel shards, each with its own app and database,
and no longer waits on the backend job. A single aggregator job keeps the
required check name. CI retries drop from 2 to 1 so a real failure no longer
runs three times.

A change-detection job skips the build, test, and image jobs when a PR only
touches docs/, .claude/, .opencode/, or markdown. It fails closed: an empty
file list, a detection failure, or a rename out of code runs everything.

* test(e2e): create the test admin in global setup so specs do not depend on file order

Sharded runs start each shard on a fresh instance. A spec that logs in
through the API in beforeAll failed with 401 when it ran first, because the
admin was previously created by whichever earlier spec clicked through the
setup screen.
2026-09-25 23:56:05 -04:00

30 lines
1.2 KiB
TypeScript

/**
* Completes first-run setup once, before any spec runs, so every spec file can
* assume the test admin exists regardless of which files ran before it. CI
* shards the suite across fresh instances, so no file can rely on an earlier
* file having clicked through the setup screen. Idempotent: an instance that
* is already set up is left alone.
*/
import { request, type FullConfig } from '@playwright/test';
import { TEST_USERNAME, TEST_PASSWORD } from './helpers';
export default async function globalSetup(config: FullConfig): Promise<void> {
const baseURL = config.projects[0]?.use.baseURL;
const api = await request.newContext({ baseURL });
try {
const status = await api.get('/api/auth/status');
if (!status.ok()) throw new Error(`auth status check failed with ${status.status()}`);
const { needsSetup } = (await status.json()) as { needsSetup: boolean };
if (!needsSetup) return;
const setup = await api.post('/api/auth/setup', {
data: { username: TEST_USERNAME, password: TEST_PASSWORD, confirmPassword: TEST_PASSWORD },
});
if (!setup.ok()) {
throw new Error(`first-run setup failed with ${setup.status()}: ${await setup.text()}`);
}
} finally {
await api.dispose();
}
}