Repository navigation
E2E: migrate frontend to Cypress (consolidate #729 + #774); keep Python Playwright #967
Copy link
Copy link
Closed
Labels
good first issueGood for newcomersGood for newcomershelp wantedExtra attention is neededExtra attention is needed
Description
Goal
Consolidate frontend E2E from Jest/Puppeteer to Cypress; keep Python Playwright for backend/embeddings E2E (separate concern).
Context
Frontend browser E2E is effectively dead on main today:
yarn test:e2eruns Jest (package.json), butapplication/frontend/src/test/basic-e2e.test.tsis fully commented out (legacy Puppeteer).github/workflows/e2e.ymlis entirely commented out — E2E does not run in CIjest-puppeteer/puppeteerremain inpackage.jsonas dead tooling
Playwright in this repo is Python-only (application/prompt_client/ for embeddings/scraping). It is not the frontend E2E runner. make install-python must keep playwright install.
Two open PRs overlap on Cypress migration (see Pending merges):
- #729 — restore Cypress under
application/frontend/src/test/cypress/, re-enablee2e.yml - #774 — fuller migration: root
cypress.config.js,cypress/e2e/smoke.cy.js, stabilizedmake e2e, switchestest:e2etocypress run
Related: #523 (fix e2e tests).
Implementation instructions
0. Playwright guardrail (dependency — do first)
- Ensure
playwright installstays ininstall-python(Makefile) — required forapplication/prompt_client/ - Merge or cherry-pick branch
chore/playwright-install-guardrail(commit69049e36) before or as part of this work — documents the guardrail in Makefile + AGENTS.md - Do not remove Python Playwright when migrating frontend to Cypress
1. Document legacy Jest/Puppeteer coverage
Read application/frontend/src/test/basic-e2e.test.ts (commented) and record what routes/flows it covered. Historical coverage included:
| Flow | Route / behavior |
|---|---|
| Homepage search UI | / — #SearchBar visible, contains "Search" |
| No-results search | / → search asdf → "No results match your search term" |
| Successful free-text search | / → search crypto → results with standards + CREs |
| Standard browse | /node/standard/ASVS — heading, pagination, section link, external reference, CRE link |
| CRE search by ID | / → search 558-807 → CRE title, nested accordion |
| CRE filter (case-insensitive) | /cre/558-807?applyFilters=true&filters=asvs and filters=ASVS |
| Smartlink redirect | /smartlink/standard/CWE/1002 → /node/standard/CWE/sectionid/1002; /smartlink/standard/CWE/404 → external CWE URL |
2. Migrate to Cypress
- Use fix(e2e): complete Cypress migration and stabilize make e2e for #523 #774 as the base (Makefile
e2efixes, rootcypress.config.js, smoke suite,package.jsonscripts) - Cherry-pick anything still useful from #729 if not duplicated
-
package.json:test:e2e→cypress run; addcypress:open/cypress:run; addcypressdevDependency - Root
cypress.config.js+cypress/e2e/suite (start with smoke, expand toward legacy coverage) - Remove obsolete
cypress.jsonand commented/deletedbasic-e2e.test.ts -
make e2e: deterministic Flask on127.0.0.1:5000, readiness wait, trap cleanup (from fix(e2e): complete Cypress migration and stabilize make e2e for #523 #774) - Prefer stable selectors (
form#search-bar, semantic roles) over brittle CSS chains - Close fix(e2e) : restore Cypress setup and add smoke test #729 as superseded once consolidated PR merges
3. Wire Cypress into CI
- Re-enable
.github/workflows/e2e.yml(or equivalent job) so PRs run Cypress smoke E2E - Fix YAML indentation/structure (both fix(e2e) : restore Cypress setup and add smoke test #729 and fix(e2e): complete Cypress migration and stabilize make e2e for #523 #774 drafts need review — current
e2e.ymlon main is fully commented) - Ensure deploy workflows (
deploy.yml,deploy-staging.yml) can depend on a greenTest-e2ejob again
4. Keep Python Playwright separate
- Do not conflate Cypress (frontend) with Python Playwright (embeddings/scraping)
- Python tests under
application/tests/that use Playwright (e.g.prompt_client_pdf_embeddings_test.py, embedding registration tests) must still pass
5. Cleanup (in scope or follow-up PR)
- Remove or fully replace deprecated Jest E2E config (
jest-puppeteer,puppeteerinpackage.json) without leaving dead tooling - Document local run instructions (see success criteria)
Success criteria
All must pass before closing this issue:
- Route/feature coverage at least equivalent to historical Jest/Puppeteer E2E — minimum smoke (homepage search form, search →
/search/{term}, browse/root_cres); stretch goal: port the flows in the table above (standard browse, CRE search/filter, smartlink) - Clean code: follows existing frontend conventions; no flaky tests; sensible selectors; documented how to run locally (
make e2e,yarn cypress:open) - E2E restored in CI: Cypress job green on PRs (
.github/workflows/e2e.ymlor equivalent) - Python Playwright tests still run and pass —
playwright installinmake install-pythonunchanged; embedding/scraping tests unaffected -
make frontend/yarn buildpasses - README or AGENTS.md notes how to run Cypress locally
- Deprecated Jest E2E tooling removed or fully replaced — no commented-out Puppeteer suite, no
test:e2e→jeston main -
make lintpasses -
make e2epasses locally (Cypress smoke: 3+ tests green) - Only one open Cypress migration PR; #729 closed as superseded
Pending merges
| Item | Status |
|---|---|
chore/playwright-install-guardrail (69049e3) |
Remote branch exists; no open PR; not on main |
| #774 | Open — recommended base for consolidated work |
| #729 | Open — supersede/close after consolidation |
| #732 | Open — Cypress Makefile integration (stale, Test check failing) |
.github/workflows/e2e.yml on main |
Fully commented out — E2E not in CI |
PRs to merge/close
| PR | Action |
|---|---|
| #774 | Base for consolidated migration (after playwright guardrail) |
| #729 | Close as superseded |
chore/playwright-install-guardrail |
Open PR and merge first (or include in consolidated PR) |
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
good first issueGood for newcomersGood for newcomershelp wantedExtra attention is neededExtra attention is needed
Activity
northdpole commentedon Jul 8, 2026
Playwright guardrail commit on branch
chore/playwright-install-guardrail(69049e3) — merge before or as part of the consolidated Cypress PR.northdpole commentedon Jul 9, 2026
Maintainer update
Labels: Added
good first issueandhelp wanted— this is now tagged for newcomers.Issue body: Refreshed with implementation instructions (legacy Jest/Puppeteer coverage table, Cypress migration steps, CI wiring) and expanded success criteria.
Anything pending merge?
chore/playwright-install-guardrail(69049e3)main. Should be PR'd and merged before or bundled with the Cypress work soplaywright installguardrail docs land.make e2efixes). CI green (Test, Lint, CodeQL). Does not re-enablee2e.yml.e2e.ymlbut workflow YAML needs fixes. Supersede after consolidation..github/workflows/e2e.ymlonmainBottom line: Yes — playwright guardrail branch needs a PR; #774 (and/or a new consolidated PR) plus CI workflow re-enable are pending before this issue can close.
DevHusnainAi commentedon Jul 17, 2026
Hi @northdpole ! I would love to work on consolidating the Cypress migration (#967). I have a strong background in server-side automation, Docker/Makefiles, and full-stack web environments. I will follow the implementation guide exactly: bundle the playwright install guardrail commit (69049e3), use #774 as the base, port the legacy coverage flows, and fix the .github/workflows/e2e.yml CI wiring. Can you please assign this to me
northdpole commentedon Jul 17, 2026
thanks for the offer, done, excited to see what you can do :-D
we essentially need to port the old jest tests to cypress and optionally extend them to achieve coverage of all features
DevHusnainAi commentedon Jul 17, 2026
Thanks @northdpole ! I've already set up the workspace locally, pulled in the playwright install guardrail commit, and merged #774 as the base.
I am currently cleaning up a couple of minor merge conflicts in the local configs. Once done, I will focus entirely on porting the old Jest/Puppeteer flows over to Cypress and verifying them against a local Flask server target. I will update you as soon as the baseline suites are green!
ci(e2e): seed e2e db via create_all, restore Cypress CI
test(e2e): port legacy jest/puppeteer flows to cypress
chore(e2e): remove dead puppeteer/jest-puppeteer tooling
docs: document local cypress run [ci skip]
docs: document local cypress run
DevHusnainAi commentedon Jul 18, 2026
Hi @northdpole 👋 — this is the consolidated Cypress migration for #967, ready for review.
Here's how I approached it. I started from #774 as the base and bundled the playwright-install guardrail so those docs land here. When I re-enabled e2e.yml and ran it, CI was still red — so I dug into why rather than just patching around it. Two things: the branch was a couple commits behind main which left two Alembic heads (so flask db upgrade bailed with "Multiple head revisions"), and more importantly the e2e job was building the SQLite cache from migrations instead of the models. Migrations are the Postgres path and were missing cre.document_metadata, so upstream_sync died with no such column. Your pgvector migration's own docstring pointed me the right way — SQLite/CI is meant to use create_all.
So the fix was: merge main for a single head, and add a make e2e-db target that seeds the schema from the models (create_all) and then loads the real graph with upstream_sync. The e2e job now uses that instead of migrate-upgrade, and it doesn't run playwright install since Cypress brings its own browser — Python Playwright is completely untouched, install-python still has it, and the Python test suite stays green.
For coverage I ported all the flows from the old Jest/Puppeteer suite — homepage/search (hit + no-results), ASVS standard browse, CRE by id + the case-insensitive filter, and smartlink (internal + external CWE redirect). Every spec asserts on real data so it goes red on an empty DB, not just on page chrome.
I ran it end-to-end on my fork and everything's green — Test-e2e passes 11/11, plus Test and Lint (run here). One thing worth flagging: the e2e job downloads the full CRE graph via upstream_sync, which took ~5 min in CI (the whole job ~10 min). Happy to switch to a cached or fixture-based seed if you'd prefer something lighter on opencre.org.
#729 and #732 are already closed, so once this merges it should be the only Cypress PR left. Would love your feedback — thanks for assigning it to me! 🙏
ci(e2e): pin checkout creds and clarify e2e-db docs
DevHusnainAi commentedon Jul 18, 2026
Fixed both CodeRabbit points in 14bdb00 — persist-credentials: false on the e2e checkout, and the README now says make e2e-db rebuilds the cache each run (not one-time). Left a reply on the Makefile thread explaining that one's a false positive (.ONESHELL).
DevHusnainAi commentedon Jul 20, 2026
Hey @northdpole, hope you're doing well. Just wanted to see if you've had a moment to review this. Let me know if everything looks good or if there’s anything I should update on my side!
northdpole commentedon Aug 7, 2026
Added end-of-August maintainer fallback: # (finish Cypress e2e ourselves if #984 has not landed).
northdpole commentedon Aug 7, 2026
Fallback tracker: #1007 (end of August 2026).
style(e2e): prettier-format standard.cy.js pagination chain (OWASP#967)
northdpole commentedon Aug 12, 2026
Note: closed the end-of-August fallback tracker (#1007). Deadlines for picking up remaining Cypress work (if needed) will be handled as a maintainer reminder outside GitHub issues — active path remains this issue + #984.
fix(e2e): run make e2e recipe under bash so set -o pipefail works in …
fix(e2e): consolidate frontend E2E to Cypress and restore CI (#967) (#…