Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ git clone https://github.com/microsoft/playwright-java
cd playwright-java
```

2. Run the following script to download 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 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).

```bash
scripts/download_driver.sh
```

Each driver is assembled from the [`playwright-core`](https://www.npmjs.com/package/playwright-core) npm package (version pinned in [scripts/DRIVER_VERSION](scripts/DRIVER_VERSION)) and the matching Node.js binary from https://nodejs.org, the same way the upstream Playwright build does it.

### Building and running the tests with Maven

```bash
Expand All @@ -39,10 +41,9 @@ BROWSER=chromium mvn test -Dtest=TestPageNetworkSizes

### Generating API

Public Java API is generated from api.json which is produced by `print-api-json` command of playwright CLI. To regenerate Java interfaces for the current driver run the following commands:
Public Java API is generated from api.json, which is generated from the upstream Playwright source at the exact commit that produced the driver version in [scripts/DRIVER_VERSION](scripts/DRIVER_VERSION) (resolved via `npm view playwright@<version> gitHead`). `scripts/generate_api.sh` fetches a minimal upstream checkout automatically; set `PW_SRC_DIR` to reuse an existing `microsoft/playwright` checkout instead. To regenerate Java interfaces for the current driver run:

```bash
./scripts/download_driver.sh
./scripts/generate_api.sh
```

Expand Down
93 changes: 68 additions & 25 deletions scripts/download_driver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ cd "$(dirname $0)"

if [[ ($1 == '-h') || ($1 == '--help') ]]; then
echo ""
echo "This script for downloading playwright driver for all platforms."
echo "The downloaded files will be put under 'driver-bundle/src/main/resources/driver'."
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 ""
echo "Usage: scripts/download_driver.sh [option]"
echo ""
Expand All @@ -19,8 +21,40 @@ if [[ ($1 == '-h') || ($1 == '--help') ]]; then
exit 0
fi

# Ubuntu 24.04-arm64 emulated via qemu has a bug, so we prefer wget over curl.
# See https://github.com/microsoft/playwright-java/issues/1678.
download() {
local url=$1
local out=$2
echo "Downloading $url"
if command -v wget &> /dev/null; then
wget -q -O "$out" "$url"
else
curl --retry 5 --retry-delay 2 -fL -o "$out" "$url"
fi
}

DRIVER_VERSION=$(head -1 ./DRIVER_VERSION)
FILE_PREFIX=playwright-$DRIVER_VERSION

# Resolve the exact upstream commit that produced this driver version, so that the
# bundled Node.js version matches the driver exactly.
GIT_HEAD=$(npm view playwright@"$DRIVER_VERSION" gitHead)
if [[ -z "$GIT_HEAD" ]]; then
echo "Failed to resolve upstream commit (gitHead) for playwright@$DRIVER_VERSION"
exit 1
fi

# The Node.js version is kept in sync with the driver version in the upstream build script.
NODE_VERSION=$(curl -fsSL "https://raw.githubusercontent.com/microsoft/playwright/$GIT_HEAD/utils/build/build-playwright-driver.sh" \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'll get rid of this script later on, so the node version would be somewhere else (probably hardcoded and updated right here in this script).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on the fence, we have this auto-updater upstream which could jus bump NODE_VERSION file there. In any case we can update this line later on.

| sed -n 's/^NODE_VERSION="\([^"]*\)".*/\1/p')
if [[ -z "$NODE_VERSION" ]]; then
echo "Failed to determine Node.js version for playwright@$DRIVER_VERSION ($GIT_HEAD)"
exit 1
fi

echo "Driver version: $DRIVER_VERSION"
echo "Upstream commit: $GIT_HEAD"
echo "Node.js version: $NODE_VERSION"

cd ../driver-bundle/src/main/resources

Expand All @@ -32,32 +66,41 @@ fi
mkdir -p driver
cd driver

for PLATFORM in mac mac-arm64 linux linux-arm64 win32_x64
# Download the platform-independent driver package (playwright-core) once.
CORE_TGZ="$(pwd)/playwright-core-$DRIVER_VERSION.tgz"
download "https://registry.npmjs.org/playwright-core/-/playwright-core-$DRIVER_VERSION.tgz" "$CORE_TGZ"

# <java platform dir>:<nodejs platform suffix>:<archive extension>
for ENTRY in \
"mac:darwin-x64:tar.gz" \
"mac-arm64:darwin-arm64:tar.gz" \
"linux:linux-x64:tar.gz" \
"linux-arm64:linux-arm64:tar.gz" \
"win32_x64:win-x64:zip"
do
FILE_NAME=$FILE_PREFIX-$PLATFORM.zip
mkdir $PLATFORM
cd $PLATFORM
echo "Downloading driver for $PLATFORM to $(pwd)"

URL=https://cdn.playwright.dev/builds/driver
if [[ "$DRIVER_VERSION" == *-alpha* || "$DRIVER_VERSION" == *-beta* || "$DRIVER_VERSION" == *-next* ]]; then
URL=$URL/next
fi
URL=$URL/$FILE_NAME
echo "Using url: $URL"
# Ubuntu 24.04-arm64 emulated via qemu has a bug, so we prefer wget over curl.
# See https://github.com/microsoft/playwright-java/issues/1678.
if command -v wget &> /dev/null; then
wget $URL
IFS=':' read -r PLATFORM NODE_SUFFIX ARCHIVE <<< "$ENTRY"
echo "Assembling driver for $PLATFORM to $(pwd)/$PLATFORM"
mkdir "$PLATFORM"

# 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_DIR="node-v$NODE_VERSION-$NODE_SUFFIX"
NODE_ARCHIVE="$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"
else
curl --retry 5 --retry-delay 2 -fL -O $URL
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"
fi
unzip $FILE_NAME -d .
rm $FILE_NAME

cd -
rm -f "$NODE_ARCHIVE"
done

rm -f "$CORE_TGZ"

echo ""
echo "All drivers have been successfully downloaded."
echo "All drivers have been successfully assembled."
echo ""
53 changes: 33 additions & 20 deletions scripts/generate_api.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,39 @@ set +x
trap 'cd $(pwd -P)' EXIT
cd "$(dirname "$0")/.."

PLAYWRIGHT_CLI="unknown"
case $(uname) in
Darwin)
PLAYWRIGHT_CLI=./driver-bundle/src/main/resources/driver/mac/package/cli.js
;;
Linux)
PLAYWRIGHT_CLI=./driver-bundle/src/main/resources/driver/linux/package/cli.js
;;
MINGW64*)
PLAYWRIGHT_CLI=./driver-bundle/src/main/resources/driver/win32_x64/package/cli.js
;;
*)
echo "Unknown platform '$(uname)'"
exit 1;
;;
esac

echo "Updating api.json from $($PLAYWRIGHT_CLI --version)"

node $PLAYWRIGHT_CLI print-api-json > ./tools/api-generator/src/main/resources/api.json
DRIVER_VERSION=$(head -1 ./scripts/DRIVER_VERSION)

# api.json is generated from the upstream Playwright source at the exact commit
# that produced this driver version. Set PW_SRC_DIR to reuse an existing upstream
# checkout, otherwise a minimal one is fetched into a temporary directory.
GIT_HEAD=$(npm view playwright@"$DRIVER_VERSION" gitHead)
if [[ -z "$GIT_HEAD" ]]; then
echo "Failed to resolve upstream commit (gitHead) for playwright@$DRIVER_VERSION"
exit 1
fi

CLONED_UPSTREAM=""
if [[ -n "$PW_SRC_DIR" ]]; then
UPSTREAM_DIR="$PW_SRC_DIR"
echo "Using upstream Playwright checkout at $UPSTREAM_DIR (PW_SRC_DIR)"
else
UPSTREAM_DIR=$(mktemp -d)
CLONED_UPSTREAM="$UPSTREAM_DIR"
echo "Fetching upstream Playwright source at $GIT_HEAD"
# generateApiJson.js only needs utils/ and docs/, so fetch just those.
git clone --quiet --filter=blob:none --no-checkout https://github.com/microsoft/playwright.git "$UPSTREAM_DIR"
git -C "$UPSTREAM_DIR" sparse-checkout init --cone
git -C "$UPSTREAM_DIR" sparse-checkout set utils docs
git -C "$UPSTREAM_DIR" checkout --quiet "$GIT_HEAD"
fi

echo "Updating api.json from upstream playwright@$DRIVER_VERSION ($GIT_HEAD)"
API_JSON_MODE=1 node "$UPSTREAM_DIR/utils/doclint/generateApiJson.js" \
> ./tools/api-generator/src/main/resources/api.json

if [[ -n "$CLONED_UPSTREAM" ]]; then
rm -rf "$CLONED_UPSTREAM"
fi

mvn compile -f ./tools/api-generator --no-transfer-progress

Expand Down
Loading