diff --git a/.gitignore b/.gitignore
index dfcfd56..bc86687 100644
--- a/.gitignore
+++ b/.gitignore
@@ -348,3 +348,6 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
+
+# Java
+target/
\ No newline at end of file
diff --git a/samples/experimental/java/README.md b/samples/experimental/java/README.md
new file mode 100644
index 0000000..35c87e0
--- /dev/null
+++ b/samples/experimental/java/README.md
@@ -0,0 +1,60 @@
+# Run Playwright Java tests with Microsoft Playwright Testing (Experimental)
+
+This sample demonstrates how to run Playwright Java tests at scale using Microsoft Playwright Testing. It showcases the benefits of accelerating test suite completion by leveraging more parallel cloud browsers.
+
+**Note** - You won't be able to get the support for reporting and authentication to the service from the client running the tests via Entra ID.
+
+If you have not yet created a workspace, please follow the [Get Started guide](../../../README.md#get-started)
+
+## Sample setup
+
+1. Clone this sample:
+
+ ```bash
+ git clone https://github.com/microsoft/playwright-testing-service
+ cd playwright-testing-service/samples/experimental/java
+ ```
+
+1. Install dependencies:
+
+ ```bash
+ mvn install
+ ```
+
+1. Set up Authentication using Access Tokens:
+
+ Currently, only access tokens are supported for Java. See [Set up authentication using access tokens](../../../../README.md#set-up-authentication-using-access-tokens)
+
+1. Set access token generated above as environment variable for your project:
+
+ ```bash
+ PLAYWRIGHT_SERVICE_ACCESS_TOKEN= # Paste Access Token value from previous step
+ ```
+
+1. Set up environment:
+
+ In the [Playwright portal](https://aka.ms/mpt/portal), copy the command under **Add region endpoint in your set up** and set the following environment variable:
+
+ ```bash
+ PLAYWRIGHT_SERVICE_URL= # Paste region endpoint URL
+ ```
+
+## Run tests
+
+Run Playwright tests against browsers managed by the service using the configuration you created above. You can run up to 100 parallel workers with the service
+
+```bash
+mvn compile exec:java -D exec.mainClass="org.example.App"
+```
+
+## Add more configuration
+
+You can use the following environment variables to specify configuration parameters for the service:
+
+1. **PLAYWRIGHT_SERVICE_RUN_ID**: This variable allows you to change the ID of the test run. The run ID is a unique identifier for a test run and is used to track test runs in the portal.
+
+ Example :
+
+ ```bash
+ export PLAYWRIGHT_SERVICE_RUN_ID = "my_custom_runId"
+ ```
\ No newline at end of file
diff --git a/samples/experimental/java/pom.xml b/samples/experimental/java/pom.xml
new file mode 100644
index 0000000..fcc4dbe
--- /dev/null
+++ b/samples/experimental/java/pom.xml
@@ -0,0 +1,42 @@
+
+
+ 4.0.0
+
+ org.example
+ examples
+ 1.0-SNAPSHOT
+ Playwright Client - Microsoft Playwright Testing Integration Examples
+
+ UTF-8
+
+
+
+ com.microsoft.playwright
+ playwright
+ 1.49.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+ snapshots-repo
+ https://oss.sonatype.org/content/repositories/snapshots
+ false
+ true
+
+
+
\ No newline at end of file
diff --git a/samples/experimental/java/src/main/java/org/example/App.java b/samples/experimental/java/src/main/java/org/example/App.java
new file mode 100644
index 0000000..8d05c0a
--- /dev/null
+++ b/samples/experimental/java/src/main/java/org/example/App.java
@@ -0,0 +1,40 @@
+package org.example;
+
+import java.util.regex.Pattern;
+
+import org.example.PlaywrightService.BrowserConnectOptions;
+
+import com.microsoft.playwright.Browser;
+import com.microsoft.playwright.Locator;
+import com.microsoft.playwright.Page;
+import com.microsoft.playwright.Playwright;
+import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
+import com.microsoft.playwright.options.AriaRole;
+
+public class App {
+ public static void main(String[] args) {
+ try (Playwright playwright = Playwright.create()) {
+ BrowserConnectOptions browserConnectOptions = PlaywrightService.getConnectOptions();
+ Browser browser = playwright.chromium().connect(browserConnectOptions.wsEndpoint, browserConnectOptions.connectOptions);
+
+ Page page = browser.newPage();
+ page.navigate("http://playwright.dev");
+
+ // Expect a title "to contain" a substring.
+ assertThat(page).hasTitle(Pattern.compile("Playwright"));
+
+ // create a locator
+ Locator getStarted = page.getByRole(AriaRole.LINK, new Page.GetByRoleOptions().setName("Get Started"));
+
+ // Expect an attribute "to be strictly equal" to the value.
+ assertThat(getStarted).hasAttribute("href", "/docs/intro");
+
+ // Click the get started link.
+ getStarted.click();
+
+ // Expects page to have a heading with the name of Installation.
+ assertThat(page.getByRole(AriaRole.HEADING,
+ new Page.GetByRoleOptions().setName("Installation"))).isVisible();
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/experimental/java/src/main/java/org/example/PlaywrightService.java b/samples/experimental/java/src/main/java/org/example/PlaywrightService.java
new file mode 100644
index 0000000..5a0bbba
--- /dev/null
+++ b/samples/experimental/java/src/main/java/org/example/PlaywrightService.java
@@ -0,0 +1,50 @@
+package org.example;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import com.microsoft.playwright.BrowserType.ConnectOptions;
+
+public class PlaywrightService {
+ public static class BrowserConnectOptions {
+ public final String wsEndpoint;
+ public final ConnectOptions connectOptions;
+
+ public BrowserConnectOptions(String wsEndpoint, ConnectOptions connectOptions) {
+ this.wsEndpoint = wsEndpoint;
+ this.connectOptions = connectOptions;
+ }
+ }
+
+ public static BrowserConnectOptions getConnectOptions() {
+ return PlaywrightService.getConnectOptions("linux");
+ }
+
+ public static BrowserConnectOptions getConnectOptions(String osName) {
+ return PlaywrightService.getConnectOptions(osName, "");
+ }
+
+ public static BrowserConnectOptions getConnectOptions(String osName, String runId) {
+ String playwrightRunId = System.getenv("PLAYWRIGHT_SERVICE_RUN_ID");
+ if (runId != null && !runId.isEmpty()) {
+ System.setProperty("PLAYWRIGHT_SERVICE_RUN_ID", runId);
+ }
+ if (playwrightRunId == null || playwrightRunId.isEmpty()) {
+ playwrightRunId = UUID.randomUUID().toString();
+ System.setProperty("PLAYWRIGHT_SERVICE_RUN_ID", playwrightRunId);
+ }
+
+ String serviceUrl = System.getenv("PLAYWRIGHT_SERVICE_URL");
+ String serviceAccessToken = System.getenv("PLAYWRIGHT_SERVICE_ACCESS_TOKEN");
+
+ Map headers = new HashMap<>();
+ headers.put("Authorization", "Bearer " + serviceAccessToken);
+
+ String wsEndpoint = String.format("%s?os=%s&runId=%s&api-version=2023-10-01-preview",
+ serviceUrl, osName, playwrightRunId);
+ ConnectOptions connectOptions = new ConnectOptions();
+ connectOptions.setHeaders(headers);
+ return new BrowserConnectOptions(wsEndpoint, connectOptions);
+ }
+}
\ No newline at end of file