Playwright automation testing with Java starts with a Maven dependency, the browser binaries that match that dependency, and a test that creates an isolated BrowserContext. Playwright drives Chromium, Firefox, and WebKit in headed or headless mode. The workflow below uses the dependency version shown in Microsoft’s Java introduction (1.63.0, retrieved in 2026); check the current documentation before pinning a version.
What you need before writing a test
- Java 8 or later and a supported operating system, checked against the current Playwright Java requirements.
- Maven (or another build tool that can resolve Maven artifacts).
- A test runner such as JUnit or TestNG.
- An application URL that your test environment can reach.
Playwright’s Java API is distributed as a Maven dependency. Browser executables are installed separately and are tied to the Playwright release, so upgrading the dependency can require another browser-install step.
Create a Maven project
Add Playwright to pom.xml. This example uses the version displayed in the official introduction; use one version consistently for the dependency and browser installation.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>playwright-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<playwright.version>1.63.0</playwright.version>
</properties>
<dependencies>
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>${playwright.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.12.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.2</version>
</plugin>
</plugins>
</build>
</project>
The JUnit and Surefire versions above are ordinary project choices; align them with your organization’s supported stack. Playwright itself is the required browser-automation dependency.
Install Playwright browsers
After Maven downloads the library, install the browser binaries from the same project version:
mvn exec:java -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="install"
On a Linux CI image, install operating-system dependencies as documented by Playwright:
mvn exec:java -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="install --with-deps"
For headless-only Chromium jobs, the browser guide documents the --only-shell option. Rerun the installation after changing the Playwright version. Playwright can also install branded Chrome or Edge; those installations use the operating system’s global location and may override an existing installation, so use that option deliberately. See Browsers | Playwright Java for the current commands and supported systems.
Write a first Java test
The basic lifecycle is: create Playwright, launch a browser, create a context, open a page, navigate, interact through a locator, assert, and close resources. The try-with-resources form ensures cleanup even when an assertion fails.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutepackage com.example;
import com.microsoft.playwright.*;
import org.junit.jupiter.api.Test;
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
class HomePageTest {
@Test
void homePageLoads() {
try (Playwright playwright = Playwright.create();
Browser browser = playwright.chromium().launch(
new BrowserType.LaunchOptions().setHeadless(true));
BrowserContext context = browser.newContext();
Page page = context.newPage()) {
page.navigate("https://example.com");
assertThat(page).hasTitle("Example Domain");
assertThat(page.locator("h1")).hasText("Example Domain");
}
}
}
Use setHeadless(false) while diagnosing a test locally. In CI, headless mode avoids a display requirement. A separate context per test keeps cookies, local storage, permissions, and session data from leaking between tests while allowing a browser process to be reused.
Locators, waiting, and assertions
Prefer user-facing locators
Use roles, labels, text, and explicit test IDs before brittle CSS or XPath selectors. For example:
Rank #2
Locator save = page.getByRole(AriaRole.BUTTON,
new Page.GetByRoleOptions().setName("Save"));
save.click();
assertThat(page.getByText("Saved")).isVisible();
When an element has a stable test identifier, configure and use it consistently:
page.getByTestId("checkout-submit").click();
Let Playwright wait for actionability
Actions wait for conditions such as visibility, stability, enabled state, and the ability to receive pointer input. Playwright assertions retry until the expected condition is met. This is more reliable than inserting arbitrary sleeps. Wait for a specific application state instead:
page.getByRole(AriaRole.BUTTON,
new Page.GetByRoleOptions().setName("Load report")).click();
assertThat(page.locator("[data-testid=report]")).isVisible();
For a known asynchronous condition, use a locator assertion or an explicit wait for a selector. Avoid increasing global timeouts to hide a selector or application problem.
Organize tests with JUnit or TestNG
JUnit
JUnit works naturally with Maven Surefire and IDE test discovery. A practical fixture creates one Playwright and browser for a class or suite, then creates a fresh context and page for each test. If you share the browser for performance, never share mutable page state between tests.
class AccountTest {
static Playwright playwright;
static Browser browser;
BrowserContext context;
Page page;
@BeforeAll
static void start() {
playwright = Playwright.create();
browser = playwright.chromium().launch();
}
@BeforeEach
void openContext() {
context = browser.newContext();
page = context.newPage();
}
@AfterEach
void closeContext() { context.close(); }
@AfterAll
static void stop() {
browser.close();
playwright.close();
}
}
Import the JUnit lifecycle annotations from org.junit.jupiter.api. Add synchronization or a carefully designed fixture if your runner executes methods in parallel; a shared Playwright object must not become a source of test-state races.
TestNG
TestNG is documented as another Playwright integration and can suit projects already using TestNG groups, data providers, and suite XML. Map its @BeforeSuite, @BeforeMethod, @AfterMethod, and @AfterSuite lifecycle to the same resource pattern: reuse a browser when useful, but create a context and page for each test method. Choose the runner that matches your build reporting, fixture conventions, and parallel-execution model. See Test Runners | Playwright Java.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Run headed, headless, and across browsers
Switch the browser type without changing locator code:
Browser browser = playwright.firefox().launch();
// or
Browser browser = playwright.webkit().launch();
// Chromium is also available through playwright.chromium()
Run headed for visual debugging and headless for automation. Test the engines your users require rather than assuming Chromium coverage represents Firefox or WebKit. Browser binaries must be installed for every engine selected in the environment.
Use code generation, then refactor it
Codegen records interactions and generates Java code. Start it with the Java CLI:
mvn exec:java -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="codegen https://your-app.example"
The generator prioritizes role, text, and test-id locators. Treat its output as a draft: remove incidental clicks, replace ambiguous selectors, add assertions for the behavior that matters, and move repeated login or navigation into fixtures. A recording that merely reaches a page is not a regression test until it checks an outcome.
Free tools Windows power users keep installed
One-click scans. No signup required.
Documentation: Generating tests | Playwright Java.
CI practices that prevent flaky runs
- Pin the Playwright dependency and install its matching browsers during image setup.
- Install Linux dependencies with
--with-depswhen the runner image does not provide them. - Use headless mode unless a virtual display is intentionally configured.
- Keep each test’s context isolated and avoid shared accounts or mutable data when tests run concurrently.
- Use deterministic test data and wait on visible application states rather than fixed delays.
- Retain the failed URL, browser, test name, and application logs in CI so a failure can be reproduced locally in headed mode.
Common failures and fixes
Executable or browser not found
Cause: the Maven library is present but its matching browser was not installed, or the dependency was upgraded. Fix: rerun the Playwright CLI install command for that version and include --with-deps on Linux.
Timeout waiting for a locator
Cause: the selector is wrong, the page is on a different URL, an overlay blocks the element, or the application never reaches the expected state. Fix: inspect the locator in headed mode, prefer a role or test ID, assert the URL or response state that should precede the action, and fix the application or test data instead of adding a long sleep.
Rank #4
Tests influence one another
Cause: contexts, cookies, storage, or server-side records are shared. Fix: create a new BrowserContext per test, isolate accounts or records, and close the context in teardown.
Works locally but fails in CI
Cause: missing OS libraries, different browser binaries, viewport, timezone, network access, or environment variables. Fix: install browsers and dependencies in the CI image, log the Playwright version and target browser, and make environment configuration explicit.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Branded Chrome or Edge behaves unexpectedly
Cause: the branded installation uses a global operating-system location and can replace an existing installation. Fix: review the browser guide’s installation behavior and use the bundled engine unless branded-browser coverage is a deliberate requirement.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your goal is a clean image or PDF rather than an interactive test, ScreenshotNeo provides a single HTTP request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
cURL (full API details are in the ScreenshotNeo docs):
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo includes full-page and element capture, device and viewport controls, retina scale, PDF settings, custom CSS and JavaScript, selector clicks and hiding, selector/delay/network-idle waits, request and resource blocking, headers, cookies, user-agent, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen-TTL caching, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage reporting, and an OpenAPI specification. Parameter names used by other screenshot APIs also work. Every plan includes every feature: 1,000 shots per month are free with no card; paid plans start at $5 for 3,000 shots. Sign up for the free 1,000-shot plan.
FAQ
Does Playwright Java require Selenium?
No. Playwright Java is its own browser-automation library and communicates with its managed browser engines through its Java API.
Best Value
Should I create a browser for every test?
Not usually. Reusing a browser can reduce startup overhead, while a new context and page per test provide isolation. Validate that lifecycle against your runner’s parallelism.
Can I test WebKit on a Linux CI runner?
Playwright provides WebKit binaries for supported environments, but install the browsers and operating-system dependencies required by the current browser guide and verify your target matrix in CI.
Frequently Asked Questions
Does Playwright Java require Selenium?
No. Playwright Java is its own browser-automation library and communicates with its managed browser engines through its Java API.
Should I create a browser for every test?
Not usually. Reusing a browser can reduce startup overhead, while a new context and page per test provide isolation. Validate that lifecycle against your runner’s parallelism.
Can I test WebKit on a Linux CI runner?
Playwright provides WebKit binaries for supported environments, but install the browsers and operating-system dependencies required by the current browser guide and verify your target matrix in CI.
Quick Recap
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.

