Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Migrate Selenium tests to Playwright by preserving what each test verifies while deliberately changing its locators, waits, browser lifecycle, runner setup, and CI installation. It is not a line-by-line syntax conversion: inventory the suite, port a representative slice, compare the assertions and behavior, then expand by pattern. Playwright’s official guides cover migrations from some other tools, but the guidance here synthesizes its documentation with Selenium’s rather than following a dedicated Selenium-to-Playwright recipe.

What changes—and what should stay the same

The point of a migration is not to make the new code look like the old code. It is to keep each test’s purpose, inputs, assertions, and covered user behavior intact while replacing the mechanisms used to drive and synchronize the browser.

Expect to revisit selectors, waits, frame and tab handling, setup and teardown, parallel execution, and browser installation. The language may stay the same; the test runner does not have to. A small pilot helps expose differences in your suite before they are multiplied across every test.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Preserve: the behavior the test is meant to prove, its meaningful assertions, and any required data setup.
  • Rework: how elements are located and interacted with, how UI readiness is expressed, and how pages and browser contexts are created.
  • Choose intentionally: whether to adopt Playwright Test or use the Playwright library with your existing runner.

How do I migrate Selenium tests to Playwright?

1. Inventory the suite before changing it

Group tests by behavior and dependencies, not just by file. For each group, record the language and runner; driver setup and teardown; page-object boundaries; implicit and explicit waits; selector patterns; frame and window use; browser-specific capabilities; downloads and screenshots; retries and reporting; and how tests share accounts, files, or other data.

This inventory is your migration map. It can reveal that one group mainly needs locator and assertion changes, while another depends on a shared signed-in session, a frame, or a particular browser capability. Those groups should not be treated as the same conversion.

2. Decide how much of the runner to change

Playwright can drive a browser as a library. Playwright Test adds its own fixtures, configuration, and parallel execution. Moving to the latter can replace more setup, teardown, and test-runner code; using the library with a different runner may keep more existing infrastructure. Adopting Playwright does not itself require replacing every runner concern.

Check API details for your project’s language and binding before estimating the work. The concrete examples below use JavaScript with Playwright Test; syntax and runner choices differ across JavaScript, Java, Python, .NET, and other bindings.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

3. Port a representative slice first

Choose tests that exercise the suite’s common interactions and include at least one meaningful synchronization case, frame or tab pattern if used, and typical setup. Keep the Selenium version available while you compare what both versions assert and which user behaviors they cover. Run the migrated tests repeatedly and across the browser matrix you actually intend to support before expanding by pattern.

What replaces Selenium selectors and element calls?

Playwright’s preferred interaction surface is a locator: a query that resolves against the current DOM when used. That is useful when a page re-renders between actions. The Playwright documentation describes locators as the central part of its auto-waiting and retry behavior.

Prefer locators that describe the control as a user encounters it, such as a role and accessible name for a button or a label for a form field. Use an explicit test ID when your team deliberately treats it as a stable contract between the application and its tests. CSS and XPath remain available, but selectors tied to incidental DOM structure can be brittle.

Selenium pattern Playwright direction Migration check
Find an element by a long CSS or XPath path Use a role, label, text, or agreed test ID locator when it represents the intended control Keep CSS or XPath if needed, but distinguish a meaningful selector from a path coupled to page structure
Find an element, then act on that element Build a locator and use its action, such as click or fill Confirm the action still targets the same control and the test still proves the same behavior
Read a value once, then assert it Use a web-first locator assertion for an expected UI state where appropriate Preserve the original assertion’s meaning; changing how state is read must not silently change what is verified

For example, with Playwright Test installed, the following is a complete small test file for the public example page. It demonstrates a user-facing locator and a retrying assertion rather than prescribing selectors for your application:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import { test, expect } from '@playwright/test';

test('the example page exposes its heading and link', async ({ page }) => {
  await page.goto('https://example.com');
  await expect(page.getByRole('heading', { name: 'Example Domain' })).toBeVisible();
  await expect(page.getByRole('link', { name: 'More information' })).toBeVisible();
});

Save it as tests/example.spec.js. Install Playwright Test with npm install -D @playwright/test, install a browser with npx playwright install chromium, and run it with npx playwright test tests/example.spec.js. Use the language and browser projects appropriate to your own suite rather than treating this JavaScript example as a required migration target.

What replaces WebDriverWait in Playwright?

There is no single one-for-one replacement for every Selenium wait. Playwright automatically checks actionability conditions before actions and retries web-first locator assertions. That often removes a Selenium-style wait whose sole purpose was to wait for an element to become ready to click or for a visible UI state to appear.

Do not delete waits mechanically, and do not carry every wait over mechanically. First ask what the wait expresses:

  • UI readiness: use a locator action or an assertion for the expected UI state. Let the interaction or assertion wait for its relevant condition.
  • Navigation or page transition: express the expected page state or navigation outcome directly, then assert the result that matters to the test.
  • Application-specific readiness: wait for the actual condition that indicates the application is ready, rather than an arbitrary pause if a meaningful condition is available.
  • External process or non-UI condition: retain explicit synchronization when it represents a distinct condition the browser action cannot establish.

A fixed delay may still be appropriate for a genuinely time-based behavior, but it should not be a substitute for understanding the condition being synchronized. Do not copy Selenium implicit-wait configuration into a Playwright design. Selenium warns that mixing implicit and explicit waits can make timeout behavior unpredictable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How should frames, tabs, and browser state map over?

Frames

Selenium code often switches the WebDriver context into a frame. In Playwright, investigate a frameLocator() chain to locate and interact with content inside the frame. During conversion, check that the frame locator points to the intended frame and that the assertion still concerns the same content.

Tabs and windows

Treat tabs and windows as a separate mapping exercise rather than assuming a Selenium context switch translates directly. Model how the new page is opened, identify the resulting Playwright page, and assert its state explicitly. Review how the old test determines which window to use and what happens when the new page closes.

Browser, context, and page lifetimes

Make ownership and lifetime clear. Separate tests that intentionally reuse a signed-in browser state from tests that should be isolated. Reusing state can be a deliberate fixture decision; accidental sharing can make a test depend on another test’s activity. The correct mapping depends on the old suite’s actual lifecycle and window-handling patterns, not on a universal Selenium conversion table.

Should I move to Playwright Test and run tests in parallel?

Playwright Test offers fixtures, configuration, and parallel workers. Those are useful capabilities, not an obligation to redesign the whole suite at once. If you adopt the runner, map existing hooks to fixtures and configuration deliberately, and review retries and reporting as separate choices.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Before increasing concurrency, identify shared mutable state: accounts, databases, files, test data, and third-party services. Start conservatively, verify isolation and stable outcomes, and only then increase worker concurrency. Parallel execution can expose collisions; it is not a guaranteed performance improvement for every suite.

When comparing the old and new approach, weigh language and runner investment, remote-grid and browser coverage requirements, control over browser and driver versions, locator and wait behavior, isolation, CI browser provisioning, diagnostic artifacts, and the engineering cost of changing shared infrastructure. These needs differ by project, so a blanket claim that one framework is always faster or better is not a useful migration decision.

How do I make CI browser setup reproducible?

Playwright uses browser binaries corresponding to its package versions. In CI, install the Playwright dependency and matching browsers, include operating-system dependencies as needed, and verify the intended browser projects and headless mode. A package update can require a browser-install step because browser versions move with Playwright releases.

Validate the exact installation and caching behavior in the CI provider you use. A local browser setup does not prove that the target runner has the same dependencies, permissions, cache contents, or artifact handling. Make browser installation part of the reproducible CI setup rather than relying on an unverified pre-existing binary.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How should I validate equivalent coverage?

  1. Compare intent: write down what each old test proves, including its meaningful preconditions and assertions.
  2. Compare data and setup: verify that the migrated test creates or reuses the same required state without introducing unintended sharing.
  3. Run repeatedly: inspect failures and diagnostics rather than assuming a passing first run proves stable synchronization.
  4. Exercise the intended browser matrix: include the browsers and CI mode your team plans to support.
  5. Expand by pattern: after a representative slice behaves as intended, apply the established locator, wait, lifecycle, and runner choices to similar tests.

Assess outcomes from your own suite. Official framework documentation does not establish a general migration duration, speedup, or flake-reduction figure, and those results depend on application behavior, test design, infrastructure, and the changes made.

Or skip the browser setup

If your task is capturing a clean website screenshot rather than migrating browser-driven assertions, ScreenshotNeo is a separate option: it provides a screenshot API and MCP server for developers. A single GET request can return an image or PDF; for a WebP screenshot of Stripe, the cURL call is:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for parameters. ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; these steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies page verdict and billing status in headers. Its MCP server includes take_screenshot, get_page_info, and capture_pdf for AI agents using Claude, Cursor, or another MCP client. The free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots.

Sign up for ScreenshotNeo free to get 1,000 screenshots a month with no card.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Do I need to rewrite Selenium tests in TypeScript?

No. Playwright supports multiple language bindings; the runner and APIs you choose should match your project’s supported language. The code example here uses JavaScript, not a requirement to adopt TypeScript.

Is there an official Selenium-to-Playwright migration guide?

The official Playwright migration guides cover some other tools, but not Selenium. Treat a conversion plan as project-specific guidance based on the frameworks’ documented behaviors, and verify binding-specific APIs for your target language.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.