129 / 139 · 13 Browser Automation with Playwright · Migration and Comparison← prev⊞ allnext →☰ Read as one page
15.4Migrating from Selenium to Playwright
Step 1: Concept Mapping
| Selenium Concept | Playwright Equivalent |
|---|---|
WebDriver / driver |
Page / page |
driver.get(url) |
page.goto(url) |
driver.find_element(By.ID, 'x') |
page.locator('#x') or page.getByTestId('x') |
element.click() |
locator.click() (with auto-wait) |
element.send_keys('text') |
locator.fill('text') |
WebDriverWait + expected_conditions |
Auto-waiting (built-in) |
driver.switch_to.frame() |
page.frameLocator() |
driver.quit() |
Context/browser cleanup (automatic in test runner) |
| Selenium Grid | Built-in workers + sharding |
Page Object with WebDriverWait |
Page Object with Locators (no waits needed) |
Step 2: Migration Strategy
Approach A: Gradual (Recommended)
- New tests written in Playwright from day one
- Run both suites in CI in parallel
- Migrate existing tests by priority (critical paths first)
- Decommission Selenium suite when coverage is equivalent
Approach B: Big Bang
- Rewrite all tests in Playwright at once
- Faster transition but higher risk
- Only viable for small suites (< 100 tests)
Step 3: Common Conversion Patterns
# Selenium
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-testid="submit"]'))
)
element.click()
# Playwright — no explicit wait needed
page.get_by_test_id("submit").click()
// Selenium (JS)
await driver.wait(until.elementLocated(By.id('result')), 10000);
const text = await driver.findElement(By.id('result')).getText();
assert.equal(text, 'Success');
// Playwright — web-first assertion retries automatically
await expect(page.locator('#result')).toHaveText('Success');