diff --git a/.gitignore b/.gitignore
index 8973dcce..d7aae7e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,4 +19,3 @@ target/
.idea
*.iml
-/driver/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a6338dd0..72d3a27a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -11,7 +11,7 @@ git clone https://github.com/microsoft/playwright-java
cd playwright-java
```
-2. Run the following script to download playwright-cli binary for your platform into `playwright/src/main/resources/driver/` directory. It will also install Playwright and download browser binaries for Chromium, Firefox and WebKit.
+2. Run the following script to download playwright-cli binary for your platform into `driver/src/main/resources/driver/` directory. It will also install Playwright and download browser binaries for Chromium, Firefox and WebKit.
```bash
scripts/download_driver.sh
diff --git a/driver/pom.xml b/driver/pom.xml
new file mode 100644
index 00000000..fd254274
--- /dev/null
+++ b/driver/pom.xml
@@ -0,0 +1,33 @@
+
+
+ 4.0.0
+
+ com.microsoft.playwright
+ playwright-java
+ 0.1-SNAPSHOT
+
+ driver
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M5
+
+
+
+
+
+ com.microsoft.playwright
+ playwright
+ 0.1-SNAPSHOT
+ compile
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+
+
+
diff --git a/driver/src/main/java/com/microsoft/playwright/impl/DriverJar.java b/driver/src/main/java/com/microsoft/playwright/impl/DriverJar.java
new file mode 100644
index 00000000..1365cedc
--- /dev/null
+++ b/driver/src/main/java/com/microsoft/playwright/impl/DriverJar.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.microsoft.playwright.impl;
+
+import com.microsoft.playwright.PlaywrightException;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.TimeUnit;
+
+class DriverJar extends Driver {
+ private final Path driverTempDir;
+
+ DriverJar() throws IOException, URISyntaxException, InterruptedException {
+ driverTempDir = Files.createTempDirectory("playwright-java-");
+ driverTempDir.toFile().deleteOnExit();
+ ClassLoader classloader = Thread.currentThread().getContextClassLoader();
+ Path path = Paths.get(classloader.getResource("driver").toURI());
+ Files.list(path).forEach(filePath -> {
+ try {
+ extractResource(filePath, driverTempDir);
+ } catch (IOException e) {
+ throw new PlaywrightException("Failed to extract driver from " + path, e);
+ }
+ });
+
+ Path driver = driverTempDir.resolve("playwright-cli");
+ ProcessBuilder pb = new ProcessBuilder(driver.toString(), "install");
+ pb.redirectError(ProcessBuilder.Redirect.INHERIT);
+ pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
+ Process p = pb.start();
+ boolean result = p.waitFor(10, TimeUnit.MINUTES);
+ if (!result) {
+ System.err.println("Timed out waiting for browsers to install");
+ }
+ }
+
+ private static Path extractResource(Path from, Path toDir) throws IOException {
+ Path path = toDir.resolve(from.getFileName());
+ Files.copy(from, path);
+ path.toFile().setExecutable(true);
+ path.toFile().deleteOnExit();
+// System.out.println("extracting: " + from.toString() + " to " + path.toString());
+ return path;
+ }
+
+ @Override
+ Path driverDir() {
+ return driverTempDir;
+ }
+}
diff --git a/playwright/src/main/resources/.gitignore b/driver/src/main/resources/.gitignore
similarity index 100%
rename from playwright/src/main/resources/.gitignore
rename to driver/src/main/resources/.gitignore
diff --git a/driver/src/test/java/com/microsoft/playwright/TestLaunch.java b/driver/src/test/java/com/microsoft/playwright/TestLaunch.java
new file mode 100644
index 00000000..e2808e5a
--- /dev/null
+++ b/driver/src/test/java/com/microsoft/playwright/TestLaunch.java
@@ -0,0 +1,51 @@
+package com.microsoft.playwright;/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.junit.jupiter.api.Test;
+
+public class TestLaunch {
+ @Test
+ void launchBrowser() throws Exception {
+ // Clear system property to ensure that the driver is loaded from jar.
+ System.clearProperty("playwright.cli.dir");
+ Playwright playwright = Playwright.create();
+ String browserName = System.getenv("BROWSER");
+ if (browserName == null) {
+ browserName = "chromium";
+ }
+ BrowserType browserType;
+ switch (browserName) {
+ case "webkit":
+ browserType = playwright.webkit();
+ break;
+ case "firefox":
+ browserType = playwright.firefox();
+ break;
+ case "chromium":
+ browserType = playwright.chromium();
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown browser: " + browserName);
+ }
+ String headfulEnv = System.getenv("HEADFUL");
+ boolean headful = headfulEnv != null && !"0".equals(headfulEnv) && !"false".equals(headfulEnv);
+ BrowserType.LaunchOptions options = new BrowserType.LaunchOptions();
+ options.headless = !headful;
+ Browser browser = browserType.launch(options);
+ browser.close();
+ playwright.close();
+ }
+}
diff --git a/playwright/pom.xml b/playwright/pom.xml
index d75c7a3c..734528db 100644
--- a/playwright/pom.xml
+++ b/playwright/pom.xml
@@ -27,6 +27,11 @@
org.apache.maven.plugins
maven-surefire-plugin
3.0.0-M5
+
+
+ ${project.parent.basedir}/driver/src/main/resources/driver
+
+
diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Driver.java b/playwright/src/main/java/com/microsoft/playwright/impl/Driver.java
new file mode 100644
index 00000000..2d4103c2
--- /dev/null
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/Driver.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.microsoft.playwright.impl;
+
+import com.microsoft.playwright.PlaywrightException;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+abstract class Driver {
+ private static Driver instance;
+
+ private static class PreinstalledDriver extends Driver {
+ private final Path driverDir;
+ PreinstalledDriver(Path driverDir) {
+ this.driverDir = driverDir;
+ }
+ @Override
+ Path driverDir() {
+ return driverDir;
+ }
+ }
+
+ static synchronized Path ensureDriverInstalled() {
+ if (instance == null) {
+ try {
+ instance = createDriver();
+ } catch (Exception exception) {
+ throw new PlaywrightException("Failed to find playwright-cli", exception);
+ }
+ }
+ return instance.driverDir().resolve("playwright-cli");
+ }
+
+ private static Driver createDriver() throws Exception {
+ String pathFromProperty = System.getProperty("playwright.cli.dir");
+ if (pathFromProperty != null) {
+ return new PreinstalledDriver(Paths.get(pathFromProperty));
+ }
+
+ Class> jarDriver = Class.forName("com.microsoft.playwright.impl.DriverJar");
+ return (Driver) jarDriver.getDeclaredConstructor().newInstance();
+ }
+
+ abstract Path driverDir();
+}
diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/PlaywrightImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/PlaywrightImpl.java
index 6ecfc8d5..4a0d91f2 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/PlaywrightImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/PlaywrightImpl.java
@@ -25,21 +25,17 @@ import com.microsoft.playwright.PlaywrightException;
import com.microsoft.playwright.Selectors;
import java.io.IOException;
-import java.net.URISyntaxException;
-import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class PlaywrightImpl extends ChannelOwner implements Playwright {
- private static Path driverTempDir;
private Process driverProcess;
public static PlaywrightImpl create() {
try {
- Path driver = ensureDriverInstalled();
+ Path driver = Driver.ensureDriverInstalled();
ProcessBuilder pb = new ProcessBuilder(driver.toString(), "run-driver");
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
// pb.environment().put("DEBUG", "pw:pro*");
@@ -48,47 +44,11 @@ public class PlaywrightImpl extends ChannelOwner implements Playwright {
PlaywrightImpl result = (PlaywrightImpl) connection.waitForObjectWithKnownName("Playwright");
result.driverProcess = p;
return result;
- } catch (IOException | InterruptedException | URISyntaxException e) {
+ } catch (IOException e) {
throw new PlaywrightException("Failed to launch driver", e);
}
}
- private static synchronized Path ensureDriverInstalled() throws IOException, InterruptedException, URISyntaxException {
- if (driverTempDir == null) {
- driverTempDir = Files.createTempDirectory("playwright-java-");
- driverTempDir.toFile().deleteOnExit();
- ClassLoader classloader = Thread.currentThread().getContextClassLoader();
- Path path = Paths.get(classloader.getResource("driver").toURI());
- Files.list(path).forEach(filePath -> {
- try {
- extractResource(filePath, driverTempDir);
- } catch (IOException e) {
- throw new PlaywrightException("Failed to extract driver from " + path, e);
- }
- });
-
- Path driver = driverTempDir.resolve("playwright-cli");
- ProcessBuilder pb = new ProcessBuilder(driver.toString(), "install");
- pb.redirectError(ProcessBuilder.Redirect.INHERIT);
- pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
- Process p = pb.start();
- boolean result = p.waitFor(10, TimeUnit.MINUTES);
- if (!result) {
- System.err.println("Timed out waiting for browsers to install");
- }
- }
- return driverTempDir.resolve("playwright-cli");
- }
-
- private static Path extractResource(Path from, Path toDir) throws IOException {
- Path path = toDir.resolve(from.getFileName());
- Files.copy(from, path);
- path.toFile().setExecutable(true);
- path.toFile().deleteOnExit();
-// System.out.println("extracting: " + from.toString() + " to " + path.toString());
- return path;
- }
-
private final BrowserTypeImpl chromium;
private final BrowserTypeImpl firefox;
private final BrowserTypeImpl webkit;
diff --git a/pom.xml b/pom.xml
index 68b91ce3..f14ceedf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,8 +11,9 @@
Playwright Java
- playwright
- api-generator
+ playwright
+ api-generator
+ driver
diff --git a/scripts/download_driver.sh b/scripts/download_driver.sh
index e5bad437..854a2504 100755
--- a/scripts/download_driver.sh
+++ b/scripts/download_driver.sh
@@ -8,7 +8,7 @@ FILE_PREFIX=playwright-cli-0.170.0-next.1605573954344
trap "cd $(pwd -P)" EXIT
cd "$(dirname $0)"
-cd ../playwright/src/main/resources
+cd ../driver/src/main/resources
if [[ -d driver ]]; then
echo "$(pwd)/driver already exists, delete it first"
exit 1;