mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
183 lines
6.3 KiB
Markdown
183 lines
6.3 KiB
Markdown
![]() |
---
|
||
|
id: junit
|
||
|
title: "JUnit (experimental)"
|
||
|
---
|
||
|
|
||
|
## Introduction
|
||
|
|
||
|
With a few lines of code, you can hook up Playwright to your favorite Java test runner.
|
||
|
|
||
|
In [JUnit](https://junit.org/junit5/), you can use Playwright [fixtures](./junit.md#fixtures) to automatically initialize [Playwright], [Browser], [BrowserContext] or [Page]. In the example below, all three test methods use the same
|
||
|
[Browser]. Each test uses its own [BrowserContext] and [Page].
|
||
|
|
||
|
<!-- TOC -->
|
||
|
|
||
|
```java
|
||
|
package org.example;
|
||
|
|
||
|
import com.microsoft.playwright.junit.UsePlaywright;
|
||
|
import com.microsoft.playwright.Page;
|
||
|
|
||
|
import org.junit.jupiter.api.*;
|
||
|
|
||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||
|
|
||
|
@UsePlaywright
|
||
|
public class TestExample {
|
||
|
|
||
|
@Test
|
||
|
void shouldClickButton(Page page) {
|
||
|
page.navigate("data:text/html,<script>var result;</script><button onclick='result=\"Clicked\"'>Go</button>");
|
||
|
page.locator("button").click();
|
||
|
assertEquals("Clicked", page.evaluate("result"));
|
||
|
}
|
||
|
|
||
|
@Test
|
||
|
void shouldCheckTheBox(Page page) {
|
||
|
page.setContent("<input id='checkbox' type='checkbox'></input>");
|
||
|
page.locator("input").check();
|
||
|
assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked"));
|
||
|
}
|
||
|
|
||
|
@Test
|
||
|
void shouldSearchWiki(Page page) {
|
||
|
page.navigate("https://www.wikipedia.org/");
|
||
|
page.locator("input[name=\"search\"]").click();
|
||
|
page.locator("input[name=\"search\"]").fill("playwright");
|
||
|
page.locator("input[name=\"search\"]").press("Enter");
|
||
|
assertEquals("https://en.wikipedia.org/wiki/Playwright", page.url());
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Fixtures
|
||
|
|
||
|
Simply add JUnit annotation `@UsePlaywright` to your test classes to enable Playwright fixtures. Test fixtures are used to establish environment for each test, giving the test everything it needs and nothing else.
|
||
|
|
||
|
```java
|
||
|
@UsePlaywright
|
||
|
public class TestExample {
|
||
|
|
||
|
@Test
|
||
|
void basicTest(Page page) {
|
||
|
page.navigate("https://playwright.dev/");
|
||
|
|
||
|
assertThat(page).hasTitle(Pattern.compile("Playwright"));
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
The `Page page` argument tells JUnit to setup the `page` fixture and provide it to your test method.
|
||
|
|
||
|
Here is a list of the pre-defined fixtures:
|
||
|
|
||
|
|Fixture |Type |Description |
|
||
|
|:-------------|:------------------|:--------------------------------|
|
||
|
|page |[Page] |Isolated page for this test run.|
|
||
|
|browserContext|[BrowserContext] |Isolated context for this test run. The `page` fixture belongs to this context as well.|
|
||
|
|browser |[Browser] |Browsers are shared across tests to optimize resources.|
|
||
|
|playwright |[Playwright] |Playwright instance is shared between tests running on the same thread.|
|
||
|
|request |[APIRequestContext]|Isolated APIRequestContext for this test run. Learn how to do [API testing](./api-testing).|
|
||
|
|
||
|
## Customizing options
|
||
|
|
||
|
To customize fixture options, you should implement an `OptionsFactory` and specify the class in the `@UsePlaywright()` annotation.
|
||
|
|
||
|
You can easily override launch options for [`method: BrowserType.launch`], or context options for [`method: Browser.newContext`] and [`method: APIRequest.newContext`]. See the following example:
|
||
|
|
||
|
```java
|
||
|
import com.microsoft.playwright.junit.Options;
|
||
|
import com.microsoft.playwright.junit.OptionsFactory;
|
||
|
import com.microsoft.playwright.junit.UsePlaywright;
|
||
|
|
||
|
@UsePlaywright(MyTest.CustomOptions.class)
|
||
|
public class MyTest {
|
||
|
|
||
|
public static class CustomOptions implements OptionsFactory {
|
||
|
@Override
|
||
|
public Options getOptions() {
|
||
|
return new Options()
|
||
|
.setHeadless(false)
|
||
|
.setContextOption(new Browser.NewContextOptions()
|
||
|
.setBaseURL("https://github.com"))
|
||
|
.setApiRequestOptions(new APIRequest.NewContextOptions()
|
||
|
.setBaseURL("https://playwright.dev"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Test
|
||
|
public void testWithCustomOptions(Page page, APIRequestContext request) {
|
||
|
page.navigate("/");
|
||
|
assertThat(page).hasURL(Pattern.compile("github"));
|
||
|
|
||
|
APIResponse response = request.get("/");
|
||
|
assertTrue(response.text().contains("Playwright"));
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Running Tests in Parallel
|
||
|
|
||
|
By default JUnit will run all tests sequentially on a single thread. Since JUnit 5.3 you can change this behavior to run tests in parallel
|
||
|
to speed up execution (see [this page](https://junit.org/junit5/docs/snapshot/user-guide/index.html#writing-tests-parallel-execution)).
|
||
|
Since it is not safe to use same Playwright objects from multiple threads without extra synchronization we recommend you create Playwright
|
||
|
instance per thread and use it on that thread exclusively. Here is an example how to run multiple test classes in parallel.
|
||
|
|
||
|
```java
|
||
|
@UsePlaywright
|
||
|
class Test1 {
|
||
|
@Test
|
||
|
void shouldClickButton(Page page) {
|
||
|
page.navigate("data:text/html,<script>var result;</script><button onclick='result=\"Clicked\"'>Go</button>");
|
||
|
page.locator("button").click();
|
||
|
assertEquals("Clicked", page.evaluate("result"));
|
||
|
}
|
||
|
|
||
|
@Test
|
||
|
void shouldCheckTheBox(Page page) {
|
||
|
page.setContent("<input id='checkbox' type='checkbox'></input>");
|
||
|
page.locator("input").check();
|
||
|
assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked"));
|
||
|
}
|
||
|
|
||
|
@Test
|
||
|
void shouldSearchWiki(Page page) {
|
||
|
page.navigate("https://www.wikipedia.org/");
|
||
|
page.locator("input[name=\"search\"]").click();
|
||
|
page.locator("input[name=\"search\"]").fill("playwright");
|
||
|
page.locator("input[name=\"search\"]").press("Enter");
|
||
|
assertEquals("https://en.wikipedia.org/wiki/Playwright", page.url());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@UsePlaywright
|
||
|
class Test2 {
|
||
|
@Test
|
||
|
void shouldReturnInnerHTML(Page page) {
|
||
|
page.setContent("<div>hello</div>");
|
||
|
assertEquals("hello", page.innerHTML("css=div"));
|
||
|
}
|
||
|
|
||
|
@Test
|
||
|
void shouldClickButton(Page page) {
|
||
|
Page popup = page.waitForPopup(() -> {
|
||
|
page.evaluate("window.open('about:blank');");
|
||
|
});
|
||
|
assertEquals("about:blank", popup.url());
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
|
||
|
Configure JUnit to run tests in each class sequentially and run multiple classes on parallel threads (with max
|
||
|
number of thread equal to 1/2 of the number of CPU cores):
|
||
|
|
||
|
```bash
|
||
|
junit.jupiter.execution.parallel.enabled = true
|
||
|
junit.jupiter.execution.parallel.mode.default = same_thread
|
||
|
junit.jupiter.execution.parallel.mode.classes.default = concurrent
|
||
|
junit.jupiter.execution.parallel.config.strategy=dynamic
|
||
|
junit.jupiter.execution.parallel.config.dynamic.factor=0.5
|
||
|
```
|