Migrate to Playwright
Migrate from Cypress or Selenium to Playwright.
How to use it
Claude Code
- Run the line below. It pulls the whole folder into
~/.claude/skills/migrate, including the files SKILL.md points to. - Describe your job in plain words. Claude Code follows the skill from there.
npx degit alirezarezvani/claude-skills/engineering-team/playwright-pro/skills/migrate#main ~/.claude/skills/migrateFor one project only, change the path to .claude/skills/migrate. This skill also uses package.json, cypress-mapping.md, selenium-mapping.md — copying SKILL.md alone won't be enough. See the folder on GitHub.
Claude (web or desktop app)
- On this page open ⋯ → Download .md.
- Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
- Pick the file and Save. Claude shows the name and description and runs a security scan.
- Check the skill is switched on.
- Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
- ChatGPT: make a Project and paste it into Instructions.
- Neither? Paste it at the top of a new chat — it works for that chat.
Not working?
- Check which app you pasted it into — the steps above name the right one.
- Some skills need the paid tier of Claude or ChatGPT.
Paste into Claude, ChatGPT or Cursor.
Source of Migrate to Playwright
Show the full text136 lines
| name | description |
|---|---|
| migrate | >- 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". |
Migrate to Playwright
Interactive migration from Cypress or Selenium to Playwright with file-by-file conversion.
Input
$ARGUMENTS can be:
"from cypress"— migrate Cypress test suite"from selenium"— migrate Selenium/WebDriver tests- A file path: convert a specific test file
- Empty: auto-detect source framework
Steps
1. Detect Source Framework
Use Explore subagent to scan:
cypress/directory orcypress.config.ts→ Cypressselenium,webdriverinpackage.jsondeps → Selenium.pytest files withseleniumimports → Selenium (Python)
2. Assess Migration Scope
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 |
3. Set Up Playwright (If Not Present)
Run /pw:pw-init first if Playwright isn't configured.
4. Convert Files
For each file, apply the appropriate mapping:
Cypress → Playwright
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()
Selenium → Playwright
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()
5. Upgrade Locators
During conversion, upgrade selectors to Playwright best practices:
#id→getByTestId()orgetByRole().class→getByRole()orgetByText()[data-testid]→getByTestId()- XPath → role-based locators
6. Convert Custom Commands / Utilities
- Cypress custom commands → Playwright custom fixtures via
test.extend() - Selenium page objects → Playwright page objects (keep structure, update API)
- Shared helpers → TypeScript utility functions
7. Verify Each Converted File
After converting each file:
npx playwright test <converted-file> --reporter=list
Fix any compilation or runtime errors before moving to the next file.
8. Clean Up
After all files are converted:
- Remove Cypress/Selenium dependencies from
package.json - Remove old config files (
cypress.config.ts, etc.) - Update CI workflow to use Playwright
- Update README with new test commands
Ask user before deleting anything.
Output
- Conversion summary: files converted, total tests migrated
- Any tests that couldn't be auto-converted (manual intervention needed)
- Updated CI config
- Before/after comparison of test run results
| 1 | |
| 2 | name "migrate" |
| 3 | description >- |
| 4 | Migrate from Cypress or Selenium to Playwright. Use when user mentions |
| 5 | "cypress", "selenium", "migrate tests", "convert tests", "switch to |
| 6 | playwright", "move from cypress", or "replace selenium". |
| 7 | |
| 8 | |
| 9 | # Migrate to Playwright |
| 10 | |
| 11 | Interactive migration from Cypress or Selenium to Playwright with file-by-file conversion. |
| 12 | |
| 13 | ## Input |
| 14 | |
| 15 | `$ARGUMENTS` can be: |
| 16 | `"from cypress"` — migrate Cypress test suite |
| 17 | `"from selenium"` — migrate Selenium/WebDriver tests |
| 18 | A file path: convert a specific test file |
| 19 | Empty: auto-detect source framework |
| 20 | |
| 21 | ## Steps |
| 22 | |
| 23 | ### 1. Detect Source Framework |
| 24 | |
| 25 | Use `Explore` subagent to scan: |
| 26 | `cypress/` directory or `cypress.config.ts` → Cypress |
| 27 | `selenium`, `webdriver` in `package.json` deps → Selenium |
| 28 | `.py` test files with `selenium` imports → Selenium (Python) |
| 29 | |
| 30 | ### 2. Assess Migration Scope |
| 31 | |
| 32 | Count files and categorize: |
| 33 | |
| 34 | |
| 35 | Migration Assessment: |
| 36 | - Total test files: X |
| 37 | - Cypress custom commands: Y |
| 38 | - Cypress fixtures: Z |
| 39 | - Estimated effort: [small|medium|large] |
| 40 | |
| 41 | |
| 42 | | Size | Files | Approach | |
| 43 | |---|---|---| |
| 44 | | Small (1-10) | Convert sequentially | Direct conversion | |
| 45 | | Medium (11-30) | Batch in groups of 5 | Use sub-agents | |
| 46 | | Large (31+) | Use `/batch` | Parallel conversion with `/batch` | |
| 47 | |
| 48 | ### 3. Set Up Playwright (If Not Present) |
| 49 | |
| 50 | Run `/pw:pw-init` first if Playwright isn't configured. |
| 51 | |
| 52 | ### 4. Convert Files |
| 53 | |
| 54 | For each file, apply the appropriate mapping: |
| 55 | |
| 56 | #### Cypress → Playwright |
| 57 | |
| 58 | Load `cypress-mapping.md` for complete reference. |
| 59 | |
| 60 | Key translations: |
| 61 | |
| 62 | cy.visit(url) → page.goto(url) |
| 63 | cy.get(selector) → page.locator(selector) or page.getByRole(...) |
| 64 | cy.contains(text) → page.getByText(text) |
| 65 | cy.find(selector) → locator.locator(selector) |
| 66 | cy.click() → locator.click() |
| 67 | cy.type(text) → locator.fill(text) |
| 68 | cy.should('be.visible') → expect(locator).toBeVisible() |
| 69 | cy.should('have.text') → expect(locator).toHaveText(text) |
| 70 | cy.intercept() → page.route() |
| 71 | cy.wait('@alias') → page.waitForResponse() |
| 72 | cy.fixture() → JSON import or test data file |
| 73 | |
| 74 | |
| 75 | **Cypress custom commands** → Playwright fixtures or helper functions |
| 76 | **Cypress plugins** → Playwright config or fixtures |
| 77 | **`before`/`beforeEach`** → `test.beforeAll()` / `test.beforeEach()` |
| 78 | |
| 79 | #### Selenium → Playwright |
| 80 | |
| 81 | Load `selenium-mapping.md` for complete reference. |
| 82 | |
| 83 | Key translations: |
| 84 | |
| 85 | driver.get(url) → page.goto(url) |
| 86 | driver.findElement(By.id('x')) → page.locator('#x') or page.getByTestId('x') |
| 87 | driver.findElement(By.css('.x')) → page.locator('.x') or page.getByRole(...) |
| 88 | element.click() → locator.click() |
| 89 | element.sendKeys(text) → locator.fill(text) |
| 90 | element.getText() → locator.textContent() |
| 91 | WebDriverWait + ExpectedConditions → expect(locator).toBeVisible() |
| 92 | driver.switchTo().frame() → page.frameLocator() |
| 93 | Actions → locator.hover(), locator.dragTo() |
| 94 | |
| 95 | |
| 96 | ### 5. Upgrade Locators |
| 97 | |
| 98 | During conversion, upgrade selectors to Playwright best practices: |
| 99 | `#id` → `getByTestId()` or `getByRole()` |
| 100 | `.class` → `getByRole()` or `getByText()` |
| 101 | `[data-testid]` → `getByTestId()` |
| 102 | XPath → role-based locators |
| 103 | |
| 104 | ### 6. Convert Custom Commands / Utilities |
| 105 | |
| 106 | Cypress custom commands → Playwright custom fixtures via `test.extend()` |
| 107 | Selenium page objects → Playwright page objects (keep structure, update API) |
| 108 | Shared helpers → TypeScript utility functions |
| 109 | |
| 110 | ### 7. Verify Each Converted File |
| 111 | |
| 112 | After converting each file: |
| 113 | |
| 114 | |
| 115 | npx playwright test <converted-file> --reporter=list |
| 116 | |
| 117 | |
| 118 | Fix any compilation or runtime errors before moving to the next file. |
| 119 | |
| 120 | ### 8. Clean Up |
| 121 | |
| 122 | After all files are converted: |
| 123 | Remove Cypress/Selenium dependencies from `package.json` |
| 124 | Remove old config files (`cypress.config.ts`, etc.) |
| 125 | Update CI workflow to use Playwright |
| 126 | Update README with new test commands |
| 127 | |
| 128 | Ask user before deleting anything. |
| 129 | |
| 130 | ## Output |
| 131 | |
| 132 | Conversion summary: files converted, total tests migrated |
| 133 | Any tests that couldn't be auto-converted (manual intervention needed) |
| 134 | Updated CI config |
| 135 | Before/after comparison of test run results |
| 136 |
Discussion
Browse more free Claude skills.