From il
Orchestrate a Cypress→Playwright migration — audit, bulk conversion with gotchas enforcement, TypeScript gate, and phased validation
How this command is triggered — by the user, by Claude, or both
Slash command
/il:convert-cypress-playwright <cypress-repo-path> <playwright-target-path> [--jira <TICKET>] [--phase scaffold|bulk|audit|validate|all] [--scope <domain,domain>] [--skip-baseline] [--skip-audits] [--quiet-jira]sonnetFiles this command reads when invoked
The summary Claude sees in its command listing — used to decide when to auto-load this command
# Convert Cypress to Playwright You are orchestrating a Cypress→Playwright migration. This command mirrors the phased structure of `/il:generate-code` but specializes every phase for the unique risks of a test-suite migration: silent data corruption on response parsing, strict-mode violations, BrowserContext isolation, parallelism collisions, and ~30 other documented gotchas. Follow these phases exactly. **Authoritative knowledge source:** the `cypress-to-playwright` skill plus the QA-maintained Confluence rulebook it points to (`weldnorthed.atlassian.net` page `134491275317`). Invoke the...
You are orchestrating a Cypress→Playwright migration. This command mirrors the phased structure of /il:generate-code but specializes every phase for the unique risks of a test-suite migration: silent data corruption on response parsing, strict-mode violations, BrowserContext isolation, parallelism collisions, and ~30 other documented gotchas. Follow these phases exactly.
Authoritative knowledge source: the cypress-to-playwright skill plus the QA-maintained Confluence rulebook it points to (weldnorthed.atlassian.net page 134491275317). Invoke the skill and fetch the Confluence page before any conversion work — the page contains the full mapping tables, gotchas catalog, and pre-conversion audit checklist. The orchestrator's job is to apply them phase-by-phase and coordinate agents.
Parse $ARGUMENTS for:
Required positional arguments:
Optional flags:
--jira <TICKET-KEY> — link the migration to a Jira ticket for commentary (e.g., --jira QE-456). Without this, no Jira comments are posted.--phase scaffold|bulk|audit|validate|all — run only a specific phase. Default: all. Use for resuming partial migrations.--scope <domain,domain> — restrict conversion to specific domain folders (e.g., --scope api,auth). Default: all domains.--skip-baseline — skip Phase 1.6 Cypress baseline capture. Default is to require a baseline captured the same day as runtime validation.--skip-audits — skip Phase 5 quality audits (TypeScript, migration audit, gotchas verification). Default: run them.--quiet-jira — suppress all automatic Jira commentary. Only used when --jira is set.If either required argument is missing, use AskUserQuestion to collect it. Explain what each path should contain.
Use the Skill tool to invoke cypress-to-playwright before any analysis. Then fetch the QA-maintained Confluence rulebook — this is the single source of truth for mappings, gotchas, and the pre-conversion audit checklist:
mcp__plugin_il_atlassian__getConfluencePage({
cloudId: "weldnorthed.atlassian.net",
pageId: "134491275317",
contentFormat: "markdown"
})
Store the page content as rulebook for reuse in subagent prompts. Every subsequent phase references gotchas by their numbered section from that page (e.g., "gotcha §9"). Do not paraphrase the rulebook into agent prompts — pass the fetched content verbatim so agents work from the authoritative source.
Use Bash (ls <cypress-repo-path>) to confirm the Cypress repo path exists. Detect:
cypress/e2e/, cypress/integration/, or custom)cypress/support/, cypress/services/, cypress/pages/, etc.)cypress.config.ts / cypress.config.jspackage.json — capture current Cypress version, Node version, TypeScript versionCheck the Playwright target:
playwright.config.ts — read it to understand current state; Phase 2 will verify or augmenttests/ — treat as in-progress migration; Phase 2 detects what's already converted--jira provided)If --jira <ticket> was provided AND --quiet-jira was NOT:
mcp__plugin_il_atlassian__getJiraIssue to fetch the ticket.mcp__plugin_il_atlassian__getAccessibleAtlassianResources to resolve the Atlassian Cloud ID (UUID, not hostname). Store as resolved cloud ID — use this in every comment call.Unless --skip-baseline was provided, require a fresh Cypress baseline before Phase F runtime validation. Use AskUserQuestion to ask:
The Cypress→Playwright migration requires a Cypress baseline captured the same day you run Playwright validation, to avoid credential/data drift masking as migration bugs (see gotcha §4). Have you already captured a fresh Cypress baseline today? If not, we'll pause before Phase 6 to let you run it.
Record the answer. If NO, set a flag to pause before runtime validation.
Context Summary
───────────────
Cypress repo: <path> (<spec count> specs, <test count> it() blocks, <domain count> domains)
Playwright target: <path> (<fresh|partial|in-progress>)
Jira ticket: <key or "none">
Scope: <all domains | filtered list>
Phase: <all | specific phase>
Baseline: <captured today | needed before Phase 6 | skipped>
Ask the user to confirm before proceeding.
Delegate the Cypress codebase audit to a subagent to keep the orchestrator's context clean. This agent scans the Cypress repo for every gotcha pattern and produces a quantified findings table.
Use Agent with:
subagent_type: "Explore"name: "cypress-auditor"description: "Audit Cypress repo for migration gotchas"The prompt must include:
You are auditing a Cypress test repository before a Playwright migration. Your job is to produce a quantified findings table that drives migration planning.
## Repo path
<cypress repo path>
## Required Reading
Before starting, invoke the `cypress-to-playwright` skill via the `Skill` tool. The authoritative audit checklist lives in Confluence — the orchestrator has already fetched it and is providing it below as **rulebook**. Use the "Pre-Conversion Audit" / "Gotchas Checklist" sections of that rulebook for the exact grep commands and output template.
<rulebook>
<paste full Confluence page content here>
</rulebook>
## Your Task
1. Run every inventory command in the rulebook's audit section (suite inventory, per-gotcha counts, credential audit, shared-mutable-state audit).
2. For each gotcha category with a non-zero count, record:
- Count (total matches and unique files)
- Up to 5 example file paths
- Planned Playwright approach (1 sentence, referencing the gotcha number from the rulebook)
3. Produce the credential findings table (credential → file count).
4. Produce the parallelism recommendation paragraph.
5. List every Cypress test currently using Applitools, cy.task, cy.origin, cy.getIframeBody, or `cy.session` — these categories typically become skip list entries.
## Required Output (Markdown)
Return a single markdown document with these sections. Do NOT write it to a file:
- **Suite Inventory** — test counts, file counts, domain list, currently-skipped count
- **Gotcha Findings Table** — one row per applicable gotcha from the rulebook
- **Credential Audit** — per-credential file count sorted descending
- **Shared Mutable State** — mutating helpers and the specs that call them
- **Parallelism Recommendation** — one paragraph with a concrete `workers` / account-provisioning recommendation
- **Skip List Candidates** — tests that should be temporarily skipped during conversion, grouped by blocker
Return the full markdown document as your text response. No additional commentary. No files created.
Store the audit document. Present the summary (inventory counts + top 3 gotcha findings + parallelism recommendation) to the user. Ask for confirmation before proceeding.
If --jira was set and --quiet-jira was NOT, decide whether the audit surfaced anything worth a Jira comment. Things worth commenting on:
@applitools/eyes-playwright is integrated in a follow-up"Use mcp__plugin_il_atlassian__addCommentToJiraIssue with the resolved cloud ID, contentFormat: "markdown", and the ticket key.
Use EnterPlanMode. The plan must cover the specific axes a test-suite migration needs:
Scaffold (if target is fresh)
playwright.config.ts — testDir, workers, fullyParallel, timeout, use.baseURL, reportertsconfig.json — path aliases (@pages/*, @services/*, @fixtures/*, etc.) — see the rulebook's scaffolding sectionsrc/{aws,fixtures,mocks,pages,services,support,types,util}/ + tests/<domain>/.env.dev, .env.staging, etc.Infrastructure Port
page.context().request for login — gotcha §14)cy.task registration — see mappings)Bulk Conversion Scope
Skip List
playwright-skipped-tests-report.mdTypeScript Gate Strategy
npx tsc --noEmit produces 0 errors after bulk conversionTimeout & Parallelism Config
timeout starting value (45-60s)test.describe.configure({ timeout }) for heavy-setup suites (identify candidates from Phase 2 — any suite with >20s of hard waits or heavy API setup)workers and fullyParallel decisions per the Phase 2 recommendationRuntime Validation Phases
@smoke tagSuccess Criteria
npx tsc --noEmit = 0 errorsit() has a Playwright test() or explicit test.skip(); DIFF per file = 0 or positivecy.wait elimination, and selector modernization are deferred — see the skill's "Cleanup is scope B" guardrail and the rulebook's §15.src/ + tests/ split is non-negotiable (gotcha §8).workers: 1 is correct until credentials/data are isolated.The user must explicitly approve the plan before proceeding. Use ExitPlanMode when ready for review.
If --jira was set and --quiet-jira was NOT, comment on the ticket after the user approves. Worth commenting on:
Use TeamCreate to create a team named cypress-playwright-conversion-<target repo> (basename of the Playwright target path) — scoping to the target repo avoids collisions between concurrent sessions. Reuse this exact name for all team_name references below and the final TeamDelete. If the team already exists, do NOT silently reuse it — pause and ask the user.
Use TaskCreate to create: "Bulk-convert Cypress suite to Playwright per approved plan"
Reuse the code-generator agent — it already knows how to follow a plan, respects existing codebase patterns, and honors anti-hallucination guardrails. Spawn with:
Use Agent tool with:
subagent_type: "code-generator"
team_name: "cypress-playwright-conversion-<target repo>"
name: "converter"
The agent's prompt MUST include all of the following (paste full content inline):
Skill tool to invoke the cypress-to-playwright skill. The authoritative rulebook (mappings table + gotchas catalog) is the QA-maintained Confluence page 134491275317 on weldnorthed.atlassian.net — the orchestrator has fetched it and is providing the full content below as rulebook. Every conversion must apply the relevant rules — reference gotchas by number in commit messages and comments when non-obvious. <paste full Confluence page content here>"--scope filternpx tsc --noEmit from the Playwright target root. The output target is zero errors. Iterate until that gate passes. Do NOT proceed to skip-list documentation until tsc is clean."test.skip(...) in Playwright with the same title, and append an entry to playwright-skipped-tests-report.md grouped by blocker category per the skip-report template in the rulebook."playwright-migration-audit.md — a per-file table of Cypress it() count vs Playwright test() count (including skips). DIFF column must be 0 or positive for every file."cy.wait(<ms>) as page.waitForTimeout(<ms>) as-is. Do NOT modernize waits, do NOT fix selector quality issues unless they are the pre-existing malformed selectors from gotcha §22. Migration is scope A; cleanup is scope B."Page, Locator, BrowserContext, or APIRequestContext, verify against node_modules/@playwright/test/index.d.ts or leave a TODO with a specific question."--jira set and --quiet-jira NOT set):You have access to mcp__plugin_il_atlassian__addCommentToJiraIssue to comment on <ticket key>. Use cloudId: "<resolved cloud ID>", contentFormat: "markdown", issueIdOrKey: "<ticket key>".
Comment when you encounter something worth documenting for humans reviewing this migration:
- **Surprising patterns**: "Found 12 specs with bare `//` XPath — all converted to CSS"
- **Non-mechanical decisions**: "Spec X uses cy.session with external identity provider — converted to storageState instead of inline login for Playwright"
- **Deferred TODOs**: "Left 3 TODOs for contenteditable editors that need `pressSequentially` helper — not in this scope"
- **Discoveries**: pre-existing Cypress bugs found during conversion
Do NOT post mechanical status or restate the plan. One comment per non-obvious discovery is the right cadence.
SendMessage with to: 'team-lead', a short summary (5-10 words), and the full report as message. Include: files created/modified count, tsc --noEmit final exit status, migration audit summary (files with DIFF ≠ 0), skip list summary (counts per blocker category), and any TODO or deviation notes. Mark your task as completed via TaskUpdate."Agent messages are delivered automatically. Do NOT poll. Wait for the converter's completion message.
Run git status and git diff --stat in the Playwright target. Record:
This delta goes to the reviewer in Phase 6 as factual context.
Skip if --skip-audits was specified. Otherwise run three audits in parallel.
Run git diff and git status from the Playwright target. Compile the changed-file list.
Dispatch three audits in parallel (multiple Agent calls in one response):
Audit A: TypeScript Gate
subagent_type: "Explore", name: "ts-gate"npx tsc --noEmit from <playwright target path>. Return the full output. Categorize every error: (1) missing import / wrong path, (2) missing method signature on ported helper, (3) any leakage, (4) actual type mismatch. Return a single JSON object: { exitCode, errorCount, byCategory: { ... }, topFiles: [...] }."Audit B: Migration Audit (Test Count Parity)
subagent_type: "Explore", name: "migration-audit"it() count to Playwright test() count per file. Read <cypress repo>/cypress/e2e/ and <playwright target>/tests/ recursively. For each pair of corresponding files, count: Cypress it(, Playwright test( (including test.skip(). Produce a table with columns: file, cypress_count, playwright_count, diff. DIFF must be 0 or positive (positive = previously-hidden gated tests now made explicit via test.skip). Return JSON: { totalCypress, totalPlaywright, filesWithNegativeDiff: [...], summary }."Audit C: Gotchas Verification
subagent_type: "Explore", name: "gotchas-audit"<path> for residual migration gotchas. Use the cypress-to-playwright skill and the QA-maintained Confluence rulebook (page 134491275317 on weldnorthed.atlassian.net) — the orchestrator has fetched it and is providing the full content below as rulebook. Use the bulk-detection one-liners from the rulebook's gotchas section. Run each detection command against the Playwright target (not the Cypress source). For every match, classify as: (a) legitimate (e.g., response.json() against a JSON endpoint) or (b) potential gotcha (e.g., response.json() against an endpoint the audit says returns raw text). Return JSON: { perGotcha: { '§1': { matches, potentialIssues }, '§2': {...}, ... }, topConcerns: [...] }. <paste full Confluence page content here>"For each audit:
The gate is simpler than the generic code-quality gate:
ts-gate.exitCode == 0 is mandatory. Non-zero is a hard block.filesWithNegativeDiff.length == 0 is mandatory. Negative diff means tests were dropped.beforeAll request), §4 (cookie strings), §9 (waitForResponse navigation), §14 (cy.request login).## Migration Quality Audit
**TypeScript Gate:** <PASS | FAIL (<N> errors)>
**Migration Audit:** <PASS | FAIL (<N> files with lost tests)>
**Gotchas Verification:** <clean | <N> potential issues across <M> gotcha categories>
### Critical Concerns
<enumerate CRITICAL-tier gotchas with file:line references>
### Full Report
<TypeScript error summary, per-category counts>
<Migration audit table (files with diff ≠ 0)>
<Gotchas audit — per-category match counts with (legitimate / potential) split>
If TS gate or migration audit fails, use AskUserQuestion:
If audits pass, proceed to Phase 6.
If Phase 1.6 flagged that no baseline was captured today, pause here. Ask the user:
Runtime validation requires a fresh Cypress baseline captured today. The reviewer will compare migration findings to this baseline to distinguish migration bugs from environment/data issues. Capture it now (from the Cypress repo) and confirm the pass/fail summary before we proceed.
Wait for confirmation and a baseline summary (pass count, fail count, date). Store for the reviewer.
Use TaskCreate to create: "Independent migration review"
Use Agent tool with:
subagent_type: "code-reviewer"
team_name: "cypress-playwright-conversion-<target repo>"
name: "reviewer"
Review Isolation: The reviewer's prompt must NOT include the converter's rationale or the approved plan. Pass only:
cypress-to-playwright skill. The ground-truth checklist is the QA-maintained Confluence rulebook (page 134491275317 on weldnorthed.atlassian.net) — the orchestrator has fetched it and is providing the full content below as rulebook. Evaluate every gotcha category from that page against the diff. <paste full Confluence page content here>"Read tool instructionsSendMessage with to: 'team-lead', a short summary, and the full review as message. Include verdict (APPROVE / REQUEST CHANGES / REJECT), findings by gotcha category with file:line references, confirmed vs disputed audit findings, and a runtime-readiness assessment. Mark your task as completed via TaskUpdate."Messages are delivered automatically.
Extract verdict, findings, and runtime-readiness assessment.
Next Steps — Phased Runtime Validation
1. API-only first:
npx playwright test --grep @api
Expected: ≥85% pass, all failures match the Cypress baseline from <date>.
2. Single UI login:
npx playwright test tests/auth/login.spec.ts
Expected: pass. Validates cookie/storageState wiring (gotcha §4, §14).
3. Smoke tag:
npx playwright test --grep @smoke
4. Full regression, per-domain, student last. For every failure:
a. Re-run the equivalent Cypress spec SAME DAY to separate migration bugs from env/data.
b. Cluster real failures into categories using the Confluence rulebook.
c. Fix by category in bulk, not one test at a time.
5. Cleanup passes (separate PRs, not this one):
- Hard waits → proper conditions (gotcha §15)
- Parallelism: provision accounts, then raise `workers` (gotcha §7)
- Applitools / visual — separate PR
TeamDelete.request fixture across many specs (§14). These suggest re-running Phase 3 with a revised plan.AskUserQuestion:
AskUserQuestion:
If --jira was set and --quiet-jira was NOT, post a final summary comment with: verdict, TypeScript gate status, migration audit test-count delta, top gotcha findings, and runtime-readiness assessment. Do NOT dump full reports — link the resolved cloud ID to where they live.
npx claudepluginhub imaginelearning/dp-claude-plugin --plugin il