1. Introduction & Motivation
Migrating a legacy Selenium suite isn't just about changing syntax—it's about fixing structural test flakiness and execution lag.
Legacy Selenium Java Approach
Selenium requires explicit driver management, verbose setup, and manual wait configurations:
public class LoginTest {
WebDriver driver;
@BeforeMethod
public void setUp() {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}
@Test
public void testLogin() {
driver.get("https://app.example.com/login");
WebElement emailInput = driver.findElement(By.id("username"));
emailInput.sendKeys("user@example.com");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
WebElement submitBtn = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit-btn")));
submitBtn.click();
}
}
Modern Playwright TypeScript Approach
Playwright provides built-in browser contexts, automatic waiting, and clean user-visible locators out of the box:
import { test, expect } from '@playwright/test';
test('login test', async ({ page }) => {
await page.goto('https://app.example.com/login');
await page.getByLabel('Username').fill('user@example.com');
await page.getByRole('button', { name: 'Submit' }).click();
await expect(page.getByText('Dashboard')).toBeVisible();
});
2. Core Migration Steps
1.Directory Coexistence: Run npm init playwright@latest inside your root repository alongside Maven/Gradle to allow incremental test migration.
2.Page Object Model Translation: Convert Java classes into modular TypeScript exports:
import { Page, Locator } from '@playwright/test';
export class LoginPage {
readonly emailInput: Locator;
readonly submitButton: Locator;
constructor(private readonly page: Page) {
this.emailInput = this.page.getByLabel('Username');
this.submitButton = this.page.getByRole('button', { name: 'Submit' });
}
async login(email: string) {
await this.emailInput.fill(email);
await this.submitButton.click();
}
}
3.Eliminating Explicit Waits: Replace WebDriverWait logic with Playwright’s auto-waiting locators, which automatically check for visibility, actionability, and stability before executing interactions.
3. Edge Cases & Gotchas
- Cross-Domain iFrames: Selenium requires explicit context switching via driver.switchTo().frame(). Playwright handles frame navigation natively using frame locators:
const frame = page.frameLocator('#my-iframe');
await frame.getByRole('button', { name: 'Confirm' }).click();
- Cookie and Storage State Persistence: Bypass repetitive UI login steps by generating a single storageState.json during global setup and reusing it across spec files.
Top comments (0)