Add E2E retry support with SQLite snapshot/restore#1087
Merged
Conversation
Enables Playwright retries (3 attempts) for the E2E suite while preserving the serial, state-dependent nature of the 14 specs. On retry, the backend server is killed, both the SQLite DB and settings JSON are restored from the last known-good snapshot, and the server is restarted before the spec group re-runs. maxFailures: 1 ensures downstream specs are skipped immediately once a spec exhausts all retries, preventing meaningless results from running against incomplete state. - Add e2e/db-snapshot.ts: snapshotState(), snapshotExists(), restoreStateAndRestartServer() - Export SERVER_PORT and waitForServer from global-setup.ts for reuse - Set retries: 3 and maxFailures: 1 in playwright.config.ts - Add beforeAll (restore on retry) and afterEach (snapshot on pass) hooks to all 14 spec files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace ({}, testInfo) with (_fixtures, testInfo) in the beforeAll/afterEach
hooks added to all 14 spec files. Empty destructuring patterns are
disallowed by the no-empty-pattern ESLint rule.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Playwright requires the first argument of beforeAll/afterEach to use object destructuring syntax — a plain identifier causes a fixture parser error. Using test.info() as a static accessor avoids the parameter entirely, satisfying both Playwright and the no-empty-pattern ESLint rule. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract the beforeAll/afterEach retry logic from all 14 spec files into a single registerRetryHooks() function in db-snapshot.ts. Each spec now calls registerRetryHooks() instead of repeating the 10-line hook block, reducing ~140 duplicated lines to one call site per spec. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
digiscript.jsonsettings file are restored from the last known-good snapshot (taken after each passing test), and the server is restarted before the spec group re-runs from test 1maxFailures: 1so that once a spec exhausts all retries, downstream specs are immediately skipped — preventing meaningless results from running against incomplete stateChanges
New file —
client-v3/e2e/db-snapshot.tssnapshotState()— copiesdigiscript.sqlite+digiscript.jsonto.snapshotsibling files after each passing testsnapshotExists()— guards the restore path (handles the spec 01 edge case where no snapshot exists yet)restoreStateAndRestartServer()— SIGKILLs the server, restores both files, respawns the server, polls the health endpointclient-v3/e2e/global-setup.ts— exportsSERVER_PORTandwaitForServersodb-snapshot.tsreuses them without duplicationclient-v3/playwright.config.ts—retries: 0 → 3, addsmaxFailures: 1All 14 spec files — identical change to each: import from
db-snapshot.js, add a restorebeforeAll(registered before the existing one so it fires first on retry), add a snapshotafterEachHow it works
The Python server uses SQLite's DELETE journal mode (no WAL/SHM files) and per-request SQLAlchemy sessions with no persistent connections, so SIGKILL + file swap + restart is safe.
Test plan
maxFailures: 1stops the suite — downstream specs 05–14 do not run🤖 Generated with Claude Code