From e164ac769729126452ab05d77f44b597aeb913b3 Mon Sep 17 00:00:00 2001 From: Playwright Service <89237858+playwrightmachine@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:29:49 -0700 Subject: [PATCH] cherry-pick(#29406): docs(java): update JUnit examples with new fixtures (#29881) This PR cherry-picks the following commits: - 8f4c2f714df1880e888400d9bc186c934573e96f --- docs/src/accessibility-testing-java.md | 2 + docs/src/api-testing-java.md | 2 + docs/src/junit-java.md | 182 +++++++++++++++++++++++++ docs/src/running-tests-java.md | 2 + docs/src/test-runners-java.md | 2 + 5 files changed, 190 insertions(+) create mode 100644 docs/src/junit-java.md diff --git a/docs/src/accessibility-testing-java.md b/docs/src/accessibility-testing-java.md index a14064452c..15bb998481 100644 --- a/docs/src/accessibility-testing-java.md +++ b/docs/src/accessibility-testing-java.md @@ -238,3 +238,5 @@ public class HomepageTests extends AxeTestFixtures { } } ``` + +See experimental [JUnit integration](./junit.md) to automatically initialize Playwright objects and more. diff --git a/docs/src/api-testing-java.md b/docs/src/api-testing-java.md index 80faa968d4..41265776a5 100644 --- a/docs/src/api-testing-java.md +++ b/docs/src/api-testing-java.md @@ -375,6 +375,8 @@ public class TestGitHubAPI { } ``` +See experimental [JUnit integration](./junit.md) to automatically initialize Playwright objects and more. + ## Prepare server state via API calls The following test creates a new issue via API and then navigates to the list of all issues in the diff --git a/docs/src/junit-java.md b/docs/src/junit-java.md new file mode 100644 index 0000000000..99753f082c --- /dev/null +++ b/docs/src/junit-java.md @@ -0,0 +1,182 @@ +--- +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]. + + + +```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,"); + page.locator("button").click(); + assertEquals("Clicked", page.evaluate("result")); + } + + @Test + void shouldCheckTheBox(Page page) { + page.setContent(""); + 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,"); + page.locator("button").click(); + assertEquals("Clicked", page.evaluate("result")); + } + + @Test + void shouldCheckTheBox(Page page) { + page.setContent(""); + 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("