Skip to content

feat(dashboard): SQLite run history, remove Quick Presets, run output reorder & expanded docs - #118

Merged
MyNameIsEdi merged 6 commits into
mainfrom
feat/playwright-dashboard-upgrade
May 25, 2026
Merged

MyNameIsEdi merged 6 commits into
mainfrom
feat/playwright-dashboard-upgrade

Conversation

@MyNameIsEdi

@MyNameIsEdi MyNameIsEdi commented May 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • SQLite run history — replaces per-run JSON files in test-results/runs/ with a single better-sqlite3 database (test-results/runs.db). archiveRun() INSERTs into the DB; /api/playwright/history, /api/playwright/results/:runId, and DELETE /api/playwright/history all query SQLite directly.
  • Remove Quick Presets — deleted PRESETS constant, applyPreset(), noPresets prop, and the entire preset card from the Settings panel.
  • Run Output above Run History — terminal log panel now appears immediately after the Insights row, above the RunsPanel history table, so live output is the first thing you see after a run.
  • Expanded DocsView — grew from 5 to 8 sections; added Authentication, Visual & A11y (axe-core), and CI/CD (GitHub Actions) chapters with code examples.
  • Stop button fix — runAbortRef useRef pattern ensures the Stop button aborts the active SSE fetch without racing against subsequent runs.
  • History from SQLite only — removed all localStorage caching of run history to prevent stale pre-migration data surfacing on page load.
  • streamSummary crash fix — removed stale RUNS_DIR reference left over from JSON-file era; reads raw_json from SQLite when runId is present.

Test plan

  • npm install — better-sqlite3 installs cleanly on Node 20
  • npm run dev — server starts; test-results/runs.db is created automatically
  • Click Run Tests → run appears in /api/playwright/history after completion
  • Click a past run in the history table → suite results and log replay correctly
  • Click Clear History → history table empties
  • Settings panel has no Quick Presets section
  • Run Output terminal appears above the Run History table
  • Stop button aborts cleanly; clicking Run Tests again works immediately
  • npx tsc --noEmit and cd ui && npx tsc --noEmit — zero type errors
  • npm run format:check — passes

Summary by CodeRabbit

  • New Features

    • Persistent run history and full run logs now stored and replayable from a central archive.
    • Docs view expanded with Authentication, Visual/A11y, and CI/CD sections (runnable examples).
  • Changed

    • Run output panel relocated in the dashboard layout; history now queried from the central store (newest-first).
    • Removed Quick Presets and localStorage run-history caching.
  • Bug Fixes

    • Stop button reliably aborts live runs; resolved a crash when loading archived run summaries.
  • Chores

    • Added SQLite runtime dependency for persisted history.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 25, 2026 •

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR migrates Playwright run history persistence from individual JSON files under test-results/runs/ to a SQLite database. The server initializes a runs table at startup, the archive function stores normalized test results and capped logs in the database, API endpoints query SQLite instead of the filesystem, and the AI summary helper reads archived snapshots from the database when a runId is provided.

Changes

Run History SQLite Persistence

Layer / File(s) Summary
Documentation of changes
CHANGELOG.md, README.md
CHANGELOG records new Dashboard UI features, immediate history refresh on [DONE], DocsView expansion, and SSE/streamSummary fixes. README updates the Persistent Run History + Logs row to reflect test-results/runs.db.
Dependencies and imports
package.json, server/index.ts
Add better-sqlite3 and @types/better-sqlite3; server/index.ts imports Database and Node fs sync helpers.
Database initialization
server/index.ts
Create test-results/ if needed, open test-results/runs.db, and create runs table for metadata, normalized counts, capped run_log, and raw_json.
Run archiving via SQLite
server/index.ts
archiveRun reads pw-results.json, normalizes results, computes totals, caps run_log, and upserts a runs row containing the full raw_json instead of writing per-run JSON files.
API endpoints for archived runs
server/index.ts
GET /api/playwright/history queries runs ordered newest-first (optional limit); GET /api/playwright/results/:runId returns normalized results and run_log from SQLite; DELETE /api/playwright/history clears the table.
Post-run summary integration
server/index.ts
streamSummary now prefers raw_json from the runs table when creds.runId is supplied; otherwise it falls back to pw-results.json on disk.
Dashboard UI updates
ui/src/pages/PlaywrightDashboard.tsx
Remove localStorage run-history hydrate/persist, clear stale pre-migration key, add runAbortRef and integrate SSE abort handling, change Stop button to abort active SSE, remove Quick Presets and Presets bar, update SettingsView invocation, relocate Run Output panel, and refresh Docs view content.

Sequence Diagram

sequenceDiagram
  participant Dashboard
  participant Server
  participant SQLite
  Dashboard->>Server: GET /api/playwright/history or /results/:runId
  Server->>SQLite: SELECT raw_json, run_log FROM runs WHERE id=?
  SQLite-->>Server: row(s)
  Server-->>Dashboard: normalized results + run_log
  Dashboard->>Server: POST to start run (SSE)
  Server-->>Dashboard: SSE events (stdout, summary_*)
  Dashboard->>Dashboard: runAbortRef aborts SSE controller on Stop
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • MyNameIsEdi/open-qa#117: Overlaps in dashboard SSE/live run handling and immediate history refresh after [DONE].
  • MyNameIsEdi/open-qa#114: Overlaps in SSE/run-handling and hydration of archived run logs in the dashboard client.
  • MyNameIsEdi/open-qa#116: Related client changes for fetching archived runLog and adapting to server-provided immutable run snapshots.

Poem

🐰 I found the logs beneath the bog,

A SQLite burrow for each cog,
No scattered JSON to misplace,
One comfy DB holds every trace,
Hooray — the dashboard hops with grace!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and specifically summarizes the main changes: SQLite run history persistence, removal of Quick Presets feature, reordering of run output UI, and expanded documentation—all of which are confirmed in the changeset.
Description check ✅ Passed The PR description provides a comprehensive summary of all major changes and a detailed test plan, but does not follow the provided template structure with standard sections like Type of change or Checklist.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/playwright-dashboard-upgrade

Comment @coderabbitai help to get the list of available commands and usage tips.

MyNameIsEdi and others added 5 commits May 25, 2026 05:58
… above history

- Replace JSON-file run storage with SQLite (better-sqlite3):
  archiveRun() now writes id/run_at/spec/counts/run_log/raw_json into
  a single runs.db; GET /history reads via prepared SELECT; GET
  /results/:id reads raw_json + run_log from DB; DELETE /history
  executes DELETE FROM runs — no more RUNS_DIR file scatter
- Remove Quick Presets entirely: delete Preset interface, SV_CONFIG,
  SV_ALL_SPECS, PRESETS array, applyPreset(), noPresets prop, both
  JSX blocks (SettingsView card + always-visible presets bar), and
  unused Zap icon import
- Move Run Output terminal above Run History (RunsPanel) so users see
  the latest stdout immediately after a run without scrolling past the
  history table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tent

- Quick Start: add playwright.config.ts essentials block (multi-project,
  reporters, trace/screenshot/video defaults)
- Locator Strategies: add getByTitle(), expand code examples with
  chaining, correct all descriptions
- Core Assertions: expand from 11 to 20 assertions across 4 card groups
  (toBeAttached, toBeDisabled, toBeEditable, toHaveValues, toHaveClass,
  toHaveCSS, toHaveCount, toHaveAccessibilityTree); add negation +
  soft-assertion examples
- Common Patterns: add Parallel & Sharded runs section; expand POM with
  typed Locator fields; update Fixtures with DashboardPage; add
  network modify-response pattern
- Authentication (new section): global-setup storageState, multi-role
  auth, API-based JWT auth, config project setup
- Visual & Accessibility Testing (new section): screenshot workflow
  steps, mask/maxDiffPixelRatio options, axe-core WCAG 2.1 AA integration,
  accessibility checklist (keyboard, contrast, alt text, RTL, ARIA)
- CI / CD Integration (new section): GitHub Actions workflow, sharding
  across parallel jobs, environment variables, recommended CI flags
- CLI Reference: expand from 11 to 16 flags (--grep-invert,
  --forbid-only, --shard, --update-snapshots, --pass-with-no-tests);
  add merge-reports and --help examples
- Add GitBranch icon import; add 3 new TOC entries and sidebar links

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… cache

- Remove RUN_HISTORY_KEY and the lazy localStorage initialiser for
  runHistory — state now always starts as [] and is populated by the
  first fetchHistory() call on mount
- Remove the useEffect that wrote runHistory back to localStorage after
  every change (stale cache was masking real DB data on page refresh)
- Add one-time localStorage.removeItem('pw_run_history_v1') at module
  level to clear any stale pre-SQLite data in existing browsers
- Remove LIMIT 30 cap from GET /api/playwright/history — all runs are
  returned from SQLite; caller can pass ?limit=N to override

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The Stop button was calling setRunning(false) directly, which only
updated local state. The AbortController inside runWithSSE/runDynamicTest
was never invoked, so:
  1. The fetch/SSE stream kept running server-side after Stop was clicked
  2. When the orphaned stream eventually finished, its finally block
     called setRunning(false) again — silently cancelling any new run
     the user had just started

Fix: store the AbortController in runAbortRef (useRef). The Stop button
now calls runAbortRef.current?.abort() which throws an AbortError inside
the running fetch, causing the catch block to log [TIMEOUT] and the
finally block to clean up normally. Both runWithSSE and runDynamicTest
are updated; the ref is cleared in each finally block.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… SQLite

streamSummary() still used path.join(RUNS_DIR, ...) to load the archived
run JSON for the AI post-mortem, but RUNS_DIR was deleted in the SQLite
migration. This crashed the server the moment a run finished, keeping
the dashboard stuck in RUNNING state forever.

Fix: when creds.runId is set, query the runs table directly
(SELECT raw_json FROM runs WHERE id = ?); fall back to RESULTS_PATH
only when no runId is provided (legacy path).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@MyNameIsEdi
MyNameIsEdi force-pushed the feat/playwright-dashboard-upgrade branch from c035c3f to c1d228e Compare May 25, 2026 02:59
…& run output reorder

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@MyNameIsEdi
MyNameIsEdi merged commit a7c2235 into main May 25, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant