Skip to content

Feat/playwright runner - #2

Open
Octagon-simon wants to merge 15 commits into
mainfrom
feat/playwright-runner
Open

Feat/playwright runner#2
Octagon-simon wants to merge 15 commits into
mainfrom
feat/playwright-runner

Conversation

@Octagon-simon

Copy link
Copy Markdown
Owner

No description provided.

Octagon-simon and others added 12 commits June 24, 2026 22:17
Recognise and run Playwright as a test runner alongside the unit runners.
Adds @playwright/test detection, a parser for the JSON reporter (resolving
spec paths against the report's rootDir, not cwd), best-effort config
parsing for baseURL/testDir/webServer, and per-file run commands. Playwright
is opt-in only (never auto-detected over Vitest/Jest); detectEnvironment
gains type overloads so the no-config path never yields it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add `lacuna generate --e2e` and `lacuna fix --e2e`, a browser-layer
counterpart to the unit/integration agent.

generate --e2e:
- Route discovery for Next.js (app + pages router) and React Router,
  dependency-gated so a Vite app with src/pages/ isn't misread as Next.
- Per-route DOM snapshot via the project's own Playwright (the webServer
  starts the app once): aria tree + data-testids (with tag/role),
  redirect-aware.
- DOM-aware spec generation with strict selector discipline (role/label/
  testid only, no CSS/XPath, no arbitrary waits, no forced interactions,
  post-action validation, auth/isolation rules), priority-ordered
  truncation, parallel workers with the live panel, and flake confirmation.
  A spec that never goes green is deleted, never left broken.

fix --e2e:
- Repairs failing specs with a failure-analysis prompt (selector drift,
  strict-mode violations, sync, redirect) driven by a FRESH snapshot of
  the failing route, with an explicit repair-priority order that never
  weakens assertions to force a pass.

--inject-testids (opt-in, the only path that edits app source):
- Adds data-testid to page sources, then VERIFIES against a re-snapshot:
  a testid is kept only if it lands on an actual interactive element,
  else the source is reverted. So a non-forwarding or custom component
  leaves source untouched regardless of prompt guidance.
- Library-aware (lib/flows/ui-libraries.ts + resolve-libraries.ts):
  detects the UI library by following the import chain, including barrel
  re-exports, so a custom component behind a barrel isn't mistaken for a
  library one; falls back to installed deps only when the chain can't be
  resolved.

The agent loop, provider, retry/oscillation machinery, and result parser
are shared with the unit path; target selection, context, and verification
differ.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
README End-to-end testing section, landing-page feature card, and a full
project-map pass: the runner, src/lib/flows/, the e2e-loop, the prompt
suite, the data flows, and the E2E invariants.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Resolved conflicts:
- src/agent/fix-loop.ts: combined main's keep-best (write bestCode on
  exhaustion/oscillation, report bestPassCount) with the branch's E2E
  helperBackups restore — both run; helperBackups is a no-op for unit fixes.
- project-map.md: merged the fix-loop entry (keep-best + targeted --file hint
  + scoped-per-tsconfig type-check from main; E2E mode paragraphs from branch)
  and took main's loop.ts entry (cause-aware retry wording).
- README.md: auto-merged (keep-best + governing-tsconfig wording alongside the
  E2E docs); also updated the fix-side diagram to "keep the best attempt".

main brings: patch-anchor robustness, fix-loop keep-best, monorepo type-check
via governing tsconfig, and the v0.2.4 release bump.
E2E runs needed @playwright/test but nothing helped the user get it —
`generate --e2e` just printed "none was found" and stopped, and `init`
never mentioned Playwright at all.

- init: for React/Next.js projects, add an opt-in step after unit setup —
  "Set up end-to-end (Playwright) testing?" (default no) — that installs
  @playwright/test + browser binaries. This is the consistent home for a
  heavy, explicit dependency, matching how init handles the unit-test deps.
- playwright.ts: add installPlaywright() and ensurePlaywrightForRun(), the
  shared guard for the e2e/fix loops. When @playwright/test is missing it
  prints the exact install command (+ an `lacuna init` pointer) and, only
  when interactive (TTY, not CI) and not --dry-run, offers a confirm+install
  inline. The guard runs before the worker pool spawns, so the prompt never
  races workers; in CI/non-TTY it prints the hint and returns without hanging.
- e2e-loop.ts / fix-loop.ts: replace the dead-end "none was found" error with
  ensurePlaywrightForRun (offerInstall: !dryRun).
- Docs: README E2E section + project-map (init, playwright, e2e/fix loops).
… auto-refresh

E2E generation now recovers app workflows and asserts real outcomes:
- FlowMap (src/lib/flows/flowmap.ts): static AST control→outcome map (toast/
  redirect/modal), v2 one-hop cross-file resolution; fed per-control into the
  prompt so each action asserts its own result. Open-sourced:
  https://github.com/Octagon-simon/flowmap
- Explorer (--deep): walks multi-step flows; drives ARIA comboboxes
  (widget-driver: https://github.com/Octagon-simon/widget-driver), captures the
  real success/validation toast, P6 locator typing, section/nav feature
  boundaries, live per-probe progress.
- Auth: auto-refresh stale/missing sessions (refreshAuthState), IndexedDB
  capture, signed-in readiness wait.
- Coverage guards: never go green by deleting tests; keep-best by passing-test
  count across generate AND fix (countTestFunctions).
- Assertion quality: ban persistent-landmark/taut
- Fixes: shared-test 30s timeout truncation (scaled test.setTimeout),
  networkidle on realtime apps, toast-junk capture, e2e fix no longer reads the
  unit mock / suggests --fix-polluters.
- Docs: wiki/, lessons post, README + project-map updates.
Bring the patch-coverage (@diff) + class-aware skeleton work from main into
the Playwright/E2E branch. Both feature sets are kept side by side:

- generate.ts: unified flags — E2E (--e2e/--route/--max-routes/--inject-testids
  /--deep) alongside patch-coverage (@diff positional, --improve). E2E path
  branches first (route-driven, no unit runner); the @diff/dir/file paths follow.
- fix-loop.ts: import block reconciled to include BOTH E2E (playwright, snapshot,
  spec-helpers, e2e prompts) and the scope/patch/format symbols; the merged body
  keeps the E2E repair path and the --types/scope repair path.
- detector.ts: scoped/related coverage commands + Playwright runner coexist.
- project-map.md / README.md: rows document both features.

Verified: tsc clean, npm run build succeeds, `generate @diff` and `generate
--e2e` both execute, patch-coverage unit checks pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The E2E generate path called showStarNudge() directly, so a run that
generated some specs AND failed others still showed the "thanks, star us"
nudge instead of the issue-report nudge — the exact double/contradictory
outcome showOutcomeNudge exists to prevent. Route it through
showOutcomeNudge(specsGenerated, specsFailed, 'generate') like the unit
path, which shows the issue nudge when failed > succeeded, else the star.
showStarNudge is no longer imported directly here.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gitguardian

gitguardian Bot commented Jul 6, 2026

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
34577921 Triggered Generic Password 6e87a1b src/agent/e2e-loop.ts View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

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