diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cd67302b2..67038419a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ git clone https://github.com/microsoft/playwright-java cd playwright-java ``` -2. Run the following script to download and assemble the Playwright driver for all platforms into `driver-bundle/src/main/resources/driver/` directory (browser binaries for Chromium, Firefox and WebKit will be automatically downloaded later on first Playwright run). +2. Run the following script to download and assemble the Playwright driver. The platform-independent `playwright-core` package is assembled once into `driver/src/main/resources/driver/package/`, and the Node.js binary for each platform into `driver-bundle/src/main/resources/driver//` (browser binaries for Chromium, Firefox and WebKit will be automatically downloaded later on first Playwright run). ```bash scripts/download_driver.sh diff --git a/driver-bundle/pom.xml b/driver-bundle/pom.xml index df02c5c16..2aa0b02e2 100644 --- a/driver-bundle/pom.xml +++ b/driver-bundle/pom.xml @@ -10,28 +10,15 @@ driver-bundle - Playwright - Drivers For All Platforms + Playwright - Node.js For All Platforms - This module includes Playwright driver and related utilities for all supported platforms. - It is intended to be used on the systems where Playwright driver is not preinstalled. + Node.js binaries for the Playwright driver on every supported platform. Can be excluded when + Node.js is preinstalled on the host (see PLAYWRIGHT_NODEJS_PATH). - - - com.microsoft.playwright - driver - ${project.version} - compile - - - org.junit.jupiter - junit-jupiter-engine - - - - org.apache.maven.plugins diff --git a/driver/pom.xml b/driver/pom.xml index 1f1e7df9d..fc307e9fc 100644 --- a/driver/pom.xml +++ b/driver/pom.xml @@ -12,7 +12,8 @@ driver Playwright - Driver - This module provides API for discovery and launching of Playwright driver. + API for launching the Playwright driver. Bundles the platform-independent playwright-core + package; the Node.js binary comes from the driver-bundle module or a preinstalled Node.js. @@ -21,4 +22,18 @@ junit-jupiter-engine + + + + + + org.apache.maven.plugins + maven-source-plugin + + true + + + + diff --git a/driver/src/main/java/com/microsoft/playwright/impl/driver/Driver.java b/driver/src/main/java/com/microsoft/playwright/impl/driver/Driver.java index 092d290ab..9b71b2cbc 100644 --- a/driver/src/main/java/com/microsoft/playwright/impl/driver/Driver.java +++ b/driver/src/main/java/com/microsoft/playwright/impl/driver/Driver.java @@ -25,8 +25,9 @@ /** * 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. + * in the host system and its path is passed as a system property, or it can be + * loaded from the classpath: the platform-independent driver code ships in the + * driver module and the Node.js binary in the optional driver-bundle module. */ public abstract class Driver { protected final Map env = new LinkedHashMap<>(System.getenv()); diff --git a/driver-bundle/src/main/java/com/microsoft/playwright/impl/driver/jar/DriverJar.java b/driver/src/main/java/com/microsoft/playwright/impl/driver/jar/DriverJar.java similarity index 88% rename from driver-bundle/src/main/java/com/microsoft/playwright/impl/driver/jar/DriverJar.java rename to driver/src/main/java/com/microsoft/playwright/impl/driver/jar/DriverJar.java index 654ff6732..060bd9c2d 100644 --- a/driver-bundle/src/main/java/com/microsoft/playwright/impl/driver/jar/DriverJar.java +++ b/driver/src/main/java/com/microsoft/playwright/impl/driver/jar/DriverJar.java @@ -119,7 +119,21 @@ public static URI getDriverResourceURI() throws URISyntaxException { } void extractDriverToTempDir() throws URISyntaxException, IOException { - URI originalUri = getDriverResourceURI(); + extractResourceToDir("driver/package", driverTempDir.resolve("package")); + if (preinstalledNodePath == null) { + String platformResource = "driver/" + platformDir(); + if (DriverJar.class.getClassLoader().getResource(platformResource) == null) { + throw new RuntimeException("Failed to find the bundled Node.js for platform '" + platformDir() + + "'. Add the com.microsoft.playwright:driver-bundle dependency, or set the " + + PLAYWRIGHT_NODEJS_PATH + " environment variable (or the playwright.nodejs.path system " + + "property) to point at a preinstalled Node.js."); + } + extractResourceToDir(platformResource, driverTempDir); + } + } + + private void extractResourceToDir(String resourcePath, Path destDir) throws URISyntaxException, IOException { + URI originalUri = DriverJar.class.getClassLoader().getResource(resourcePath).toURI(); URI uri = maybeExtractNestedJar(originalUri); // Create zip filesystem if loading from jar. @@ -131,14 +145,8 @@ void extractDriverToTempDir() throws URISyntaxException, IOException { // See https://github.com/microsoft/playwright-java/issues/306 Path srcRootDefaultFs = Paths.get(srcRoot.toString()); Files.walk(srcRoot).forEach(fromPath -> { - if (preinstalledNodePath != null) { - String fileName = fromPath.getFileName().toString(); - if ("node.exe".equals(fileName) || "node".equals(fileName)) { - return; - } - } Path relative = srcRootDefaultFs.relativize(Paths.get(fromPath.toString())); - Path toPath = driverTempDir.resolve(relative.toString()); + Path toPath = destDir.resolve(relative.toString()); try { if (Files.isDirectory(fromPath)) { Files.createDirectories(toPath); diff --git a/driver/src/main/resources/.gitignore b/driver/src/main/resources/.gitignore new file mode 100644 index 000000000..045408616 --- /dev/null +++ b/driver/src/main/resources/.gitignore @@ -0,0 +1,2 @@ +driver/ +local-driver/ diff --git a/driver-bundle/src/test/java/com/microsoft/playwright/impl/driver/jar/TestInstall.java b/playwright/src/test/java/com/microsoft/playwright/impl/driver/jar/TestInstall.java similarity index 100% rename from driver-bundle/src/test/java/com/microsoft/playwright/impl/driver/jar/TestInstall.java rename to playwright/src/test/java/com/microsoft/playwright/impl/driver/jar/TestInstall.java diff --git a/scripts/download_driver.sh b/scripts/download_driver.sh index dba7f75d2..c72dad687 100755 --- a/scripts/download_driver.sh +++ b/scripts/download_driver.sh @@ -9,9 +9,11 @@ cd "$(dirname $0)" if [[ ($1 == '-h') || ($1 == '--help') ]]; then echo "" echo "This script downloads and assembles the Playwright driver for all platforms." - echo "Each driver is assembled from the 'playwright-core' npm package and the matching" - echo "Node.js binary from https://nodejs.org, the same way the upstream Playwright build" - echo "does it. The result is put under 'driver-bundle/src/main/resources/driver'." + echo "The platform-independent 'playwright-core' npm package is assembled once into the driver" + echo "module ('driver/src/main/resources/driver/package'), and the matching Node.js binary from" + echo "https://nodejs.org for each platform goes into the driver-bundle module" + echo "('driver-bundle/src/main/resources/driver/'), the same way the upstream" + echo "Playwright build does it." echo "" echo "Usage: scripts/download_driver.sh [option]" echo "" @@ -56,20 +58,26 @@ echo "Driver version: $DRIVER_VERSION" echo "Upstream commit: $GIT_HEAD" echo "Node.js version: $NODE_VERSION" -cd ../driver-bundle/src/main/resources +# The platform-independent driver code (playwright-core) is assembled once into the driver module; +# the Node.js binary for each platform is assembled into the driver-bundle module. See issue #1196. +ROOT="$(cd .. && pwd)" +CORE_DEST="$ROOT/driver/src/main/resources/driver" +NODE_DEST="$ROOT/driver-bundle/src/main/resources/driver" -if [[ -d 'driver' ]]; then - echo "Deleting existing drivers from $(pwd)" - rm -rf driver -fi - -mkdir -p driver -cd driver +TMP_DIR="$(mktemp -d)" +trap 'rm -rf "$TMP_DIR"' EXIT -# Download the platform-independent driver package (playwright-core) once. -CORE_TGZ="$(pwd)/playwright-core-$DRIVER_VERSION.tgz" +# 1. playwright-core package -> driver module (once, shared by every platform). +echo "Assembling playwright-core package to $CORE_DEST/package" +rm -rf "$CORE_DEST/package" +mkdir -p "$CORE_DEST" +CORE_TGZ="$TMP_DIR/playwright-core-$DRIVER_VERSION.tgz" download "https://registry.npmjs.org/playwright-core/-/playwright-core-$DRIVER_VERSION.tgz" "$CORE_TGZ" +# The npm tarball has a top-level package/ directory, so this creates $CORE_DEST/package. +tar -xzf "$CORE_TGZ" -C "$CORE_DEST" +rm -f "$CORE_TGZ" +# 2. Node.js binary for each platform -> driver-bundle module. # :: for ENTRY in \ "mac:darwin-x64:tar.gz" \ @@ -79,28 +87,25 @@ for ENTRY in \ "win32_x64:win-x64:zip" do IFS=':' read -r PLATFORM NODE_SUFFIX ARCHIVE <<< "$ENTRY" - echo "Assembling driver for $PLATFORM to $(pwd)/$PLATFORM" - mkdir "$PLATFORM" + DEST="$NODE_DEST/$PLATFORM" + echo "Assembling Node.js for $PLATFORM to $DEST" + rm -rf "$DEST" + mkdir -p "$DEST" - # 1. playwright-core package contents -> $PLATFORM/package - tar -xzf "$CORE_TGZ" -C "$PLATFORM" - - # 2. Node.js binary and its license from the official Node.js distribution. + # Node.js binary and its license from the official Node.js distribution. NODE_DIR="node-v$NODE_VERSION-$NODE_SUFFIX" - NODE_ARCHIVE="$NODE_DIR.$ARCHIVE" + NODE_ARCHIVE="$TMP_DIR/$NODE_DIR.$ARCHIVE" download "https://nodejs.org/dist/v$NODE_VERSION/$NODE_DIR.$ARCHIVE" "$NODE_ARCHIVE" if [[ $ARCHIVE == "zip" ]]; then - unzip -joq "$NODE_ARCHIVE" "$NODE_DIR/node.exe" -d "$PLATFORM" - unzip -joq "$NODE_ARCHIVE" "$NODE_DIR/LICENSE" -d "$PLATFORM" + unzip -joq "$NODE_ARCHIVE" "$NODE_DIR/node.exe" -d "$DEST" + unzip -joq "$NODE_ARCHIVE" "$NODE_DIR/LICENSE" -d "$DEST" else - tar -xzf "$NODE_ARCHIVE" -C "$PLATFORM" --strip-components=2 "$NODE_DIR/bin/node" - tar -xzf "$NODE_ARCHIVE" -C "$PLATFORM" --strip-components=1 "$NODE_DIR/LICENSE" + tar -xzf "$NODE_ARCHIVE" -C "$DEST" --strip-components=2 "$NODE_DIR/bin/node" + tar -xzf "$NODE_ARCHIVE" -C "$DEST" --strip-components=1 "$NODE_DIR/LICENSE" fi rm -f "$NODE_ARCHIVE" done -rm -f "$CORE_TGZ" - echo "" echo "All drivers have been successfully assembled." echo "" diff --git a/tools/test-local-installation/create_project_and_run_tests.sh b/tools/test-local-installation/create_project_and_run_tests.sh index 99b2570bd..12864b84c 100755 --- a/tools/test-local-installation/create_project_and_run_tests.sh +++ b/tools/test-local-installation/create_project_and_run_tests.sh @@ -10,7 +10,6 @@ cd "$(dirname $0)" PROJECT_DIR=$(mktemp -d) echo "Creating project in $PROJECT_DIR" cp -R . $PROJECT_DIR -cp -R ../../driver-bundle/src/test/ $PROJECT_DIR/src/ cp -R ../../playwright/src/test/ $PROJECT_DIR/src/ cd $PROJECT_DIR