-
Notifications
You must be signed in to change notification settings - Fork 10
feat(java): add Playwright Java examples for axe Watcher 4.4.0 #275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
e83adfb
feat(java): add Playwright Java examples for axe Watcher 4.4.0
Garbee 2ebe5c2
fix(java): wait for links before count() in context example
Garbee 9a31035
feat(java): add Playwright Java multi-page example
padmavemulapati 55dfe8c
:robot: Automated formatting fixes
Garbee File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| # axe Watcher — Playwright Java examples | ||
|
|
||
| Runnable [JUnit 5](https://junit.org/junit5/) projects showing how to add accessibility analysis to | ||
| a [Playwright Java](https://playwright.dev/java/) test suite with | ||
| [`@axe-core/watcher`](https://central.sonatype.com/artifact/com.deque.axe_core/watcher). axe Watcher | ||
| wraps your Playwright `Page` (or `BrowserContext`) so scans run automatically as your existing | ||
| end-to-end tests drive the browser, then uploads the results to | ||
| [axe Developer Hub](https://docs.deque.com/developer-hub). | ||
|
|
||
| | Example | Scenario | What it shows | | ||
| | ---------------------------------------- | ---------------- | --------------------------------------------------------------------------------- | | ||
| | [`basic`](./basic) | Auto analysis | The default mode — wrap the page and every interaction is analyzed automatically. | | ||
| | [`manual-mode`](./manual-mode) | Manual mode | `setAutoAnalyze(false)` plus `analyze()` / `start()` / `stop()` to control scans. | | ||
| | [`context-wrapping`](./context-wrapping) | Context wrapping | `wrapContext()` so every page opened from one `BrowserContext` is instrumented. | | ||
| | [`multi-page`](./multi-page) | Multi-page | Reuse one wrapped page across several pages, flushing after each test. | | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - **Java 11 or newer.** The axe Watcher integration itself supports Java 8+; these example projects | ||
| target Java 11 source compatibility and are tested on Java 17 in CI. | ||
| - **[Maven](https://maven.apache.org/).** Each example is a standalone Maven project. | ||
| - **A Chromium-based browser.** axe Watcher loads a browser extension, which Chromium only supports | ||
| when launched via a persistent context using [Chrome for | ||
| Testing](https://developer.chrome.com/blog/chrome-for-testing), Playwright's bundled Chromium, or | ||
| a Microsoft Edge channel. Recent branded Google Chrome releases (139+) restrict the | ||
| `--load-extension` flag axe Watcher relies on, so prefer Chrome for Testing or Chromium. | ||
| - **An axe Developer Hub API key and project ID.** | ||
| - [Create an API key](https://axe.deque.com/settings) | ||
| - [Create a project ID](https://axe.deque.com/axe-watcher/projects) | ||
|
|
||
| ## Running an example | ||
|
|
||
| 1. Provide your credentials as environment variables. `SERVER_URL` is optional and defaults to | ||
| `https://axe.deque.com`; set it to target a different axe Developer Hub instance. | ||
|
|
||
| ```sh | ||
| export API_KEY="YOUR API KEY" | ||
| export PROJECT_ID="YOUR PROJECT ID" | ||
| # export SERVER_URL="https://axe.yourcompany.com" | ||
| ``` | ||
|
|
||
| 2. Change into the example you want to run: | ||
|
|
||
| ```sh | ||
| cd basic | ||
| ``` | ||
|
|
||
| 3. (Local runs only.) Install Playwright's bundled Chromium once. Skip this if you instead set | ||
| `CHROME_BIN` to a Chrome for Testing (or Chromium) binary — the examples will launch that, which | ||
| is how they run in CI. | ||
|
|
||
| ```sh | ||
| mvn exec:java -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="install chromium" | ||
| ``` | ||
|
|
||
| 4. Run the tests: | ||
|
|
||
| ```sh | ||
| mvn test | ||
| ``` | ||
|
|
||
| 5. Open your project in [axe Developer Hub](https://docs.deque.com/developer-hub) to review the | ||
| captured page states and issues. | ||
|
|
||
| ## Notes | ||
|
|
||
| - **Headless mode.** The examples run in Chromium's "new" headless mode (`setHeadless(true)` with a | ||
| Chromium-based channel) so they work in CI. axe Watcher's extension cannot load in Chromium's | ||
| classic/default headless mode, so `configure()` rejects a plain `--headless` argument, an | ||
| `--incognito` argument, or `setHeadless(true)` without a supported channel. Call | ||
| `setHeadless(false)` to watch a run in a visible window. | ||
| - **Always `flush()`.** Results are only uploaded when you flush. The examples call | ||
| `page.axeWatcher().flush()` in an `@AfterEach` hook (the `context-wrapping` example relies on | ||
| `BrowserContext.close()`, which flushes every tracked page). | ||
| - **Attributing scans to a test.** To trace a violation back to the test that produced it, call | ||
| `page.axeWatcher().setTestContext(testFilePath, testLocation)` — typically from a `@BeforeEach` | ||
| hook using JUnit 5's `TestInfo`. | ||
|
|
||
| For the full API and configuration reference, see the | ||
| [`@axe-core/watcher` Java documentation](https://central.sonatype.com/artifact/com.deque.axe_core/watcher). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <groupId>com.deque.watcher_examples.playwright</groupId> | ||
| <artifactId>basic</artifactId> | ||
| <version>1.0-SNAPSHOT</version> | ||
|
|
||
| <properties> | ||
| <maven.compiler.source>11</maven.compiler.source> | ||
| <maven.compiler.target>11</maven.compiler.target> | ||
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
| </properties> | ||
|
|
||
| <dependencies> | ||
| <!-- | ||
| axe Watcher declares Playwright as a `compileOnly` dependency, so you must declare | ||
| `com.microsoft.playwright:playwright` yourself alongside the watcher package. | ||
| --> | ||
| <dependency> | ||
| <groupId>com.microsoft.playwright</groupId> | ||
| <artifactId>playwright</artifactId> | ||
| <version>1.60.0</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>com.deque.axe_core</groupId> | ||
| <artifactId>watcher</artifactId> | ||
| <version>4.4.0</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.junit.jupiter</groupId> | ||
| <artifactId>junit-jupiter</artifactId> | ||
| <version>5.11.3</version> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| </dependencies> | ||
|
|
||
| <build> | ||
| <plugins> | ||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-surefire-plugin</artifactId> | ||
| <version>3.2.5</version> | ||
| </plugin> | ||
| </plugins> | ||
| </build> | ||
|
|
||
| </project> |
116 changes: 116 additions & 0 deletions
116
java/playwright/basic/src/test/java/com/deque/watcher_examples/playwright/BasicTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| package com.deque.watcher_examples.playwright; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
|
|
||
| import com.deque.axe_core.commons.AxeWatcherOptions; | ||
| import com.deque.axe_core.playwright.AxeWatcherPage; | ||
| import com.deque.axe_core.playwright.AxeWatcherPlaywright; | ||
| import com.microsoft.playwright.BrowserContext; | ||
| import com.microsoft.playwright.BrowserType; | ||
| import com.microsoft.playwright.Playwright; | ||
| import java.nio.file.Paths; | ||
| import java.util.Arrays; | ||
| import org.junit.jupiter.api.AfterEach; | ||
| import org.junit.jupiter.api.BeforeEach; | ||
| import org.junit.jupiter.api.DisplayName; | ||
| import org.junit.jupiter.api.Nested; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| /* | ||
| Auto analysis (the default mode). | ||
|
|
||
| Once the Playwright `Page` is wrapped with `wrapPage()`, axe Watcher analyzes each page state | ||
| automatically: every wrapped interaction (navigation, click, fill, ...) triggers a scan, and the | ||
| page is re-analyzed whenever the DOM changes. The rest of the test is plain Playwright Java. | ||
| */ | ||
| @DisplayName("My Login Application") | ||
| class BasicTest { | ||
|
|
||
| Playwright playwright; | ||
| BrowserContext context; | ||
| AxeWatcherPage page; | ||
|
|
||
| @BeforeEach | ||
| void setUp() { | ||
| AxeWatcherPlaywright axeWatcher = | ||
| new AxeWatcherPlaywright( | ||
| new AxeWatcherOptions() | ||
| .setApiKey(System.getenv("API_KEY")) | ||
| .setProjectId(System.getenv("PROJECT_ID")) | ||
| .setServerUrl(serverUrl())) | ||
| .enableDebugLogger(); | ||
|
|
||
| // configure() merges the axe Watcher extension flags into the launch options. It must be | ||
| // called before launching the persistent context — Chromium only loads extensions when | ||
| // launched via a persistent context. | ||
| BrowserType.LaunchPersistentContextOptions launchOptions = | ||
| axeWatcher.configure(browserOptions()); | ||
|
|
||
| playwright = Playwright.create(); | ||
| // An empty path tells Playwright to use a temporary profile directory. | ||
| context = playwright.chromium().launchPersistentContext(Paths.get(""), launchOptions); | ||
|
|
||
| // Interactions on a wrapped page are analyzed automatically. | ||
| page = axeWatcher.wrapPage(context.newPage()); | ||
| } | ||
|
|
||
| @AfterEach | ||
| void tearDown() { | ||
| // Send the collected results to axe Developer Hub after each test. | ||
| page.axeWatcher().flush(); | ||
| context.close(); | ||
| playwright.close(); | ||
| } | ||
|
Garbee marked this conversation as resolved.
|
||
|
|
||
| @Nested | ||
| @DisplayName("Login") | ||
| class LoginTests { | ||
| @Nested | ||
| @DisplayName("with valid credentials") | ||
| class ShouldLoginTests { | ||
| @Test | ||
| @DisplayName("should login") | ||
| void shouldLoginTest() { | ||
| page.navigate("https://the-internet.herokuapp.com/login"); | ||
|
|
||
| page.locator("#username").fill("tomsmith"); | ||
| page.locator("#password").fill("SuperSecretPassword!"); | ||
|
|
||
| page.locator("button[type='submit']").click(); | ||
|
|
||
| assertNotNull(page.waitForSelector("#flash")); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private static String serverUrl() { | ||
| String serverUrl = System.getenv("SERVER_URL"); | ||
| return serverUrl != null ? serverUrl : "https://axe.deque.com"; | ||
| } | ||
|
|
||
| private static BrowserType.LaunchPersistentContextOptions browserOptions() { | ||
| /* | ||
| axe Watcher's browser extension loads only in a headed browser or Chromium's "new" | ||
| headless mode — never Chromium's classic/default headless mode. We run headless here | ||
| (with a Chromium-based channel, selected below, which new-headless requires) so the | ||
| example works in CI; call setHeadless(false) to watch the run in a visible window. | ||
| "--no-sandbox" lets Chromium run as root in CI and isn't needed for local headed runs. | ||
| */ | ||
| BrowserType.LaunchPersistentContextOptions options = | ||
| new BrowserType.LaunchPersistentContextOptions() | ||
| .setHeadless(true) | ||
| .setArgs(Arrays.asList("--no-sandbox")); | ||
|
|
||
| // In CI we point Playwright at the Chrome installed on the runner (CHROME_BIN). Locally, | ||
| // without CHROME_BIN, Playwright falls back to its bundled Chromium — install it with | ||
| // `mvn exec:java -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="install chromium"`. | ||
| String chromeBin = System.getenv("CHROME_BIN"); | ||
| if (chromeBin != null) { | ||
| options.setChannel("chrome").setExecutablePath(Paths.get(chromeBin)); | ||
| } else { | ||
| options.setChannel("chromium"); | ||
| } | ||
|
|
||
| return options; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <groupId>com.deque.watcher_examples.playwright</groupId> | ||
| <artifactId>context-wrapping</artifactId> | ||
| <version>1.0-SNAPSHOT</version> | ||
|
|
||
| <properties> | ||
| <maven.compiler.source>11</maven.compiler.source> | ||
| <maven.compiler.target>11</maven.compiler.target> | ||
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
| </properties> | ||
|
|
||
| <dependencies> | ||
| <!-- | ||
| axe Watcher declares Playwright as a `compileOnly` dependency, so you must declare | ||
| `com.microsoft.playwright:playwright` yourself alongside the watcher package. | ||
| --> | ||
| <dependency> | ||
| <groupId>com.microsoft.playwright</groupId> | ||
| <artifactId>playwright</artifactId> | ||
| <version>1.60.0</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>com.deque.axe_core</groupId> | ||
| <artifactId>watcher</artifactId> | ||
| <version>4.4.0</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.junit.jupiter</groupId> | ||
| <artifactId>junit-jupiter</artifactId> | ||
| <version>5.11.3</version> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| </dependencies> | ||
|
|
||
| <build> | ||
| <plugins> | ||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-surefire-plugin</artifactId> | ||
| <version>3.2.5</version> | ||
| </plugin> | ||
| </plugins> | ||
| </build> | ||
|
|
||
| </project> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.