Migrate from Cypress or Selenium to Playwright. Use when user mentions "cypress", "selenium", "migrate tests", "convert tests", "switch to playwright", "move from cypress", or "replace selenium".
19392f7Interactive migration from Cypress or Selenium to Playwright with file-by-file conversion.
$ARGUMENTS can be:
"from cypress" — migrate Cypress test suite"from selenium" — migrate Selenium/WebDriver testsUse Explore subagent to scan:
cypress/ directory or cypress.config.ts → Cypressselenium, webdriver in package.json deps → Selenium.py test files with selenium imports → Selenium (Python)Count files and categorize:
Migration Assessment:
- Total test files: X
- Cypress custom commands: Y
- Cypress fixtures: Z
- Estimated effort: [small|medium|large]
| Size | Files | Approach |
|---|---|---|
| Small (1-10) | Convert sequentially | Direct conversion |
| Medium (11-30) | Batch in groups of 5 | Use sub-agents |
| Large (31+) | Use /batch | Parallel conversion with /batch |
Run /pw:pw-init first if Playwright isn't configured.
For each file, apply the appropriate mapping:
Load cypress-mapping.md for complete reference.
Key translations:
cy.visit(url) → page.goto(url)
cy.get(selector) → page.locator(selector) or page.getByRole(...)
cy.contains(text) → page.getByText(text)
cy.find(selector) → locator.locator(selector)
cy.click() → locator.click()
cy.type(text) → locator.fill(text)
cy.should('be.visible') → expect(locator).toBeVisible()
cy.should('have.text') → expect(locator).toHaveText(text)
cy.intercept() → page.route()
cy.wait('@alias') → page.waitForResponse()
cy.fixture() → JSON import or test data file
Cypress custom commands → Playwright fixtures or helper functions
Cypress plugins → Playwright config or fixtures
before/beforeEach → test.beforeAll() / test.beforeEach()
Load selenium-mapping.md for complete reference.
Key translations:
driver.get(url) → page.goto(url)
driver.findElement(By.id('x')) → page.locator('#x') or page.getByTestId('x')
driver.findElement(By.css('.x')) → page.locator('.x') or page.getByRole(...)
element.click() → locator.click()
element.sendKeys(text) → locator.fill(text)
element.getText() → locator.textContent()
WebDriverWait + ExpectedConditions → expect(locator).toBeVisible()
driver.switchTo().frame() → page.frameLocator()
Actions → locator.hover(), locator.dragTo()
During conversion, upgrade selectors to Playwright best practices:
#id → getByTestId() or getByRole().class → getByRole() or getByText()[data-testid] → getByTestId()test.extend()After converting each file:
npx playwright test <converted-file> --reporter=list
Fix any compilation or runtime errors before moving to the next file.
After all files are converted:
package.jsoncypress.config.ts, etc.)Ask user before deleting anything.
Copy a source-pinned command for your client. You run it yourself.
Destination: .claude/skills/migrate · pinned to the source commit
# Run from your project root
git clone https://github.com/alirezarezvani/claude-skills.git .skillboard-tmp
git -C .skillboard-tmp checkout 19392f7a08264ed00486a251f5b2098321771f94
mkdir -p ".claude/skills"
cp -r ".skillboard-tmp/.gemini/skills/migrate" ".claude/skills/"
rm -rf .skillboard-tmpReview the source before running. This copies files into your project; it is not a one-click install and does not verify runtime safety.
sudo apt update && sudo apt install -y gitnpm install -g @anthropic-ai/claude-code# Run from your project root
git clone https://github.com/alirezarezvani/claude-skills.git .skillboard-tmp
git -C .skillboard-tmp checkout 19392f7a08264ed00486a251f5b2098321771f94
mkdir -p ".claude/skills"
cp -r ".skillboard-tmp/.gemini/skills/migrate" ".claude/skills/"
rm -rf .skillboard-tmpDestination: .claude/skills/migrate
Scanner static-checks@0.1.0 · commit 19392f7a0826. Static checks cannot prove runtime safety – review the source and the exact diff before installing. How checks work.
No static rules matched. This is not a safety guarantee.