| |

Selenium to Playwright Migration Part 5: Waits, Retries, and Infrastructure

This is part of the Selenium to Playwright Migration Series. Follow the complete 7-part tutorial to migrate your test suite from Selenium Java to Playwright TypeScript.

๐ŸŽญ Want to master this with real projects? Join the Playwright Automation Mastery course at The Testing Academy.


The infrastructure layer changes dramatically: WebDriverWait becomes auto-wait, RetryAnalyzer becomes a config line, ScreenshotListener becomes a flag, and ThreadLocal driver becomes browser contexts.

Contents

Wait Strategy Conversion

Before: WaitHelpers.java (60+ lines)

public class WaitHelpers {
    private WebDriverWait wait;
    public WaitHelpers(WebDriver driver) {
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }
    public void waitForVisibility(WebElement element) {
        wait.until(ExpectedConditions.visibilityOf(element));
    }
    public void waitForClickable(WebElement element) {
        wait.until(ExpectedConditions.elementToBeClickable(element));
    }
    public void waitForText(WebElement element, String text) {
        wait.until(ExpectedConditions.textToBePresentInElement(element, text));
    }
}

After: Delete the file entirely

// No WaitHelper needed in Playwright!

// Every action auto-waits for element to be:
// - Attached to DOM
// - Visible
// - Stable (no animation)
// - Enabled
// - Not obscured by other elements

await page.getByRole('button', { name: 'Submit' }).click();
// ^ Automatically waits for all 5 conditions before clicking

// For assertions, expect() auto-retries:
await expect(page.getByText('Success')).toBeVisible();
// ^ Retries every 100ms until visible or timeout (default 5s)

// Custom timeout when needed:
await expect(page.getByText('Report ready')).toBeVisible({ timeout: 30_000 });

Retry Logic: RetryAnalyzer to Config

๐Ÿš€ Level Up Your Playwright

From locators to CI pipelines โ€” build a production-grade Playwright + TypeScript framework step by step.

Before: 40+ lines of Java

public class RetryAnalyzer implements IRetryAnalyzer {
    private int retryCount = 0;
    private static final int MAX_RETRY = 2;
    public boolean retry(ITestResult result) {
        if (retryCount < MAX_RETRY) { retryCount++; return true; }
        return false;
    }
}
public class RetryListener implements IAnnotationTransformer {
    public void transform(ITestAnnotation annotation, ...) {
        annotation.setRetryAnalyzer(RetryAnalyzer.class);
    }
}

After: 1 line in config

// playwright.config.ts
export default defineConfig({
  retries: process.env.CI ? 2 : 0,  // That's it. Done.
});

Screenshot and Video: Listeners to Config

// playwright.config.ts
use: {
  screenshot: 'only-on-failure',  // Replaces ScreenshotListener.java
  video: 'retain-on-failure',     // No Selenium equivalent
  trace: 'on-first-retry',        // Step-by-step replay of every action
}

Test Isolation: ThreadLocal to BrowserContext

In Selenium, you used ThreadLocal<WebDriver> for parallel test isolation. In Playwright, each test automatically gets its own BrowserContext โ€” isolated cookies, localStorage, and session state. Zero configuration needed.

Next: Part 6: AI-Powered Migration โ€” using Claude Code and LLMs to automate the conversion process.

๐ŸŽ“ Master Playwright End to End

Join hundreds of SDETs building real automation frameworks. Lifetime access, hands-on projects, and a job-ready portfolio.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.