You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 4e1ce7a
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: AGENTS.md
+5-6Lines changed: 5 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ Python bindings for [Playwright](https://playwright.dev). The Python client talk
9
9
## Layout
10
10
11
11
-`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. Internal types are in `_internal_structures.py`.
12
-
-`playwright/_impl_v2/` — the second implementation, a line-by-line port of upstream's JS client (`packages/playwright-core/src/client/*.ts`), one module per client file in snake_case (`browserContext.ts` is `browser_context.py`), members in the JS order. It has only the async API; `PW_IMPL=v2` switches the async API to it (`playwright/_impl/_api_classes.py`). Each difference from the JS code has a `# Python:` comment; see its `__init__.py` for the rules. `isomorphic/`, `protocol/` and `utils/` hold its own ports of the parts of `packages/isomorphic`, `packages/protocol` and `packages/utils` that it uses; from `playwright/_impl` it uses only the public error classes, `FormData`, the generated API types, the driver location and the protocol check. `protocol_channels.py`, `protocol_types.py` and `protocol/validator.py` are generated by `scripts/codegen/generate_protocol.py`.
12
+
- `playwright/_impl_v2/` — the second implementation, a line-by-line port of upstream's JS client (`packages/playwright-core/src/client/*.ts`), one module per client file in snake_case (`browserContext.ts` is `browser_context.py`), members in the JS order. `PW_IMPL=v2` switches the async and the sync API to it (`playwright/_impl/_api_classes.py`, `playwright/{async,sync}_api/_context_manager.py`); the sync API is the greenlet mechanism of v1, shared (`playwright/_impl/_sync_base.py`, `playwright/_impl/_greenlets.py`). Each difference from the JS code has a `# Python:` comment; see its `__init__.py` for the rules. `isomorphic/`, `protocol/` and `utils/` hold its own ports of the parts of `packages/isomorphic`, `packages/protocol` and `packages/utils` that it uses; from `playwright/_impl` it uses only the public error classes, `FormData`, the generated API types, the driver location, the protocol check and the greenlets of the sync API. `protocol_channels.py`, `protocol_types.py` and `protocol/validator.py` are generated by `scripts/codegen/generate_protocol.py`.
13
13
-`playwright/async_api/_generated.py`, `playwright/sync_api/_generated.py`, and the public TypedDicts in `playwright/_impl/_api_structures.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/`.
14
14
-`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, the calls into `_impl/`, and the TypedDicts. It does not read `_impl/`.
15
15
-`scripts/codegen/python_rules.js` — the Python facts that the docs do not contain (positional options, struct `total=`, hidden members and options). 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.
@@ -18,7 +18,7 @@ Python bindings for [Playwright](https://playwright.dev). The Python client talk
18
18
-`_protocol_types.py` has the TypedDicts for initializers, results, events and nested types, named as upstream's `utils/generate_channels.js` names them (`PageInitializer`, `FrameGotoResult`, `PageRouteEvent`, …).
19
19
-`_protocol.py` has the parameters of every command. With `PW_CHECK_PROTOCOL=1`, `playwright/_impl/_protocol_check.py` checks each message that the client sends against it. The test suite sets this, and fails a test that sends an unknown command, an unknown or missing parameter, or a value of the wrong type.
20
20
-`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.
21
-
-`tests/async/`, `tests/sync/` — pytest suites, ported test for test from the upstream tests, which `tests/upstream_registry.md` lists by identifier. See [Tests](#tests). `playwright/_impl` (v1, the default) runs the older tests in `tests/{async,sync}/legacy/` and the other tests outside of `tests/async` and `tests/sync`; `PW_IMPL=v2` runs `playwright/_impl_v2` on all of `tests/async` (`tests/conftest.py`). CI runs v2 on Ubuntu 22.04 with Chromium, Firefox and WebKit. An older test that checks a behavior where v2 follows upstream and v1 does not is marked `@only_v1("<tests of v2>")` (`tests/utils.py`), naming the upstream port that covers v2, or the Python-only test of v2 in `tests/async/python/`, which v1 does not run.
21
+
-`tests/async/`, `tests/sync/` — pytest suites, ported test for test from the upstream tests, which `tests/upstream_registry.md` lists by identifier. See [Tests](#tests). `playwright/_impl` (v1, the default) runs the older tests in `tests/{async,sync}/legacy/` and the other tests outside of `tests/async` and `tests/sync`; `PW_IMPL=v2` runs `playwright/_impl_v2` on all of `tests/async`and `tests/sync`(`tests/conftest.py`). CI runs v2 on Ubuntu 22.04 with Chromium, Firefox and WebKit. An older test that checks a behavior where v2 follows upstream and v1 does not is marked `@only_v1("<tests of v2>")` (`tests/utils.py`), naming the upstream port that covers v2, or the Python-only test of v2 in `tests/async/python/`, which v1 does not run.
22
22
-`DRIVER_VERSION` — the single source of truth for which Playwright build the driver is assembled from. Two lines: `npm=<version>`, the `playwright-core` npm version (e.g. `npm=1.61.0`, no `v` prefix), and `rev=<sha>`, the `microsoft/playwright` commit that the package is built from (`npm view playwright-core@<version> gitHead`). Read by `setup.py`, `scripts/build_driver.py`, `scripts/update_api.sh`, and CI (through `setup.py`). 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.
23
23
-`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`).
24
24
-`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).
@@ -35,17 +35,16 @@ pip install --upgrade pip
35
35
pip install -r local-requirements.txt
36
36
pip install -e .
37
37
python -m build --wheel # downloads playwright-core @ DRIVER_VERSION + Node.js and assembles the driver
38
-
pre-commit install
39
38
```
40
39
41
40
If the system lacks `python3-venv`, `uv venv env` is an acceptable substitute (then `uv pip install --python env/bin/python --upgrade pip`).
42
41
43
42
## Common commands
44
43
45
44
- Regenerate `_generated.py`: `./scripts/update_api.sh` (runs codegen + pre-commit on the generated files).
46
-
- Lint everything: `pre-commit run --all-files`.
45
+
- Lint everything: `pre-commit run --all-files` (what the Lint job of CI runs; the checks are not a git hook, do not `pre-commit install`).
47
46
- Type-check: `mypy playwright`.
48
-
- Run tests: `pytest --browser chromium [-k name]` (v1), `PW_IMPL=v2 pytest tests/async --browser chromium` (v2), or `./test.sh [browser]` for both. Browsers are installed via `playwright install chromium` (do **not** use `--with-deps`, which requires sudo).
47
+
- Run tests: `pytest --browser chromium [-k name]` (v1), `PW_IMPL=v2 pytest tests/sync tests/async --browser chromium` (v2; `./test-v2.sh [browser]` runs both suites), or `./test.sh [browser]` for both implementations. Browsers are installed via `playwright install chromium` (do **not** use `--with-deps`, which requires sudo).
49
48
50
49
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`.
51
50
@@ -91,7 +90,7 @@ It documents the full process: the upstream commit-range diff over `docs/src/api
91
90
92
91
## Commit Convention
93
92
94
-
Before committing, run `mypy playwright` and fix errors.
93
+
Before committing, run `pre-commit run --all-files` (the Lint job of CI) and fix errors.
Copy file name to clipboardExpand all lines: ROLLING.md
-1Lines changed: 0 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,6 @@
8
8
```
9
9
python -m pip install --upgrade pip
10
10
pip install -r local-requirements.txt
11
-
pre-commit install
12
11
pip install -e .
13
12
```
14
13
* change the driver pin in `DRIVER_VERSION`: `npm=` the `playwright-core` npm version (e.g. `1.61.0`) and `rev=` the commit it is built from (`npm view playwright-core@<version> gitHead`); refresh `NODE_VERSION`: `python scripts/update_node_version.py`
0 commit comments