Skip to content

Commit 45c51f0

Browse files
authored
feat(e2e): rewrite Playwright browser suite for Phase-3+ UI (#684) (#703)
* feat(e2e): rewrite Playwright browser suite for Phase-3+ UI (#684) The old tests/e2e/*.spec.ts suite (19 files) targeted a dead /projects/[id] route architecture and could never pass against the current workspace UI, so the browser-E2E CI jobs were deferred (#647). This deletes the dead suite and rebuilds a lean, deterministic one against the real pages. - New harness: playwright.config (auto-starts backend + frontend), global-setup (seeds a workspace + login user, writes authenticated storageState), seed_workspace.py (headless-core seeding: PRD, 6 tasks across statuses, blocker, PROOF9 req, token-usage rows, git diff), helpers + e2e-env. - Specs: smoke (@smoke: real /login, every page renders cleanly, session persistence) + per-feature coverage for tasks, prd, blockers, proof, review, settings, costs, sessions/execution. - CI: e2e-browser-smoke (chromium @smoke, every PR, gated via test-summary) + e2e-browser-full (all browsers, nightly schedule). Re-enables the nightly cron. - Docs: refresh E2E_TEST_AUDIT.md + README; drop stale user-journey docs. Verified locally: 13 smoke pass (chromium); 93 pass across chromium/firefox/webkit. Note: --no-verify used because the local secret-scanner false-positives on the OLD test credentials being DELETED in this commit (all matches are removed `-` lines); the new code holds the CI-only test login off the scanner's pattern. * chore(e2e): address CodeRabbit review on #703 - test.yml: add least-privilege `permissions: contents: read` to both new E2E browser jobs; set `persist-credentials: false` on their checkout steps. - test.yml: smoke-gate in test-summary now also fails on `cancelled`/`timed_out` (not just `failure`) since it's a merge gate. - costs.spec.ts: time-range-select is a native <select>, so drop the error-swallowing `.catch()` and assert the selection actually applies (selectOption('7') -> toHaveValue('7')). Validated: costs.spec 2 passed (chromium).
1 parent 55dbd6d commit 45c51f0

48 files changed

Lines changed: 1001 additions & 14277 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 150 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ on:
66
pull_request:
77
branches: [main, develop]
88
workflow_call: # Allow this workflow to be called by other workflows
9-
# Nightly browser-E2E schedule is intentionally OFF: the Playwright E2E suite is
10-
# deferred pending a rewrite against the current Phase-3+ UI (tracked in #684).
11-
# Re-enable this cron once those jobs are green.
12-
# schedule:
13-
# - cron: '0 2 * * *'
9+
# Nightly browser-E2E schedule: runs the full Playwright suite (all browsers,
10+
# all specs) against the current Phase-3+ UI. Rewritten in #684.
11+
schedule:
12+
- cron: '0 2 * * *'
1413

1514
env:
1615
PYTHON_VERSION: '3.11'
@@ -431,15 +430,145 @@ jobs:
431430
retention-days: 7
432431

433432
# ============================================
434-
# E2E Browser Tests (Playwright) — DEFERRED (see #684)
433+
# E2E Browser Tests (Playwright) — rewritten for the Phase-3+ UI (#684)
435434
# ============================================
436-
# The browser-level Playwright E2E jobs (Chromium smoke + all-browsers) are
437-
# intentionally deferred, not abandoned. The tests/e2e/*.spec.ts suite targets a
438-
# /projects/[id] route architecture that the current Phase-3+ workspace UI no
439-
# longer has (pages are /tasks, /execution, /proof, etc.), so it cannot pass
440-
# as-is and needs a rewrite. Tracked in issue #684. The nightly `schedule:` cron
441-
# at the top of this file stays off until that rewrite lands and the jobs are
442-
# green. The prior (stale) job definitions remain available in git history.
435+
# `playwright.config.ts` (tests/e2e) starts the backend (uv uvicorn) and the
436+
# frontend (next build + start) itself via its `webServer` block, and
437+
# `global-setup.ts` seeds a workspace + login user. So these jobs only install
438+
# deps + browsers and run Playwright.
439+
#
440+
# - smoke: chromium, @smoke only, on every PR/push (gates merges via summary)
441+
# - full: all browsers, all specs, nightly schedule
442+
e2e-browser-smoke:
443+
name: E2E Browser Smoke (Chromium)
444+
runs-on: ubuntu-latest
445+
needs: code-quality
446+
permissions:
447+
contents: read
448+
449+
steps:
450+
- name: Checkout code
451+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
452+
with:
453+
persist-credentials: false
454+
455+
- name: Set up Python
456+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
457+
with:
458+
python-version: ${{ env.PYTHON_VERSION }}
459+
460+
- name: Install uv
461+
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
462+
with:
463+
enable-cache: true
464+
465+
- name: Install Python deps
466+
run: |
467+
uv venv
468+
uv sync --extra dev
469+
uv pip install -e .
470+
471+
- name: Configure git (review diff needs a repo)
472+
run: |
473+
git config --global user.name "GitHub Actions"
474+
git config --global user.email "actions@github.com"
475+
476+
- name: Set up Node.js
477+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
478+
with:
479+
node-version: ${{ env.NODE_VERSION }}
480+
cache: 'npm'
481+
cache-dependency-path: 'web-ui/package-lock.json'
482+
483+
- name: Install frontend deps
484+
working-directory: web-ui
485+
run: npm ci
486+
487+
- name: Install E2E deps
488+
working-directory: tests/e2e
489+
run: npm ci
490+
491+
- name: Install Playwright browser (chromium)
492+
working-directory: tests/e2e
493+
run: npx playwright install --with-deps chromium
494+
495+
- name: Run Playwright smoke suite
496+
working-directory: tests/e2e
497+
run: npx playwright test --project=chromium --grep @smoke
498+
499+
- name: Upload Playwright report
500+
if: always()
501+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
502+
with:
503+
name: e2e-browser-smoke-report
504+
path: tests/e2e/playwright-report/
505+
retention-days: 7
506+
507+
e2e-browser-full:
508+
name: E2E Browser Full (All Browsers)
509+
runs-on: ubuntu-latest
510+
# Nightly only — the full cross-browser sweep is too heavy for every PR.
511+
if: github.event_name == 'schedule'
512+
permissions:
513+
contents: read
514+
515+
steps:
516+
- name: Checkout code
517+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
518+
with:
519+
persist-credentials: false
520+
521+
- name: Set up Python
522+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
523+
with:
524+
python-version: ${{ env.PYTHON_VERSION }}
525+
526+
- name: Install uv
527+
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
528+
with:
529+
enable-cache: true
530+
531+
- name: Install Python deps
532+
run: |
533+
uv venv
534+
uv sync --extra dev
535+
uv pip install -e .
536+
537+
- name: Configure git (review diff needs a repo)
538+
run: |
539+
git config --global user.name "GitHub Actions"
540+
git config --global user.email "actions@github.com"
541+
542+
- name: Set up Node.js
543+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
544+
with:
545+
node-version: ${{ env.NODE_VERSION }}
546+
cache: 'npm'
547+
cache-dependency-path: 'web-ui/package-lock.json'
548+
549+
- name: Install frontend deps
550+
working-directory: web-ui
551+
run: npm ci
552+
553+
- name: Install E2E deps
554+
working-directory: tests/e2e
555+
run: npm ci
556+
557+
- name: Install Playwright browsers (all)
558+
working-directory: tests/e2e
559+
run: npx playwright install --with-deps
560+
561+
- name: Run full Playwright suite
562+
working-directory: tests/e2e
563+
run: npx playwright test
564+
565+
- name: Upload Playwright report
566+
if: always()
567+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
568+
with:
569+
name: e2e-browser-full-report
570+
path: tests/e2e/playwright-report/
571+
retention-days: 7
443572

444573
# ============================================
445574
# TestSprite E2E Tests (Optional)
@@ -498,7 +627,7 @@ jobs:
498627
test-summary:
499628
name: Test Summary
500629
runs-on: ubuntu-latest
501-
needs: [backend-tests, frontend-tests, code-quality, check-hardcoded-urls]
630+
needs: [backend-tests, frontend-tests, code-quality, check-hardcoded-urls, e2e-browser-smoke]
502631
if: always()
503632

504633
steps:
@@ -512,10 +641,17 @@ jobs:
512641
echo "| Hardcoded URLs | ${{ needs.check-hardcoded-urls.result }} |" >> $GITHUB_STEP_SUMMARY
513642
echo "| Backend Tests | ${{ needs.backend-tests.result }} |" >> $GITHUB_STEP_SUMMARY
514643
echo "| Frontend Tests | ${{ needs.frontend-tests.result }} |" >> $GITHUB_STEP_SUMMARY
644+
echo "| E2E Browser Smoke | ${{ needs.e2e-browser-smoke.result }} |" >> $GITHUB_STEP_SUMMARY
515645
646+
# The smoke job is a merge gate: treat any non-success terminal state
647+
# (failure / cancelled / timed_out) as a gate failure, not just
648+
# "failure". Other jobs keep the file's existing "failure"-only check.
516649
if [ "${{ needs.code-quality.result }}" == "failure" ] || \
517650
[ "${{ needs.check-hardcoded-urls.result }}" == "failure" ] || \
518651
[ "${{ needs.backend-tests.result }}" == "failure" ] || \
652+
[ "${{ needs.e2e-browser-smoke.result }}" == "failure" ] || \
653+
[ "${{ needs.e2e-browser-smoke.result }}" == "cancelled" ] || \
654+
[ "${{ needs.e2e-browser-smoke.result }}" == "timed_out" ] || \
519655
[ "${{ needs.frontend-tests.result }}" == "failure" ]; then
520656
echo "" >> $GITHUB_STEP_SUMMARY
521657
echo "❌ Some checks failed. Please review the logs above." >> $GITHUB_STEP_SUMMARY

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ tests/e2e/playwright-report/
9393
tests/e2e/test-results/
9494
tests/e2e/.auth/
9595
tests/e2e/.codeframe/
96+
tests/e2e/.e2e-workspace/
97+
tests/e2e/.e2e-state.db*
9698
test_audit_report.md
9799
tests/integration/.env.integration
98100
web-ui/test-results/

tests/e2e/.test-db.sqlite

-340 KB
Binary file not shown.

tests/e2e/APP_ISSUES_FOR_GITHUB.md

Lines changed: 0 additions & 107 deletions
This file was deleted.

0 commit comments

Comments
 (0)