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
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jobs:
docker:
- image: cimg/ruby:3.4
- image: mcr.microsoft.com/playwright:v1.61.1-noble
command: /bin/sh -c "cd /home/pwuser ; npx --yes playwright@1.61.1 install && npx playwright@1.61.1 run-server --port 8888 --host 0.0.0.0 --path /ws"
command: /bin/sh -c "cd /home/pwuser && npm install --no-save playwright-core@1.61.1 && ./node_modules/.bin/playwright-core install && ./node_modules/.bin/playwright-core run-server --port 8888 --host 0.0.0.0 --path /ws"
environment:
DEBUG: "pw:*"
user: pwuser
Expand Down
9 changes: 4 additions & 5 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ jobs:
with:
ruby-version: 3.4
bundler-cache: true
- name: Download playwright driver
run: |
wget -O driver.zip https://playwright.azureedge.net/builds/driver/next/playwright-$(cat development/CLI_VERSION)-linux.zip || wget -O driver.zip https://playwright.azureedge.net/builds/driver/playwright-$(cat development/CLI_VERSION)-linux.zip
unzip driver.zip && rm driver.zip
- uses: actions/setup-node@v3
with:
node-version: 22
- name: re-generate codes
run: |
./node ./package/cli.js print-api-json | jq . > development/api.json
./development/generate_api_json.sh
find documentation/docs -name "*.md" | grep -v documentation/docs/article/ | xargs rm
bundle exec ruby development/generate_api.rb
- name: Check if api.json is updated
Expand Down
22 changes: 11 additions & 11 deletions .github/workflows/rspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
name: playwright_api
path: lib/playwright_api

integration_test_with_npm_playwright_driver:
integration_test_with_npm_playwright_core:
needs: [unit_test, generate_playwright_api]
strategy:
fail-fast: false
Expand All @@ -59,12 +59,12 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 22
- name: setup ${{ matrix.version }} playwright via npm install
- name: Set up playwright-core via npm install
run: |
export PLAYWRIGHT_CLI_VERSION=$(bundle exec ruby -e 'puts Playwright::COMPATIBLE_PLAYWRIGHT_VERSION.strip')
npm install playwright@${PLAYWRIGHT_CLI_VERSION} || npm install playwright@next
./node_modules/.bin/playwright install ${{ matrix.browser }}
./node_modules/.bin/playwright install-deps
npm install playwright-core@${PLAYWRIGHT_CLI_VERSION}
./node_modules/.bin/playwright-core install ${{ matrix.browser }}
./node_modules/.bin/playwright-core install-deps
sudo apt-get install -y ffmpeg
- name: Download playwright_api codes
uses: actions/download-artifact@v4
Expand All @@ -76,7 +76,7 @@ jobs:
bundle exec rspec spec/integration --profile 10
env:
BROWSER: ${{ matrix.browser }}
PLAYWRIGHT_CLI_EXECUTABLE_PATH: ./node_modules/.bin/playwright
PLAYWRIGHT_CLI_EXECUTABLE_PATH: ./node_modules/.bin/playwright-core
timeout-minutes: 25

test_example_spec:
Expand All @@ -96,12 +96,12 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 22
- name: setup ${{ matrix.version }} playwright via npm install
- name: Set up playwright-core via npm install
run: |
export PLAYWRIGHT_CLI_VERSION=$(bundle exec ruby -e 'puts Playwright::COMPATIBLE_PLAYWRIGHT_VERSION.strip')
npm install playwright@${PLAYWRIGHT_CLI_VERSION} || npm install playwright@next
./node_modules/.bin/playwright install chromium
./node_modules/.bin/playwright install-deps
npm install playwright-core@${PLAYWRIGHT_CLI_VERSION}
./node_modules/.bin/playwright-core install chromium
./node_modules/.bin/playwright-core install-deps
- name: Download playwright_api codes
uses: actions/download-artifact@v4
with:
Expand All @@ -110,5 +110,5 @@ jobs:
- run: bundle exec rspec spec/integration/example_spec.rb
env:
BROWSER: chromium
PLAYWRIGHT_CLI_EXECUTABLE_PATH: ./node_modules/.bin/playwright
PLAYWRIGHT_CLI_EXECUTABLE_PATH: ./node_modules/.bin/playwright-core
timeout-minutes: 10
9 changes: 5 additions & 4 deletions .github/workflows/windows_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 22
- name: Install playwright driver via npx
- name: Install playwright-core via npm
run: |
npx playwright@next install chromium
npx playwright@next install-deps chromium
npm install playwright-core@next
./node_modules/.bin/playwright-core install chromium
./node_modules/.bin/playwright-core install-deps chromium
- run: bundle exec ruby development/generate_api.rb
- name: Check example
run: bundle exec rspec spec/integration/example_spec.rb
env:
PLAYWRIGHT_CLI_EXECUTABLE_PATH: npx playwright@next
PLAYWRIGHT_CLI_EXECUTABLE_PATH: ./node_modules/.bin/playwright-core
timeout-minutes: 5
6 changes: 5 additions & 1 deletion CLAUDE/api_generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

## Source of generated artifacts

- Input: `development/api.json`
- API definition generator: `development/generate_api_json.sh`
- API definition: `development/api.json`
- Generator script: `development/generate_api.rb`

`generate_api_json.sh` resolves the exact upstream Playwright commit from the version in `development/CLI_VERSION`, then generates the API definition from upstream `utils/` and `docs/`. It does not use the Playwright CLI. Set `PW_SRC_DIR` to reuse an existing checkout at the resolved commit.

## Generated outputs

- `lib/playwright_api/*.rb`
Expand All @@ -22,6 +25,7 @@
## Typical command set

```sh
./development/generate_api_json.sh
rm lib/playwright_api/*.rb
find documentation/docs -name "*.md" | grep -v documentation/docs/article/ | xargs rm
bundle exec ruby development/generate_api.rb
Expand Down
1 change: 1 addition & 0 deletions CLAUDE/ci_expectations.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Checked paths:

## Practical implication

- If the Playwright version changes, run `development/generate_api_json.sh` before regenerating artifacts.
- If API-related code changes, regenerate artifacts before finishing.
- If you open a PR without regeneration, `check.yml` will likely fail.

Expand Down
10 changes: 6 additions & 4 deletions CLAUDE/playwright_upgrade_workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ Standard process for `Update Playwright driver to 1.xx.x` tasks.
1. Update versions
- `development/CLI_VERSION`
- `lib/playwright/version.rb` (`VERSION`, `COMPATIBLE_PLAYWRIGHT_VERSION`)
- `.circleci/config.yml` remote Playwright server image and `npx playwright@...` version
- `.circleci/config.yml` remote Playwright server image and `playwright-core@...` version

2. Review upstream Playwright PRs
- Follow `CLAUDE/upstream_pr_review.md`.
- This review is mandatory for Node.js Playwright to Ruby porting work.
- Do not start deciding Ruby implementation scope from generated API diffs alone.

3. Update API definition
- Set `PLAYWRIGHT_CLI_EXECUTABLE_PATH`
- `$PLAYWRIGHT_CLI_EXECUTABLE_PATH print-api-json | jq . > development/api.json`
- Update `development/CLI_VERSION` first.
- Run `./development/generate_api_json.sh`.
- The script resolves the exact upstream commit from `playwright-core` npm metadata and generates the API definition from the upstream `utils/` and `docs/` sources.
- Set `PW_SRC_DIR` to reuse an existing upstream checkout at the resolved commit.

4. Clean before generation + regenerate
- `rm lib/playwright_api/*.rb`
Expand All @@ -41,4 +43,4 @@ Standard process for `Update Playwright driver to 1.xx.x` tasks.
## Notes

- During upgrade work, prefer the steps in `development/README.md`.
- `development/update_playwright_driver.sh` can be used as a helper script.
- Install the compatible `playwright-core` npm package and set `PLAYWRIGHT_CLI_EXECUTABLE_PATH` to `node_modules/.bin/playwright-core`.
29 changes: 12 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,22 @@ gem 'playwright-ruby-client'

and then 'bundle install'.

Since playwright-ruby-client doesn't include the playwright driver, **we have to install [playwright](https://github.com/microsoft/playwright) in advance**.
Since playwright-ruby-client doesn't include Playwright, **we have to install Node.js and a compatible version of [playwright-core](https://www.npmjs.com/package/playwright-core) in advance**.

```sh
PLAYWRIGHT_CLI_VERSION=$(bundle exec ruby -e 'require "playwright/version"; puts Playwright::COMPATIBLE_PLAYWRIGHT_VERSION')
npm install "playwright-core@$PLAYWRIGHT_CLI_VERSION"
./node_modules/.bin/playwright-core install
```
npm install playwright
./node_modules/.bin/playwright install
```

And set `playwright_cli_executable_path: './node_modules/.bin/playwright'`

**Prefer playwrighting without Node.js?**

Instead of npm, you can also directly download playwright driver from playwright.azureedge.net/builds/. The URL can be easily detected from [here](https://github.com/microsoft/playwright-python/blob/cb5409934629adaabc0cff1891080de2052fa778/setup.py#L73-L77)
And set `playwright_cli_executable_path: './node_modules/.bin/playwright-core'`.

### Capture a site

```ruby
require 'playwright'

Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright-core') do |playwright|
playwright.chromium.launch(headless: false) do |browser|
page = browser.new_page
page.goto('https://github.com/YusukeIwaki')
Expand All @@ -46,7 +43,7 @@ end
```ruby
require 'playwright'

Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright-core') do |playwright|
playwright.chromium.launch(headless: false) do |browser|
page = browser.new_page
page.goto('https://github.com/')
Expand Down Expand Up @@ -94,7 +91,7 @@ $ bundle exec ruby main.rb
```ruby
require 'playwright'

Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright-core') do |playwright|
devices = playwright.android.devices
unless devices.empty?
device = devices.last
Expand Down Expand Up @@ -128,12 +125,10 @@ end
We have to download android-driver for Playwright in advance.

```
wget https://github.com/microsoft/playwright/raw/master/bin/android-driver-target.apk -O /path/to/playwright-driver/package/bin/android-driver-target.apk
wget https://github.com/microsoft/playwright/raw/master/bin/android-driver.apk -O /path/to/playwright-driver/package/bin/android-driver.apk
wget https://github.com/microsoft/playwright/raw/master/bin/android-driver-target.apk -O ./node_modules/playwright-core/bin/android-driver-target.apk
wget https://github.com/microsoft/playwright/raw/master/bin/android-driver.apk -O ./node_modules/playwright-core/bin/android-driver.apk
```

(If you downloaded Playwright via npm, replace `/path/to/playwright-driver/package/` with `./node_modules/playwright/` above.)

```ruby
require 'playwright'

Expand Down Expand Up @@ -168,7 +163,7 @@ If your environment doesn't accept installing browser or creating browser proces
For launching Playwright server, just execute:

```
npx playwright install && npx playwright run-server --port 8080 --path /ws
./node_modules/.bin/playwright-core install && ./node_modules/.bin/playwright-core run-server --port 8080 --path /ws
```

and we can connect to the server with the code like this:
Expand Down
34 changes: 12 additions & 22 deletions development/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,29 @@
bin/setup
```

- Install Node.js and the Playwright driver. Use the version defined in [`lib/playwright/version.rb`](../lib/playwright/version.rb):
- Install Node.js and `playwright-core`. Use the version defined in [`lib/playwright/version.rb`](../lib/playwright/version.rb):

```sh
VERSION=$(ruby -r "./lib/playwright/version" -e "puts Playwright::COMPATIBLE_PLAYWRIGHT_VERSION")
npm install "playwright@$VERSION"
npm install "playwright-core@$VERSION"
```
Avoid using `npx` to install Playwright because it always fetches the latest version.
Avoid using an unversioned `npx` command because it can fetch an incompatible version.

- Set the `PLAYWRIGHT_CLI_EXECUTABLE_PATH` environment variable. For example:

```sh
export PLAYWRIGHT_CLI_EXECUTABLE_PATH="$(pwd)/node_modules/.bin/playwright"
export PLAYWRIGHT_CLI_EXECUTABLE_PATH="$(pwd)/node_modules/.bin/playwright-core"
```

## API generation and testing

### (opt) Download driver

Edit `development/CLI_VERSION` and then download the specific version of driver. It can be found in https://github.com/microsoft/playwright/actions/workflows/publish_canary.yml

```
wget https://playwright.azureedge.net/builds/driver/next/playwright-$(cat development/CLI_VERSION)-mac.zip
```

Then, extract the driver zip file, and set `PLAYWRIGHT_CLI_EXECUTABLE_PATH`.

Note that Playwright >= 1.43 doesn't include playwright.sh, and we have to set `$DRIVER_DOWNLOAD_PATH/node $DRIVER_DOWNLOAD_PATH/package/cli.js` into PLAYWRIGHT_CLI_EXECUTABLE_PATH or manually put https://github.com/microsoft/playwright/blob/v1.42.1/utils/build/run-driver-posix.sh into the root of the downloaded driver's dir.

### Create/Update API definition

```sh
./development/generate_api_json.sh
```
$PLAYWRIGHT_CLI_EXECUTABLE_PATH print-api-json | jq > development/api.json
```

This resolves the upstream commit from the version in `development/CLI_VERSION`, checks out only the required `utils/` and `docs/` directories, and generates `development/api.json` from the upstream source. Set `PW_SRC_DIR` to reuse an existing checkout at the resolved commit.

### Generate API codes

Expand All @@ -53,9 +43,9 @@ bundle exec ruby development/generate_api.rb
### Test it

```
$PLAYWRIGHT_CLI_EXECUTABLE_PATH install
bundle exec rspec
"$PLAYWRIGHT_CLI_EXECUTABLE_PATH" install
rbenv exec bundle exec rspec
```

* Testing with **latest** version of playwright driver might fail because of some breaking changes
* Testing with **next** version of playwright **must be passed**
* Testing with the **latest** version of `playwright-core` might fail because of breaking changes.
* Testing with the **next** version of `playwright-core` must pass.
4 changes: 2 additions & 2 deletions development/generate_api/example_codes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1475,7 +1475,7 @@ def example_ba01da1f358cafb4c22b792488ff2f3de4dbd82d4ee1cc4050e3f0c24a2bd7dd(pag
def example_6647e5a44b0440884026a6142606dfddad75ba1e643919b015457df4ed2e198f
require 'playwright'

Playwright.create(playwright_cli_executable_path: 'npx playwright') do |playwright|
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright-core') do |playwright|
chromium = playwright.chromium # or "firefox" or "webkit".
chromium.launch do |browser|
page = browser.new_page
Expand All @@ -1491,7 +1491,7 @@ def example_6647e5a44b0440884026a6142606dfddad75ba1e643919b015457df4ed2e198f
def example_14d627977a4ad16a605ec5472d768a3324812fa8e7c57685561408fa6601e352
require 'playwright'

Playwright.create(playwright_cli_executable_path: 'npx playwright') do |playwright|
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright-core') do |playwright|
iphone = playwright.devices["iPhone 6"]
playwright.webkit.launch do |browser|
context = browser.new_context(**iphone)
Expand Down
68 changes: 68 additions & 0 deletions development/generate_api_json.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env bash

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
PLAYWRIGHT_VERSION="${1:-$(tr -d '[:space:]' < "$SCRIPT_DIR/CLI_VERSION")}"
API_JSON_PATH="$REPO_ROOT/development/api.json"

if [[ -z "$PLAYWRIGHT_VERSION" ]]; then
echo "Playwright version is empty." >&2
exit 1
fi

for command_name in git jq node npm; do
if ! command -v "$command_name" >/dev/null 2>&1; then
echo "Required command is not available: $command_name" >&2
exit 1
fi
done

PLAYWRIGHT_GIT_HEAD="$(npm view "playwright-core@$PLAYWRIGHT_VERSION" gitHead)"
if [[ ! "$PLAYWRIGHT_GIT_HEAD" =~ ^[0-9a-f]{40}$ ]]; then
echo "Failed to resolve gitHead for playwright-core@$PLAYWRIGHT_VERSION." >&2
exit 1
fi

TEMP_API_JSON="$(mktemp "$API_JSON_PATH.tmp.XXXXXX")"
CLONED_SOURCE_DIR=""

cleanup() {
rm -f -- "$TEMP_API_JSON"
if [[ -n "$CLONED_SOURCE_DIR" ]]; then
rm -rf -- "$CLONED_SOURCE_DIR"
fi
}
trap cleanup EXIT

if [[ -n "${PW_SRC_DIR:-}" ]]; then
PLAYWRIGHT_SOURCE_DIR="$PW_SRC_DIR"
SOURCE_GIT_HEAD="$(git -C "$PLAYWRIGHT_SOURCE_DIR" rev-parse HEAD)"
if [[ "$SOURCE_GIT_HEAD" != "$PLAYWRIGHT_GIT_HEAD" ]]; then
echo "PW_SRC_DIR is at $SOURCE_GIT_HEAD, expected $PLAYWRIGHT_GIT_HEAD for playwright-core@$PLAYWRIGHT_VERSION." >&2
exit 1
fi
else
CLONED_SOURCE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/playwright-source.XXXXXX")"
PLAYWRIGHT_SOURCE_DIR="$CLONED_SOURCE_DIR"

git -C "$PLAYWRIGHT_SOURCE_DIR" init --quiet
git -C "$PLAYWRIGHT_SOURCE_DIR" remote add origin https://github.com/microsoft/playwright.git
git -C "$PLAYWRIGHT_SOURCE_DIR" sparse-checkout init --cone
git -C "$PLAYWRIGHT_SOURCE_DIR" sparse-checkout set utils docs
git -C "$PLAYWRIGHT_SOURCE_DIR" fetch --quiet --depth 1 origin "$PLAYWRIGHT_GIT_HEAD"
git -C "$PLAYWRIGHT_SOURCE_DIR" checkout --quiet --detach FETCH_HEAD
fi

echo "Generating api.json for playwright-core@$PLAYWRIGHT_VERSION ($PLAYWRIGHT_GIT_HEAD)"
API_JSON_MODE=1 node "$PLAYWRIGHT_SOURCE_DIR/utils/doclint/generateApiJson.js" |
jq . > "$TEMP_API_JSON"

if [[ ! -s "$TEMP_API_JSON" ]]; then
echo "Generated api.json is empty." >&2
exit 1
fi

mv "$TEMP_API_JSON" "$API_JSON_PATH"
echo "Updated $API_JSON_PATH"
Loading
Loading