playwright-roll

Installation
SKILL.md

Rolling Playwright Python

The goal of a roll is to move the driver pin in DRIVER_VERSION to a new release, port every public API change introduced upstream during that interval, and suppress the rest, so that ./scripts/update_api.sh and mypy playwright run clean and the test suite still passes.

The previous human-facing summary lives in ../../../ROLLING.md. This skill is the operational playbook — read it end to end before starting.

Mental model

The Python port is hand-written code in playwright/_impl/, plus a generator (scripts/codegen/generate_api.js) that:

  1. parses the upstream docs ($PW_SRC_DIR/docs/src/api) with the upstream parser and filters them for Python,
  2. applies the Python facts that the docs do not contain, from scripts/codegen/python_rules.js, and
  3. emits the whole public API into playwright/{async,sync}_api/_generated.py: signatures, types, docstrings, event overloads, and the call into _impl/ for every member.

The generator never reads _impl/. A new member or option in the docs therefore shows up in _generated.py right away, as a call into _impl/ that does not exist yet. Each generated class types its _impl_obj, so mypy playwright lists every such gap as an error in _generated.py. Three resolutions:

  • PORT — the new API is intended for Python (no langs.only filter, or langs.only includes "python"). Implement it in _impl/ until mypy is clean.
  • MISMATCH — the shipped Python API differs from the docs (a callback signature uses unions, a kwarg uses a legacy name, etc.). The shipped implementation wins. Add an entry to scripts/codegen/python_rules.js with a comment explaining why, and propose the upstream docs change that would make the entry unnecessary.
  • N/A — the commit only touches docs, has * langs: js (or any other filter that excludes Python), is server-side, Electron-only, or was reverted later in the same release. No action; the generator already leaves it out.
Installs
20
GitHub Stars
15.0K
First Seen
Feb 2, 2026