mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
358 lines
9.6 KiB
Markdown
358 lines
9.6 KiB
Markdown
---
|
|
id: test-runners
|
|
title: "Test Runners"
|
|
---
|
|
|
|
## Introduction
|
|
|
|
With a few lines of code, you can hook up Playwright to your favorite Java test runner.
|
|
|
|
Playwright and Browser instances can be reused between tests for better performance. We
|
|
recommend running each test case in a new BrowserContext, this way browser state will be
|
|
isolated between the tests.
|
|
|
|
## JUnit
|
|
|
|
In [JUnit](https://junit.org/junit5/) you can initialize [Playwright] and [Browser] in [@BeforeAll](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/BeforeAll.html) method and
|
|
destroy them in [@AfterAll](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/AfterAll.html). In the example below all three test methods use the same
|
|
[Browser]. Each test uses its own [BrowserContext] and [Page].
|
|
|
|
```java
|
|
package org.example;
|
|
|
|
import com.microsoft.playwright.Browser;
|
|
import com.microsoft.playwright.BrowserContext;
|
|
import com.microsoft.playwright.Page;
|
|
import com.microsoft.playwright.Playwright;
|
|
import org.junit.jupiter.api.*;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
public class TestExample {
|
|
// Shared between all tests in this class.
|
|
static Playwright playwright;
|
|
static Browser browser;
|
|
|
|
// New instance for each test method.
|
|
BrowserContext context;
|
|
Page page;
|
|
|
|
@BeforeAll
|
|
static void launchBrowser() {
|
|
playwright = Playwright.create();
|
|
browser = playwright.chromium().launch();
|
|
}
|
|
|
|
@AfterAll
|
|
static void closeBrowser() {
|
|
playwright.close();
|
|
}
|
|
|
|
@BeforeEach
|
|
void createContextAndPage() {
|
|
context = browser.newContext();
|
|
page = context.newPage();
|
|
}
|
|
|
|
@AfterEach
|
|
void closeContext() {
|
|
context.close();
|
|
}
|
|
|
|
@Test
|
|
void shouldClickButton() {
|
|
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.setContent("<input id='checkbox' type='checkbox'></input>");
|
|
page.locator("input").check();
|
|
assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked"));
|
|
}
|
|
|
|
@Test
|
|
void shouldSearchWiki() {
|
|
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());
|
|
}
|
|
}
|
|
```
|
|
|
|
See experimental [JUnit integration](./junit.md) to automatically initialize Playwright objects and more.
|
|
|
|
### 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.
|
|
|
|
Use [`@TestInstance(TestInstance.Lifecycle.PER_CLASS)`](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/TestInstance.html)
|
|
annotation to make JUnit create one instance of a class for all test methods within that class (by default each JUnit will create a new instance of the class
|
|
for each test method). Store [Playwright] and [Browser] objects in instance fields. They will be shared between tests. Each instance of the class will use its
|
|
own copy of Playwright.
|
|
|
|
|
|
```java
|
|
// Subclasses will inherit PER_CLASS behavior.
|
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
|
class TestFixtures {
|
|
// Shared between all tests in the class.
|
|
Playwright playwright;
|
|
Browser browser;
|
|
|
|
@BeforeAll
|
|
void launchBrowser() {
|
|
playwright = Playwright.create();
|
|
browser = playwright.chromium().launch();
|
|
}
|
|
|
|
@AfterAll
|
|
void closeBrowser() {
|
|
playwright.close();
|
|
}
|
|
|
|
// New instance for each test method.
|
|
BrowserContext context;
|
|
Page page;
|
|
|
|
@BeforeEach
|
|
void createContextAndPage() {
|
|
context = browser.newContext();
|
|
page = context.newPage();
|
|
}
|
|
|
|
@AfterEach
|
|
void closeContext() {
|
|
context.close();
|
|
}
|
|
}
|
|
|
|
class Test1 extends TestFixtures {
|
|
@Test
|
|
void shouldClickButton() {
|
|
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.setContent("<input id='checkbox' type='checkbox'></input>");
|
|
page.locator("input").check();
|
|
assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked"));
|
|
}
|
|
|
|
@Test
|
|
void shouldSearchWiki() {
|
|
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());
|
|
}
|
|
}
|
|
|
|
class Test2 extends TestFixtures {
|
|
@Test
|
|
void shouldReturnInnerHTML() {
|
|
page.setContent("<div>hello</div>");
|
|
assertEquals("hello", page.innerHTML("css=div"));
|
|
}
|
|
|
|
@Test
|
|
void shouldClickButton() {
|
|
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
|
|
```
|
|
|
|
### Using Gradle
|
|
|
|
You can use a Gradle build configuration script, written in Groovy or Kotlin.
|
|
|
|
<Tabs
|
|
groupId="jvm-language"
|
|
defaultValue="groovy"
|
|
values={[
|
|
{label: 'Groovy', value: 'groovy'},
|
|
{label: 'Kotlin', value: 'kotlin'}
|
|
]
|
|
}>
|
|
<TabItem value="groovy">
|
|
|
|
```groovy title="build.gradle"
|
|
plugins {
|
|
application
|
|
id 'java'
|
|
}
|
|
|
|
repositories {
|
|
mavenCentral()
|
|
}
|
|
|
|
dependencies {
|
|
implementation 'com.microsoft.playwright:playwright:%%VERSION%%'
|
|
}
|
|
|
|
application {
|
|
mainClass = 'org.example.App'
|
|
}
|
|
|
|
// Usage: ./gradlew playwright --args="help"
|
|
task playwright(type: JavaExec) {
|
|
classpath sourceSets.test.runtimeClasspath
|
|
mainClass = 'com.microsoft.playwright.CLI'
|
|
}
|
|
|
|
test {
|
|
useJUnitPlatform()
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="kotlin">
|
|
|
|
```groovy title="build.gradle.kts"
|
|
plugins {
|
|
application
|
|
id("java")
|
|
}
|
|
|
|
repositories {
|
|
mavenCentral()
|
|
}
|
|
|
|
dependencies {
|
|
implementation("com.microsoft.playwright:playwright:%%VERSION%%")
|
|
}
|
|
|
|
application {
|
|
mainClass.set("org.example.App")
|
|
}
|
|
|
|
// Usage: ./gradlew playwright --args="help"
|
|
tasks.register<JavaExec>("playwright") {
|
|
classpath(sourceSets["test"].runtimeClasspath)
|
|
mainClass.set("com.microsoft.playwright.CLI")
|
|
}
|
|
|
|
tasks.test {
|
|
useJUnitPlatform()
|
|
testLogging {
|
|
events("passed", "skipped", "failed")
|
|
}
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
Tests can then be launched as follows:
|
|
|
|
```bash
|
|
./gradlew run
|
|
```
|
|
|
|
Also, Playwright command line tools can be run with :
|
|
|
|
```bash
|
|
./gradlew playwright --args="help"
|
|
```
|
|
|
|
## TestNG
|
|
|
|
In [TestNG](https://testng.org/) you can initialize [Playwright] and [Browser] in [@BeforeClass](https://javadoc.io/doc/org.testng/testng/latest/org/testng/annotations/BeforeClass.html) method and
|
|
destroy them in [@AfterClass](https://javadoc.io/doc/org.testng/testng/latest/org/testng/annotations/AfterClass.html). In the example below all three test methods use the same
|
|
[Browser]. Each test uses its own [BrowserContext] and [Page].
|
|
|
|
```java
|
|
package org.example;
|
|
|
|
import com.microsoft.playwright.Browser;
|
|
import com.microsoft.playwright.BrowserContext;
|
|
import com.microsoft.playwright.Page;
|
|
import com.microsoft.playwright.Playwright;
|
|
import org.testng.annotations.*;
|
|
|
|
import static org.testng.Assert.assertEquals;
|
|
import static org.testng.Assert.assertTrue;
|
|
|
|
public class TestExample {
|
|
// Shared between all tests in this class.
|
|
Playwright playwright;
|
|
Browser browser;
|
|
|
|
// New instance for each test method.
|
|
BrowserContext context;
|
|
Page page;
|
|
|
|
@BeforeClass
|
|
void launchBrowser() {
|
|
playwright = Playwright.create();
|
|
browser = playwright.chromium().launch();
|
|
}
|
|
|
|
@AfterClass
|
|
void closeBrowser() {
|
|
playwright.close();
|
|
}
|
|
|
|
@BeforeMethod
|
|
void createContextAndPage() {
|
|
context = browser.newContext();
|
|
page = context.newPage();
|
|
}
|
|
|
|
@AfterMethod
|
|
void closeContext() {
|
|
context.close();
|
|
}
|
|
|
|
@Test
|
|
void shouldClickButton() {
|
|
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.setContent("<input id='checkbox' type='checkbox'></input>");
|
|
page.locator("input").check();
|
|
assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked"));
|
|
}
|
|
|
|
@Test
|
|
void shouldSearchWiki() {
|
|
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());
|
|
}
|
|
}
|
|
```
|