From 283fecb30d5a938876dc67f4620311c7616cd599 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Fri, 11 Dec 2020 13:54:59 -0800 Subject: [PATCH] fix: package drivers for all platforms (#114) --- .github/workflows/test.yml | 2 +- driver-bundle/pom.xml | 63 +++++++++++++++++++ .../microsoft/playwright/impl/DriverJar.java | 20 ++++-- driver-bundle/src/main/resources/.gitignore | 2 + .../com/microsoft/playwright/TestInstall.java | 43 +++++++++++++ driver/pom.xml | 15 +---- .../com/microsoft/playwright/impl/Driver.java | 17 +++-- driver/src/main/resources/.gitignore | 1 - .../com/microsoft/playwright/TestLaunch.java | 51 --------------- playwright/pom.xml | 14 +++-- pom.xml | 50 ++++++++++----- scripts/download_driver_for_all_platforms.sh | 32 ++++++++++ ...load_driver.sh => install_local_driver.sh} | 6 +- 13 files changed, 218 insertions(+), 98 deletions(-) create mode 100644 driver-bundle/pom.xml rename {driver => driver-bundle}/src/main/java/com/microsoft/playwright/impl/DriverJar.java (80%) create mode 100644 driver-bundle/src/main/resources/.gitignore create mode 100644 driver-bundle/src/test/java/com/microsoft/playwright/TestInstall.java rename {playwright => driver}/src/main/java/com/microsoft/playwright/impl/Driver.java (72%) delete mode 100644 driver/src/main/resources/.gitignore delete mode 100644 driver/src/test/java/com/microsoft/playwright/TestLaunch.java create mode 100755 scripts/download_driver_for_all_platforms.sh rename scripts/{download_driver.sh => install_local_driver.sh} (92%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0c09325a..23d6fadf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: restore-keys: ${{ runner.os }}-m2 - name: Install driver shell: bash - run: scripts/download_driver.sh + run: scripts/download_driver_for_all_platforms.sh - name: Build with Maven run: mvn -B package -D skipTests --no-transfer-progress - name: Run tests diff --git a/driver-bundle/pom.xml b/driver-bundle/pom.xml new file mode 100644 index 00000000..83a7f700 --- /dev/null +++ b/driver-bundle/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + com.microsoft.playwright + parent-pom + 0.162.1-SNAPSHOT + + + driver-bundle + Playwright Java - Drivers For All Platforms + + This module includes playwright-cli binary and related utilities for all supported platforms. + It is intended to be used on the systems where Playwright driver is not preinstalled. + + + + + + org.apache.maven.plugins + maven-source-plugin + + true + + + + org.apache.maven.plugins + maven-javadoc-plugin + + 8 + false + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + + + + + com.microsoft.playwright + driver + ${project.version} + compile + + + org.junit.jupiter + junit-jupiter-engine + + + diff --git a/driver/src/main/java/com/microsoft/playwright/impl/DriverJar.java b/driver-bundle/src/main/java/com/microsoft/playwright/impl/DriverJar.java similarity index 80% rename from driver/src/main/java/com/microsoft/playwright/impl/DriverJar.java rename to driver-bundle/src/main/java/com/microsoft/playwright/impl/DriverJar.java index 69ee7994..880b25d4 100644 --- a/driver/src/main/java/com/microsoft/playwright/impl/DriverJar.java +++ b/driver-bundle/src/main/java/com/microsoft/playwright/impl/DriverJar.java @@ -16,8 +16,6 @@ package com.microsoft.playwright.impl; -import com.microsoft.playwright.PlaywrightException; - import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; @@ -32,12 +30,12 @@ public class DriverJar extends Driver { driverTempDir = Files.createTempDirectory("playwright-java-"); driverTempDir.toFile().deleteOnExit(); ClassLoader classloader = Thread.currentThread().getContextClassLoader(); - Path path = Paths.get(classloader.getResource("driver").toURI()); + Path path = Paths.get(classloader.getResource("driver/" + platformDir()).toURI()); Files.list(path).forEach(filePath -> { try { extractResource(filePath, driverTempDir); } catch (IOException e) { - throw new PlaywrightException("Failed to extract driver from " + path, e); + throw new RuntimeException("Failed to extract driver from " + path, e); } }); @@ -52,6 +50,20 @@ public class DriverJar extends Driver { } } + private static String platformDir() { + String name = System.getProperty("os.name").toLowerCase(); + if (name.contains("windows")) { + return "win32_x64"; + } + if (name.contains("linux")) { + return "linux"; + } + if (name.contains("mac os x")) { + return "mac"; + } + throw new RuntimeException("Unexpected os.name value: " + name); + } + private static Path extractResource(Path from, Path toDir) throws IOException { Path path = toDir.resolve(from.getFileName()); Files.copy(from, path); diff --git a/driver-bundle/src/main/resources/.gitignore b/driver-bundle/src/main/resources/.gitignore new file mode 100644 index 00000000..04540861 --- /dev/null +++ b/driver-bundle/src/main/resources/.gitignore @@ -0,0 +1,2 @@ +driver/ +local-driver/ diff --git a/driver-bundle/src/test/java/com/microsoft/playwright/TestInstall.java b/driver-bundle/src/test/java/com/microsoft/playwright/TestInstall.java new file mode 100644 index 00000000..d829a5fe --- /dev/null +++ b/driver-bundle/src/test/java/com/microsoft/playwright/TestInstall.java @@ -0,0 +1,43 @@ +/* + * 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; + +import com.microsoft.playwright.impl.Driver; +import org.junit.jupiter.api.Test; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TestInstall { + @Test + void playwrightCliInstalled() throws Exception { + // Clear system property to ensure that the driver is loaded from jar. + System.clearProperty("playwright.cli.dir"); + Path cli = Driver.ensureDriverInstalled(); + assertTrue(Files.exists(cli)); + + ProcessBuilder pb = new ProcessBuilder(cli.toString(), "install"); + pb.redirectError(ProcessBuilder.Redirect.INHERIT); + pb.redirectOutput(ProcessBuilder.Redirect.INHERIT); + Process p = pb.start(); + boolean result = p.waitFor(1, TimeUnit.MINUTES); + assertTrue(result, "Timed out waiting for browsers to install"); + } +} diff --git a/driver/pom.xml b/driver/pom.xml index eae52946..0ca2df52 100644 --- a/driver/pom.xml +++ b/driver/pom.xml @@ -11,12 +11,8 @@ driver Playwright Java - Driver - Java library to automate Chromium, Firefox and WebKit with a single API. - Playwright is built to enable cross-browser web automation that is ever-green, capable, - reliable and fast. - - This module includes playwright-cli binary and related utilities. It is intended to be - used on the systems where Playwright driver is not preinstalled. + + This module provides API for discovery and launching of playwright-cli binary. @@ -44,17 +40,10 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M5 - - com.microsoft.playwright - playwright - ${project.version} - compile - org.junit.jupiter junit-jupiter-engine diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Driver.java b/driver/src/main/java/com/microsoft/playwright/impl/Driver.java similarity index 72% rename from playwright/src/main/java/com/microsoft/playwright/impl/Driver.java rename to driver/src/main/java/com/microsoft/playwright/impl/Driver.java index 2d4103c2..8a6211bd 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/Driver.java +++ b/driver/src/main/java/com/microsoft/playwright/impl/Driver.java @@ -16,12 +16,15 @@ package com.microsoft.playwright.impl; -import com.microsoft.playwright.PlaywrightException; - import java.nio.file.Path; import java.nio.file.Paths; -abstract class Driver { +/** + * This class provides access to playwright-cli. It can be either preinstalled + * in the host system and its path is passed as a system property or it can be + * loaded from the driver-bundle module if that module is in the classpath. + */ +public abstract class Driver { private static Driver instance; private static class PreinstalledDriver extends Driver { @@ -35,15 +38,17 @@ abstract class Driver { } } - static synchronized Path ensureDriverInstalled() { + public static synchronized Path ensureDriverInstalled() { if (instance == null) { try { instance = createDriver(); } catch (Exception exception) { - throw new PlaywrightException("Failed to find playwright-cli", exception); + throw new RuntimeException("Failed to find playwright-cli", exception); } } - return instance.driverDir().resolve("playwright-cli"); + String name = System.getProperty("os.name").toLowerCase().contains("windows") ? + "playwright-cli.exe" : "playwright-cli"; + return instance.driverDir().resolve(name); } private static Driver createDriver() throws Exception { diff --git a/driver/src/main/resources/.gitignore b/driver/src/main/resources/.gitignore deleted file mode 100644 index fc7066f2..00000000 --- a/driver/src/main/resources/.gitignore +++ /dev/null @@ -1 +0,0 @@ -driver/ diff --git a/driver/src/test/java/com/microsoft/playwright/TestLaunch.java b/driver/src/test/java/com/microsoft/playwright/TestLaunch.java deleted file mode 100644 index e2808e5a..00000000 --- a/driver/src/test/java/com/microsoft/playwright/TestLaunch.java +++ /dev/null @@ -1,51 +0,0 @@ -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 cf8bc911..ffecf0de 100644 --- a/playwright/pom.xml +++ b/playwright/pom.xml @@ -50,11 +50,6 @@ org.apache.maven.plugins maven-surefire-plugin - - - ${project.parent.basedir}/driver/src/main/resources/driver - - @@ -67,6 +62,15 @@ org.junit.jupiter junit-jupiter-engine + + com.microsoft.playwright + driver + + + com.microsoft.playwright + driver-bundle + test + org.java-websocket Java-WebSocket diff --git a/pom.xml b/pom.xml index 3923ebe3..fc8dee46 100644 --- a/pom.xml +++ b/pom.xml @@ -36,9 +36,10 @@ - playwright api-generator driver + driver-bundle + playwright @@ -50,6 +51,17 @@ + + com.microsoft.playwright + driver + ${project.version} + + + com.microsoft.playwright + driver-bundle + ${project.version} + + com.google.code.gson gson @@ -117,19 +129,6 @@ - - org.apache.maven.plugins - maven-gpg-plugin - - - sign-artifacts - verify - - sign - - - - org.sonatype.plugins nexus-staging-maven-plugin @@ -153,4 +152,27 @@ https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + + diff --git a/scripts/download_driver_for_all_platforms.sh b/scripts/download_driver_for_all_platforms.sh new file mode 100755 index 00000000..19000f5d --- /dev/null +++ b/scripts/download_driver_for_all_platforms.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +set -e +set +x + +FILE_PREFIX=playwright-cli-0.170.0-next.1607022026758 + +trap "cd $(pwd -P)" EXIT +cd "$(dirname $0)" + +cd ../driver-bundle/src/main/resources +mkdir -p driver +cd driver + +for PLATFORM in mac linux win32_x64 +do + FILE_NAME=$FILE_PREFIX-$PLATFORM.zip + if [[ -d $PLATFORM ]]; then + echo "Skipping driver download for $PLATFORM ($(pwd)/$PLATFORM already exists)" + continue + fi + mkdir $PLATFORM + cd $PLATFORM + echo "Downloading driver for $PLATFORM to $(pwd)" + + curl -O https://playwright.azureedge.net/builds/cli/next/${FILE_NAME} + unzip ${FILE_NAME} -d . + rm $FILE_NAME + + cd - +done + diff --git a/scripts/download_driver.sh b/scripts/install_local_driver.sh similarity index 92% rename from scripts/download_driver.sh rename to scripts/install_local_driver.sh index 6da16c91..684fb2bb 100755 --- a/scripts/download_driver.sh +++ b/scripts/install_local_driver.sh @@ -9,13 +9,13 @@ trap "cd $(pwd -P)" EXIT cd "$(dirname $0)" cd ../driver/src/main/resources -if [[ -d driver ]]; then +if [[ -d local-driver ]]; then echo "$(pwd)/driver already exists, delete it first" exit 1; fi -mkdir driver -cd driver +mkdir local-driver +cd local-driver echo "Created directory: $(pwd)" FILE_NAME="unknown"