Skip to content

Commit ba9dac4

Browse files
committed
chore(codegen): generate the public API from the upstream docs
- scripts/codegen/generate_api.js builds async_api/_generated.py and sync_api/_generated.py from docs/src/api with the upstream doc parser, instead of introspecting playwright/_impl. - scripts/codegen/python_rules.js records the Python facts that the docs do not contain. - scripts/codegen/legacy_order.json and the code marked TEMPORARY keep the old order and formatting, so that the generated diff shows only real changes. Follow-up changes remove them. - Removes the old generator scripts.
1 parent ae494b2 commit ba9dac4

16 files changed

Lines changed: 2739 additions & 1833 deletions

‎.claude/skills/playwright-roll/SKILL.md‎

Lines changed: 82 additions & 68 deletions
Large diffs are not rendered by default.

‎CLAUDE.md‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@ Guidance for Claude when working in this repository.
44

55
## What this is
66

7-
Python bindings for [Playwright](https://playwright.dev). The Python client talks JSON over a pipe to the Node-based driver bundled in `playwright/driver/`. The pipe protocol is defined upstream in `packages/protocol/src/protocol.yml`.
7+
Python bindings for [Playwright](https://playwright.dev). The Python client talks JSON over a pipe to the Node-based driver bundled in `playwright/driver/`. The pipe protocol is defined upstream in `packages/protocol/spec/*.yml`.
88

99
## Layout
1010

1111
- `playwright/_impl/` — hand-written client implementation (one module per object: `_browser.py`, `_page.py`, `_locator.py`, `_network.py`, etc.). Edit these to add or change behavior.
12-
- `playwright/async_api/_generated.py`, `playwright/sync_api/_generated.py` — **auto-generated**. Never edit by hand; rerun `./scripts/update_api.sh` after changing `_impl/` or the driver.
13-
- `scripts/generate_api.py`, `scripts/generate_async_api.py`, `scripts/generate_sync_api.py`, `scripts/documentation_provider.py` — codegen and validation. They diff the Python implementation against Playwright's `api.json` (provided via the `PW_API_JSON` env var; see `scripts/update_api.sh`) and abort if either side is out of sync.
14-
- `scripts/expected_api_mismatch.txt` — explicit allowlist of "documented in JS, not in Python" or "named differently in Python" gaps. Lines that no longer apply must be removed.
12+
- `playwright/async_api/_generated.py`, `playwright/sync_api/_generated.py` — **auto-generated** from the upstream API docs. Never edit by hand; rerun `./scripts/update_api.sh` after a roll or after changing `scripts/codegen/`.
13+
- `scripts/codegen/generate_api.js` — the generator. A Node.js script that loads the upstream doc parser (`utils/doclint/api_parser.js`) from `$PW_SRC_DIR`, filters the docs for Python, and writes the whole public API: signatures, types, docstrings, event overloads, and the calls into `_impl/`. It does not read `_impl/`.
14+
- `scripts/codegen/python_rules.js` — the Python facts that the docs do not contain (positional parameters, struct names, type overrides, hidden members). Policy: the shipped Python API wins; each entry is a candidate for an upstream docs fix, and the generator fails on entries that no longer match anything. Every entry needs a one-line rationale comment above it.
15+
- `scripts/codegen/legacy_order.json` — **temporary**. The old generator's order of classes, members, keyword-only parameters and union members. The generator applies it, and more old habits marked `TEMPORARY` in the generator, so that the switch to the docs generator has a small diff. New members go last. If the generator reports an entry that no longer matches, remove the entry. While the file exists, `_impl_obj` is not typed, so the mypy check described below is not active yet: a docs member that `_impl/` lacks fails only at run time. A follow-up change deletes the file and the `TEMPORARY` code.
16+
- `scripts/codegen/compare_api.py` — compares two generated files (signatures, annotations, call bodies, docstrings) and lists every difference. Use it to check that a generator change does not change the API.
1517
- `tests/async/`, `tests/sync/` — pytest suites. Most new tests are added to the async file with a sync mirror.
1618
- `DRIVER_VERSION` — the single source of truth for which Playwright release the driver is assembled from (one line, the `playwright-core` npm version, e.g. `1.61.0`, no `v` prefix). Read by `setup.py`, `scripts/build_driver.py`, and CI. The wheel build downloads `playwright-core` at this version from npm plus the matching Node.js binary and assembles the per-platform bundles — no source build. The version is baked into the staged bundle filenames (`driver/playwright-<version>-<suffix>.zip`), so it doubles as the build cache key.
1719
- `NODE_VERSION` — the Node.js version bundled with the driver (one line, e.g. `24.16.0`). Maintained at roll time by `scripts/update_node_version.py` (latest LTS, mirroring upstream's `utils/build/update-playwright-node.mjs`).
1820
- `scripts/build_driver.py` — assembles the per-platform driver bundles into `driver/` by downloading the `playwright-core` npm package (`DRIVER_VERSION`) and the official Node.js binaries (`NODE_VERSION`). Fetches `playwright-core` with `npm pack` (needs Node.js/npm on PATH; honours a root `.npmrc`) and the Node.js binaries over plain HTTP; invoked from `setup.py`'s `bdist_wheel` with the target platform's suffix (no arg builds all six).
19-
- `api.json` is **not** shipped in the bundle and is never written into the driver — `scripts/update_api.sh` generates it from a nearby `microsoft/playwright` checkout (`$PW_SRC_DIR`) into a temp file and passes it to codegen via `PW_API_JSON` (read by `scripts/documentation_provider.py`). Needed only when regenerating the API, never at runtime.
21+
- The API docs are **not** shipped in the bundle. `scripts/update_api.sh` reads them from a nearby `microsoft/playwright` checkout (`$PW_SRC_DIR`, at the release branch for `DRIVER_VERSION`). Needed only when regenerating the API, never at runtime.
2022
- `ROLLING.md`, `CONTRIBUTING.md` — human-facing setup and roll docs.
2123

2224
## Setup
@@ -41,7 +43,7 @@ If the system lacks `python3-venv`, `uv venv env` is an acceptable substitute (t
4143
- Type-check: `mypy playwright`.
4244
- Run tests: `pytest --browser chromium [-k name]`. Browsers are installed via `playwright install chromium` (do **not** use `--with-deps`, which requires sudo).
4345

44-
When changing public API, edit `_impl/`, then run `./scripts/update_api.sh`. The script regenerates `_generated.py` and validates against Playwright's `api.json` (which it generates from `$PW_SRC_DIR`). If validation fails, fix the mismatch in `_impl/`, in `expected_api_mismatch.txt`, or in `documentation_provider.py` — not by hand-editing `_generated.py`.
46+
The public API comes from the upstream docs. After `./scripts/update_api.sh`, run `mypy playwright`: the generated classes type their `_impl_obj`, so every new member or option that `_impl/` does not implement yet is a mypy error in `_generated.py`. Fix it in `_impl/`, or record a justified difference in `scripts/codegen/python_rules.js` — not by hand-editing `_generated.py`.
4547

4648
## Rolling Playwright to a new version
4749

@@ -60,7 +62,7 @@ It documents the full process: the upstream commit-range diff over `docs/src/api
6062
- Don't hand-edit generated files.
6163
- Don't add `# type: ignore` or modify `_generated.py` to silence pyright; fix the source of the mismatch.
6264
- New public methods on impl classes need a sync test mirror under `tests/sync/`.
63-
- Keep `expected_api_mismatch.txt` minimal — every entry needs a one-line rationale comment above it.
65+
- Keep `scripts/codegen/python_rules.js` minimal — every entry needs a one-line rationale comment above it. Prefer fixing the upstream docs.
6466
- Prefer `locals_to_params(locals())` for forwarding optional kwargs to channel sends, matching the rest of the codebase.
6567

6668
## Commit Convention

‎CONTRIBUTING.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,11 @@ For more details look at the [CI configuration](./.github/workflows/ci.yml).
7575

7676
### Regenerating APIs
7777

78-
`update_api.sh` generates `api.json` from a nearby `microsoft/playwright`
79-
checkout (at the tag matching `DRIVER_VERSION`); point `PW_SRC_DIR` at it.
78+
`update_api.sh` generates `playwright/{async,sync}_api/_generated.py` from the
79+
API docs in a nearby `microsoft/playwright` checkout (at the release branch
80+
matching `DRIVER_VERSION`); point `PW_SRC_DIR` at it. The generator is
81+
`scripts/codegen/generate_api.js`; Python facts that the docs do not contain
82+
live in `scripts/codegen/python_rules.js`.
8083

8184
```bash
8285
PW_SRC_DIR=../playwright ./scripts/update_api.sh

‎ROLLING.md‎

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,7 @@ pip install -e .
1313
```
1414
* change the driver pin in `DRIVER_VERSION` (the `playwright-core` npm version, e.g. `1.61.0`) and refresh `NODE_VERSION`: `python scripts/update_node_version.py`
1515
* download the new driver: `python -m build --wheel` (fetches `playwright-core` via `npm pack` + the matching Node.js binary and assembles the bundle; no source build).
16-
* generate API (needs a nearby `microsoft/playwright` checkout at `v<new>`): `PW_SRC_DIR=../playwright ./scripts/update_api.sh`
16+
* generate API from the docs (needs a nearby `microsoft/playwright` checkout at the release branch for the new version, e.g. `release-1.64`): `PW_SRC_DIR=../playwright ./scripts/update_api.sh`
17+
* run `mypy playwright`: every error in `_generated.py` points at an implementation method in `playwright/_impl/` that lacks a new member or option. Implement it there, or record the difference in `scripts/codegen/python_rules.js`. (Temporary: while `scripts/codegen/legacy_order.json` exists, mypy does not check this yet; rely on the tests.)
1718
* commit changes & send PR
1819
* wait for bots to pass & merge the PR
19-
20-
21-
## Fix typing issues with Playwright ToT
22-
23-
1. `API_JSON_MODE=1 node ../playwright/utils/doclint/generateApiJson.js > /tmp/api.json`
24-
1. `PW_API_JSON=/tmp/api.json ./scripts/update_api.sh`

0 commit comments

Comments
 (0)