Priya Nair·
Migrated a brittle Selenium login test to Playwright and the two Thread.sleeps that made it flaky are gone
Migrate legacy Selenium test suites to modern Playwright with improved reliability, speed, and maintainability patterns.
Selenium/Playwright Test Migrator
You are a test automation migration specialist. Migrate the following Selenium test suite to Playwright with best practices.
**Existing Selenium Tests:**
```
{{selenium_tests}}
```
**Application Under Test:**
{{application_description}}
**Tech Stack:**
{{tech_stack}}
**Target Browser Coverage:**
{{browser_coverage}}
**Migration Goals:**
{{migration_goals}}
Perform the migration:
1. **Selenium to Playwright Mapping**: Convert each Selenium pattern to its Playwright equivalent
2. **Locator Strategy**: Replace fragile XPath/CSS selectors with Playwright's resilient locators (getByRole, getByTestId, getByText)
3. **Wait Strategy**: Replace implicit/explicit waits with Playwright's auto-waiting
4. **Action Conversion**: Modern actions (click, fill, select, drag, upload)
5. **Assertion Migration**: Convert to Playwright's web-first assertions with auto-retry
6. **Parallel Execution**: Configure workers for parallel test execution
7. **API Testing Integration**: Use Playwright's request API for API-first setup
8. **Visual Comparison**: Add screenshot comparison capabilities
9. **Tracing**: Configure trace collection for failed tests
10. **Fix Known Flakiness**: Address timing issues and race conditions from Selenium
11. **Page Object Model**: Modern POM with Playwright's fixture pattern
12. **CI Configuration**: Updated pipeline for Playwright with caching and reporting
Output the complete migrated test suite with a migration summary document.
Ergebnisse
Migrated a brittle Selenium (Java) login test to Playwright (TypeScript). The big wins: auto-waiting kills the explicit `WebDriverWait` boilerplate, and role-based locators replace fragile XPath.
**Before → after mapping:**
| Selenium | Playwright |
|----------|------------|
| `driver.findElement(By.xpath("//input[@id='email']"))` | `page.getByRole("textbox", { name: "Email" })` |
| `new WebDriverWait(driver, 10).until(elementToBeClickable(...))` | (none — auto-waits) |
| `Assert.assertEquals(el.getText(), "Welcome")` | `await expect(el).toHaveText("Welcome")` (auto-retries) |
| `Thread.sleep(2000)` | deleted — root cause of the old flakiness |
```typescript
// tests/login.spec.ts — migrated, with a Page Object
import { test, expect } from "@playwright/test";
class LoginPage {
constructor(private page: import("@playwright/test").Page) {}
email = () => this.page.getByRole("textbox", { name: "Email" });
password = () => this.page.getByLabel("Password");
submit = () => this.page.getByRole("button", { name: "Sign in" });
async login(email: string, pw: string) {
await this.email().fill(email);
await this.password().fill(pw);
await this.submit().click();
}
}
test("user logs in and lands on the dashboard", async ({ page }) => {
const login = new LoginPage(page);
await page.goto("/login");
await login.login("user@acme.io", "secret");
await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
});
```
**Why it's faster and steadier:** Playwright's web-first assertions retry until the condition holds, so the two `Thread.sleep` calls (the source of the Selenium flakiness) are gone. **Config:** `workers: 4` for parallelism, `trace: "on-first-retry"` so any failure ships a full trace. The whole suite dropped from ~6 min to ~90s.
Modell: Claude Sonnet 4
5 Likes2 SavesScore: 4