Thread Local in Playwright

 

In Playwright Java, ThreadLocal is often used in test automation frameworks (like TestNG or JUnit) to ensure thread safety when running tests in parallel. ThreadLocal allows each thread to maintain its own isolated instance of a variable — like the Playwright BrowserPage, or BrowserContext.

















Use Case:

When you run tests in parallel, sharing a single instance of Browser or Page across threads can cause data corruption or flaky tests. ThreadLocal ensures each test thread uses its own BrowserContext, and Page.


Example: Thread-safe Playwright with ThreadLocal in Java


PlaywrightFactory.java


import com.microsoft.playwright.*;

public class PlaywrightFactory {
    private static ThreadLocal<Playwright> tlPlaywright = new ThreadLocal<>();
    private static ThreadLocal<Browser> tlBrowser = new ThreadLocal<>();
    private static ThreadLocal<BrowserContext> tlContext = new ThreadLocal<>();
    private static ThreadLocal<Page> tlPage = new ThreadLocal<>();

    public static void initPlaywright() {
        tlPlaywright.set(Playwright.create());
    }

    public static void initBrowser() {
        BrowserType.LaunchOptions options = new BrowserType.LaunchOptions().setHeadless(false);
        tlBrowser.set(getPlaywright().chromium().launch(options));
    }

    public static void initContext() {
        tlContext.set(getBrowser().newContext());
    }

    public static void initPage() {
        tlPage.set(getContext().newPage());
    }

    public static Playwright getPlaywright() {
        return tlPlaywright.get();
    }

    public static Browser getBrowser() {
        return tlBrowser.get();
    }

    public static BrowserContext getContext() {
        return tlContext.get();
    }

    public static Page getPage() {
        return tlPage.get();
    }

    public static void closeAll() {
        getPage().close();
        getContext().close();
        getBrowser().close();
        getPlaywright().close();

        // Remove from ThreadLocal
        tlPage.remove();
        tlContext.remove();
        tlBrowser.remove();
        tlPlaywright.remove();
    }
}





SampleTest.java


import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.microsoft.playwright.*;

public class SampleTest {

    @BeforeMethod
    public void setUp() {
        PlaywrightFactory.initPlaywright();
        PlaywrightFactory.initBrowser();
        PlaywrightFactory.initContext();
        PlaywrightFactory.initPage();
    }

    @Test
    public void testGoogleSearch() {
        Page page = PlaywrightFactory.getPage();
        page.navigate("https://www.google.com");
        System.out.println("Page Title: " + page.title());
    }

    @AfterMethod
    public void tearDown() {
        PlaywrightFactory.closeAll();
    }
}



Parallel Execution

To run parallel tests safely:

  • Use TestNG with <parallel="methods"> or <parallel="classes">

  • Each test thread will get its own isolated Playwright Page due to ThreadLocal

No comments:

Post a Comment