mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-10-26 05:30:18 +00:00
3f2b5348be
The E2E suite runs serially against one shared admin account, so a spec that leaves server-side state dirty breaks every spec scheduled after it. The two-factor spec was the worst offender: it enrols, consumes backup codes, then disables, and its cleanup only ran when the block had captured both a secret and two unused backup codes, with every error swallowed. A test failing mid-chain destroys exactly that state, so MFA stayed enrolled and each later login stopped at the challenge screen, paying the full readiness timeout three times per test with retries until the job hit its ceiling. Playwright also retries a serial block as a whole in a new worker process, so the retry could not re-enrol either: the enrol endpoint answers 409 for an already-enrolled account and the group failed again. Reset the enrolment from beforeAll and afterAll through the existing emergency CLI, which is the only path that does not require possession of a second factor. The block is now self-healing on a retry and cannot leak state. Two supporting changes: - loginAs now recognises the challenge screen and a login that never left the sign-in form, and names the cause instead of timing out. A cascade costs seconds per test and says what to do about it. - The suite bounds itself in CI, so a cascade fails the test step while the job is still alive to upload the report. A job cancelled by its own timeout runs no further steps, which is why the previous runs produced no evidence at all. The job ceiling is raised above that bound as a backstop.
65 lines
2.5 KiB
TypeScript
65 lines
2.5 KiB
TypeScript
import { defineConfig, devices } from '@playwright/test';
|
|
|
|
/**
|
|
* Playwright E2E config for Sencho.
|
|
*
|
|
* Before running: ensure both dev servers are up:
|
|
* cd backend && npm run dev &
|
|
* cd frontend && npm run dev &
|
|
*
|
|
* Or use the webServer config below (which starts them automatically).
|
|
*/
|
|
export default defineConfig({
|
|
testDir: './e2e',
|
|
// Creates the test admin once so no spec depends on file order.
|
|
globalSetup: './e2e/global-setup.ts',
|
|
// Don't stop on first failure - show all results
|
|
maxFailures: 0,
|
|
// Bound the whole run in CI so a cascade fails the step instead of running
|
|
// until the job's timeout kills it. A job cancelled by its own timeout runs
|
|
// no further steps, so nothing would be uploaded and the next occurrence
|
|
// would have no evidence; failing here leaves the job alive long enough to
|
|
// collect the report. Locally the run is left unbounded, since a slow
|
|
// machine is not a broken build. The job's `timeout-minutes` sits above
|
|
// this value on purpose as a backstop for a wedged browser process.
|
|
globalTimeout: process.env.CI ? 15 * 60 * 1000 : 0,
|
|
// How long to wait for a single test
|
|
timeout: 30_000,
|
|
// How long to wait for an expect() assertion
|
|
expect: { timeout: 5_000 },
|
|
// Run tests serially - Sencho is a single-user app and tests share DB state
|
|
workers: 1,
|
|
// Retry once in CI: the deploy/health-gate specs drive real Docker container
|
|
// runs, so image-pull and gate-window timing varies on shared runners. One
|
|
// retry absorbs a transient blip without tripling the cost of a real failure;
|
|
// a test reported as flaky still needs a fix. trace: 'on-first-retry'
|
|
// captures the retried run.
|
|
retries: process.env.CI ? 1 : 0,
|
|
reporter: [['list'], ['html', { outputFolder: 'e2e/report', open: 'never' }]],
|
|
|
|
use: {
|
|
baseURL: 'http://localhost:5173',
|
|
// Persist auth state between tests in the same file
|
|
storageState: undefined,
|
|
trace: 'on-first-retry',
|
|
screenshot: 'only-on-failure',
|
|
},
|
|
|
|
projects: [
|
|
{
|
|
// Default project (what CI runs via --project=chromium). Skips the manual
|
|
// screenshot capture spec.
|
|
name: 'chromium',
|
|
use: { ...devices['Desktop Chrome'] },
|
|
testIgnore: ['**/screenshots.spec.ts'],
|
|
},
|
|
{
|
|
// Manual-only project for capturing docs/images/. Run explicitly:
|
|
// npx playwright test --project=screenshots
|
|
name: 'screenshots',
|
|
use: { ...devices['Desktop Chrome'] },
|
|
testMatch: ['**/screenshots.spec.ts'],
|
|
},
|
|
],
|
|
});
|