Quarkus Playwright
Playwright is an open-source automation library designed for browser testing and web scraping. This extension supports two primary use cases:
-
Testing: Perform end-to-end tests for your Quarkus web application.
-
Runtime: Leverage Playwright for screen scraping or other browser tasks in your runtime application, including support for GraalVM native compilation.
Test Usage
The primary use case for Playwright is integration with @QuarkusTest
for end-to-end testing of your application. You can easily create effective cross-browser end-to-end tests for your Quarkus web application using Playwright with frameworks such as Qute, Quinoa, Renarde, Web-Bundler, and MyFaces. Playwright Test was specifically designed to meet the requirements of end-to-end testing. It supports all modern rendering engines, including Chromium, WebKit, and Firefox. You can run tests on Windows, Linux, and macOS—either locally or in CI—both in headless and headed modes, with native mobile emulation for Google Chrome on Android and Mobile Safari.
Just add the dependency as <scope>test</scope>
to your pom.xml
:
<dependency>
<groupId>io.quarkiverse.playwright</groupId>
<artifactId>quarkus-playwright</artifactId>
<version>2.1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
Write your tests:
@QuarkusTest
@WithPlaywright
public class WithDefaultPlaywrightTest {
@InjectPlaywright
BrowserContext context;
@TestHTTPResource("/")
URL index;
@Test
public void testIndex() {
final Page page = context.newPage();
Response response = page.navigate(index.toString());
Assertions.assertEquals("OK", response.statusText());
page.waitForLoadState();
String title = page.title();
Assertions.assertEquals("My Awesome App", title);
// Make sure the web app is loaded and hits the backend
final ElementHandle quinoaEl = page.waitForSelector(".toast-body.received");
String greeting = quinoaEl.innerText();
Assertions.assertEquals("Hello from RESTEasy Reactive", greeting);
}
}
Use the annotation @WithPlaywright()
to change the browser (Chromium, Firefox, Webkit), headless, enable debug, logs, and other options.
Debug your tests with the Playwright inspector @WithPlaywright(debug=true)
.
Custom Test Selectors
Selectors can be used to install custom selector engines. An example of registering selector engine that queries elements based on a tag name:
@QuarkusTest
@WithPlaywright(selectors = {
@PlaywrightSelector(name = "tag", script = "{\n" +
" // Returns the first element matching given selector in the root's subtree.\n" +
" query(root, selector) {\n" +
" return root.querySelector(selector);\n" +
" },\n" +
" // Returns all elements matching given selector in the root's subtree.\n" +
" queryAll(root, selector) {\n" +
" return Array.from(root.querySelectorAll(selector));\n" +
" }\n" +
"}")
})
public class WithSelectorsPlaywrightTest {
@InjectPlaywright
BrowserContext context;
@Test
public void testIndex() {
final Page page = context.newPage();
// add a button to the page
page.setContent("<div><button>Click me</button></div>");
// Use the selector prefixed with its name.
Locator button = page.locator("tag=button");
// Combine it with built-in locators.
page.locator("tag=div").getByText("Click me").click();
// Can use it in any methods supporting selectors.
int buttonCount = (int) page.locator("tag=button").count();
Assertions.assertEquals(1, buttonCount);
}
}
Runtime Usage
Leverage Playwright for screen scraping or other browser tasks in your runtime application, including support for GraalVM native compilation.
Just add the runtime
dependency to pom.xml
:
<dependency>
<groupId>io.quarkiverse.playwright</groupId>
<artifactId>quarkus-playwright</artifactId>
<version>2.1.1</version>
</dependency>
In runtime mode, Playwright is used directly through its Java SDK without CDI injection. Follow the standard Microsoft Playwright documentation for usage patterns. Below is an example REST service that demonstrates screen scraping:
@Path("/playwright")
@ApplicationScoped
public class PlaywrightResource {
private static final Logger log = Logger.getLogger(PlaywrightResource.class);
/**
* Navigates to Google homepage and retrieves the page title using Playwright.
*
* <p>This endpoint demonstrates basic Playwright functionality by:
* <ul>
* <li>Launching a headless Chromium browser</li>
* <li>Creating a new page and navigating to google.com</li>
* <li>Retrieving and returning the page title</li>
* </ul>
* </p>
*
* @return The title of the Google homepage
*/
@GET
public String google() {
String pageTitle;
final BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions()
.setHeadless(true)
.setChromiumSandbox(false)
.setChannel("")
.setArgs(List.of("--disable-gpu"));
final Map<String, String> env = new HashMap<>(System.getenv());
env.put("DEBUG", "pw:api");
try (Playwright playwright = Playwright.create(new Playwright.CreateOptions().setEnv(env))) {
try (Browser browser = playwright.chromium().launch(launchOptions)) {
Page page = browser.newPage();
page.navigate("https://www.google.com/");
pageTitle = page.title();
log.infof("Page title: %s", pageTitle);
}
}
return pageTitle;
}
}
Native
If you plan on running in a Docker image we highly recommend you use a pre-built image from Microsoft mcr.microsoft.com/playwright:v1.48.1
which is based on Ubuntu and already has all libraries and tools necessary for PlayWright.
FROM mcr.microsoft.com/playwright:v1.48.1-noble
WORKDIR /work/
RUN chown 1001:root /work \
&& chmod g+rwX /work \
&& chown 1001:root /work
COPY --chown=1001:root target/*.properties target/*.so /work/
COPY --chown=1001:root target/*-runner /work/application
# Make application executable for all users
RUN chmod ugo+x /work/application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
Additional Configuration
There is additional configuration options available on the @BrowserContextConfig
and @WithPlaywright
annotations:
Unresolved include directive in modules/ROOT/pages/index.adoc - include::https://github.com/quarkiverse/quarkus-playwright/blob/main/runtime/src/main/java/io/quarkiverse/playwright/BrowserContextConfig.java[]
Unresolved include directive in modules/ROOT/pages/index.adoc - include::https://github.com/quarkiverse/quarkus-playwright/blob/main/runtime/src/main/java/io/quarkiverse/playwright/WithPlaywright.java[]