Skip to content

Add E2E retry support with SQLite snapshot/restore#1087

Merged
Tim020 merged 5 commits into
devfrom
feature/e2e-retry-with-db-snapshot
May 25, 2026
Merged

Add E2E retry support with SQLite snapshot/restore#1087
Tim020 merged 5 commits into
devfrom
feature/e2e-retry-with-db-snapshot

Conversation

@Tim020
Copy link
Copy Markdown
Contributor

@Tim020 Tim020 commented May 25, 2026

Summary

  • Enables Playwright retries (3 attempts) for the full E2E suite without compromising the serial, state-dependent test design
  • On retry, the backend server is killed, both the SQLite DB and digiscript.json settings 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 1
  • Adds maxFailures: 1 so that once a spec exhausts all retries, downstream specs are immediately skipped — preventing meaningless results from running against incomplete state

Changes

New file — client-v3/e2e/db-snapshot.ts

  • snapshotState() — copies digiscript.sqlite + digiscript.json to .snapshot sibling files after each passing test
  • snapshotExists() — 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 endpoint

client-v3/e2e/global-setup.ts — exports SERVER_PORT and waitForServer so db-snapshot.ts reuses them without duplication

client-v3/playwright.config.tsretries: 0 → 3, adds maxFailures: 1

All 14 spec files — identical change to each: import from db-snapshot.js, add a restore beforeAll (registered before the existing one so it fires first on retry), add a snapshot afterEach

How it works

First attempt:
  beforeAll (retry=0 → no restore)
  beforeAll (existing: new ctx, login, navigate)
  T1 ✓ → afterEach → snapshotState()
  T2 ✓ → afterEach → snapshotState()
  T3 ✗ → no snapshot

Retry (testInfo.retry=1 in beforeAll):
  beforeAll → restoreStateAndRestartServer()
              [SIGKILL → files restored → server restarted → health check]
  beforeAll (existing: new ctx, login, navigate — against clean server)
  T1 ✓ → T2 ✓ → T3 → ...

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

  • Full suite passes clean (148/148) with retries enabled and no actual failures
  • Deliberate failure in spec 04 triggers 3 retries with restore, then maxFailures: 1 stops the suite — downstream specs 05–14 do not run
  • TypeScript typecheck passes with no errors

🤖 Generated with Claude Code

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>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

Client V3 Test Results

23 tests  ±0   23 ✅ ±0   0s ⏱️ ±0s
 2 suites ±0    0 💤 ±0 
 1 files   ±0    0 ❌ ±0 

Results for commit 4bbbf3c. ± Comparison against base commit aaa84be.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

Client Test Results

128 tests  ±0   128 ✅ ±0   0s ⏱️ ±0s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 4bbbf3c. ± Comparison against base commit aaa84be.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

Python Test Results

  1 files  ±0    1 suites  ±0   1m 30s ⏱️ -6s
603 tests ±0  603 ✅ ±0  0 💤 ±0  0 ❌ ±0 
608 runs  ±0  608 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 4bbbf3c. ± Comparison against base commit aaa84be.

♻️ This comment has been updated with latest results.

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>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

Playwright E2E Results (firefox)

148 tests  ±0   148 ✅ ±0   1m 27s ⏱️ +2s
 14 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 4bbbf3c. ± Comparison against base commit aaa84be.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

Playwright E2E Results (chromium)

148 tests  ±0   148 ✅ ±0   1m 24s ⏱️ -1s
 14 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 4bbbf3c. ± Comparison against base commit aaa84be.

♻️ This comment has been updated with latest results.

Tim020 and others added 3 commits May 25, 2026 23:28
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>
@Tim020 Tim020 enabled auto-merge (squash) May 25, 2026 22:44
@sonarqubecloud
Copy link
Copy Markdown

@Tim020 Tim020 merged commit c6eeedc into dev May 25, 2026
35 checks passed
@Tim020 Tim020 deleted the feature/e2e-retry-with-db-snapshot branch May 25, 2026 22:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant