Skip to content

Commit a8919c8

Browse files
committed
Merge remote-tracking branch 'upstream/main' into dgozman-form-data
# Conflicts: # playwright/async_api/_generated.py # playwright/sync_api/_generated.py # scripts/generate_api.py
2 parents daf6a18 + b846cee commit a8919c8

58 files changed

Lines changed: 5666 additions & 1362 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.azure-pipelines/publish.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ extends:
6060
targetPath: $(Build.ArtifactStagingDirectory)/esrp-build
6161
steps:
6262
- checkout: none
63-
- task: EsrpRelease@9
63+
- task: EsrpRelease@11
6464
inputs:
6565
connectedservicename: 'Playwright-ESRP-PME'
6666
usemanagedidentity: true

‎.github/workflows/ci.yml‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
name: Lint
2222
runs-on: ubuntu-latest
2323
steps:
24-
- uses: actions/checkout@v5
24+
- uses: actions/checkout@v6
2525
- name: Set up Python
2626
uses: actions/setup-python@v6
2727
with:
@@ -91,7 +91,7 @@ jobs:
9191
browser: chromium
9292
runs-on: ${{ matrix.os }}
9393
steps:
94-
- uses: actions/checkout@v5
94+
- uses: actions/checkout@v6
9595
- name: Set up Python
9696
uses: actions/setup-python@v6
9797
with:
@@ -138,7 +138,7 @@ jobs:
138138
browser-channel: msedge
139139
runs-on: ${{ matrix.os }}
140140
steps:
141-
- uses: actions/checkout@v5
141+
- uses: actions/checkout@v6
142142
- name: Set up Python
143143
uses: actions/setup-python@v6
144144
with:
@@ -181,11 +181,11 @@ jobs:
181181
# where the default shell is pwsh and skips the activation hooks.
182182
shell: bash -el {0}
183183
steps:
184-
- uses: actions/checkout@v5
184+
- uses: actions/checkout@v6
185185
with:
186186
fetch-depth: 0
187187
- name: Get conda
188-
uses: conda-incubator/setup-miniconda@v3
188+
uses: conda-incubator/setup-miniconda@v4
189189
with:
190190
python-version: '3.12'
191191
channels: conda-forge
@@ -202,7 +202,7 @@ jobs:
202202
run:
203203
working-directory: examples/todomvc/
204204
steps:
205-
- uses: actions/checkout@v5
205+
- uses: actions/checkout@v6
206206
- name: Set up Python
207207
uses: actions/setup-python@v6
208208
with:

‎.github/workflows/publish.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ jobs:
2222
runs-on: ${{ matrix.os }}
2323
defaults:
2424
run:
25-
# Required for conda-incubator/setup-miniconda@v3
25+
# Required for conda-incubator/setup-miniconda@v4
2626
shell: bash -el {0}
2727
steps:
28-
- uses: actions/checkout@v5
28+
- uses: actions/checkout@v6
2929
with:
3030
fetch-depth: 0
3131
- name: Get conda
32-
uses: conda-incubator/setup-miniconda@v3
32+
uses: conda-incubator/setup-miniconda@v4
3333
with:
3434
python-version: '3.12'
3535
channels: conda-forge

‎.github/workflows/publish_docker.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ jobs:
1515
contents: read # This is required for actions/checkout to succeed
1616
environment: Docker
1717
steps:
18-
- uses: actions/checkout@v5
18+
- uses: actions/checkout@v6
1919
- name: Azure login
20-
uses: azure/login@v2
20+
uses: azure/login@v3
2121
with:
2222
client-id: ${{ secrets.AZURE_DOCKER_CLIENT_ID }}
2323
tenant-id: ${{ secrets.AZURE_DOCKER_TENANT_ID }}
@@ -29,7 +29,7 @@ jobs:
2929
with:
3030
python-version: "3.10"
3131
- name: Set up Docker QEMU for arm64 docker builds
32-
uses: docker/setup-qemu-action@v3
32+
uses: docker/setup-qemu-action@v4
3333
with:
3434
platforms: arm64
3535
- name: Install dependencies & browsers

‎.github/workflows/test_docker.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
- ubuntu-24.04
3131
- ubuntu-24.04-arm
3232
steps:
33-
- uses: actions/checkout@v5
33+
- uses: actions/checkout@v6
3434
- name: Set up Python
3535
uses: actions/setup-python@v6
3636
with:

‎CLAUDE.md‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,51 @@ This is the recurring high-stakes task. Use the dedicated skill:
4848

4949
It documents the full process: the upstream commit-range diff over `docs/src/api/`, how to classify each commit (PORT / MISMATCH / N/A), how to handle the `langs:` filter, the recurring failure modes, and the tests/sync-mirroring conventions.
5050

51+
## Working on PRs
52+
53+
- Never post comments, replies, or reviews on GitHub PRs/issues under my account without my explicit approval. Draft the proposed text and wait for me to approve before sending.
54+
5155
## House style
5256

5357
- Don't hand-edit generated files.
5458
- Don't add `# type: ignore` or modify `_generated.py` to silence pyright; fix the source of the mismatch.
5559
- New public methods on impl classes need a sync test mirror under `tests/sync/`.
5660
- Keep `expected_api_mismatch.txt` minimal — every entry needs a one-line rationale comment above it.
5761
- Prefer `locals_to_params(locals())` for forwarding optional kwargs to channel sends, matching the rest of the codebase.
62+
63+
## Commit Convention
64+
65+
Before committing, run `mypy playwright` and fix errors.
66+
67+
Semantic commit messages: `label(scope): description`
68+
69+
Labels: `fix`, `feat`, `chore`, `docs`, `test`, `devops`
70+
71+
```bash
72+
git checkout -b fix-12345
73+
# ... make changes ...
74+
git add <changed-files>
75+
git commit -m "$(cat <<'EOF'
76+
fix(asyncio): do not deadlock in atexit handler
77+
78+
Fixes: https://github.com/microsoft/playwright-python/issues/12345
79+
EOF
80+
)"
81+
git push origin fix-12345
82+
gh pr create --repo microsoft/playwright-python --head username:fix-12345 \
83+
--title "fix(asyncio): do not deadlock in atexit handler" \
84+
--body "$(cat <<'EOF'
85+
## Summary
86+
- <describe the change very! briefly>
87+
88+
Fixes https://github.com/microsoft/playwright-python/issues/12345
89+
EOF
90+
)"
91+
```
92+
93+
Never add Co-Authored-By agents in commit message.
94+
Never add "Generated with" in commit message.
95+
Never add test plan to PR description. Keep PR description short — a few bullet points at most.
96+
Branch naming for issue fixes: `fix-<issue-number>`
97+
98+
**Never `git push` without an explicit instruction to push.** Applies even when a PR is already open for the branch — additional commits are immediately visible to reviewers. Commit locally, report what was committed, and wait. Only push when the user's message contains "push", "upload", "create PR", "ship it", or equivalent.

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ Playwright is a Python library to automate [Chromium](https://www.chromium.org/H
44

55
| | Linux | macOS | Windows |
66
| :--- | :---: | :---: | :---: |
7-
| Chromium <!-- GEN:chromium-version -->147.0.7727.15<!-- GEN:stop --> | ✅ | ✅ | ✅ |
7+
| Chromium <!-- GEN:chromium-version -->148.0.7778.96<!-- GEN:stop --> | ✅ | ✅ | ✅ |
88
| WebKit <!-- GEN:webkit-version -->26.4<!-- GEN:stop --> | ✅ | ✅ | ✅ |
9-
| Firefox <!-- GEN:firefox-version -->148.0.2<!-- GEN:stop --> | ✅ | ✅ | ✅ |
9+
| Firefox <!-- GEN:firefox-version -->150.0.2<!-- GEN:stop --> | ✅ | ✅ | ✅ |
1010

1111
## Documentation
1212

‎local-requirements.txt‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1+
asyncio-atexit==1.0.1
12
autobahn==23.1.2
23
black==25.1.0
34
build==1.3.0
4-
flake8==7.2.0
5+
flake8==7.3.0
56
mypy==1.17.1
67
objgraph==3.6.2
78
Pillow==11.3.0
89
pixelmatch==0.3.0
910
pre-commit==3.5.0
10-
pyOpenSSL==25.1.0
11+
pyOpenSSL==26.0.0
1112
pytest==8.4.1
1213
pytest-asyncio==1.1.0
13-
pytest-cov==6.3.0
14+
pytest-cov==7.1.0
1415
pytest-repeat==0.9.4
1516
pytest-rerunfailures==15.1
1617
pytest-timeout==2.4.0
@@ -19,4 +20,4 @@ requests==2.32.5
1920
service_identity==24.2.0
2021
twisted==25.5.0
2122
types-pyOpenSSL==24.1.0.20240722
22-
types-requests==2.32.4.20250809
23+
types-requests==2.32.4.20260107

‎playwright/_impl/_api_structures.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,31 @@ class ViewportSize(TypedDict):
151151

152152
class SourceLocation(TypedDict):
153153
url: str
154+
line: int
155+
column: int
154156
lineNumber: int
155157
columnNumber: int
156158

157159

160+
class WebErrorLocation(TypedDict):
161+
url: str
162+
line: int
163+
column: int
164+
165+
158166
class FilePayload(TypedDict):
159167
name: str
160168
mimeType: str
161169
buffer: bytes
162170

163171

172+
class DropPayload(TypedDict, total=False):
173+
files: Optional[
174+
Union[str, Path, FilePayload, Sequence[Union[str, Path]], Sequence[FilePayload]]
175+
]
176+
data: Optional[Dict[str, str]]
177+
178+
164179
class RemoteAddr(TypedDict):
165180
ipAddress: str
166181
port: int
@@ -216,6 +231,7 @@ class FrameExpectOptions(TypedDict, total=False):
216231
useInnerText: Optional[bool]
217232
isNot: bool
218233
timeout: Optional[float]
234+
pseudo: Optional[str]
219235

220236

221237
class FrameExpectResult(TypedDict):
@@ -330,3 +346,5 @@ class DebuggerPausedDetails(TypedDict):
330346

331347
class ScreencastFrame(TypedDict):
332348
data: bytes
349+
viewportWidth: int
350+
viewportHeight: int

‎playwright/_impl/_assertions.py‎

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515
import collections.abc
16-
from typing import Any, List, Optional, Pattern, Sequence, Union
16+
from typing import Any, List, Literal, Optional, Pattern, Sequence, Union
1717
from urllib.parse import urljoin
1818

1919
from playwright._impl._api_structures import (
@@ -26,6 +26,7 @@
2626
from playwright._impl._errors import Error
2727
from playwright._impl._fetch import APIResponse
2828
from playwright._impl._helper import is_textual_mime_type
29+
from playwright._impl._js_handle import parse_value
2930
from playwright._impl._locator import Locator
3031
from playwright._impl._page import Page
3132
from playwright._impl._str_utils import escape_regex_flags
@@ -71,7 +72,14 @@ async def _expect_impl(
7172
del expect_options["useInnerText"]
7273
result = await self._call_expect(expression, expect_options, title)
7374
if result["matches"] == self._is_not:
74-
actual = result.get("received")
75+
received = result.get("received") or {}
76+
if isinstance(received, dict):
77+
if "value" in received and received["value"] is not None:
78+
actual = parse_value(received["value"])
79+
else:
80+
actual = received.get("ariaSnapshot")
81+
else:
82+
actual = received
7583
if self._custom_message:
7684
out_message = self._custom_message
7785
if expected is not None:
@@ -161,6 +169,24 @@ async def not_to_have_url(
161169
__tracebackhide__ = True
162170
await self._not.to_have_url(urlOrRegExp, timeout, ignoreCase)
163171

172+
async def to_match_aria_snapshot(
173+
self, expected: str, timeout: float = None
174+
) -> None:
175+
__tracebackhide__ = True
176+
await self._expect_impl(
177+
"to.match.aria",
178+
FrameExpectOptions(expectedValue=expected, timeout=timeout),
179+
expected,
180+
"Page expected to match Aria snapshot",
181+
'Expect "to_match_aria_snapshot"',
182+
)
183+
184+
async def not_to_match_aria_snapshot(
185+
self, expected: str, timeout: float = None
186+
) -> None:
187+
__tracebackhide__ = True
188+
await self._not.to_match_aria_snapshot(expected, timeout)
189+
164190

165191
class LocatorAssertions(AssertionsBase):
166192
def __init__(
@@ -400,13 +426,17 @@ async def to_have_css(
400426
name: str,
401427
value: Union[str, Pattern[str]],
402428
timeout: float = None,
429+
pseudo: Literal["after", "before"] = None,
403430
) -> None:
404431
__tracebackhide__ = True
405432
expected_text = to_expected_text_values([value])
406433
await self._expect_impl(
407434
"to.have.css",
408435
FrameExpectOptions(
409-
expressionArg=name, expectedText=expected_text, timeout=timeout
436+
expressionArg=name,
437+
expectedText=expected_text,
438+
timeout=timeout,
439+
pseudo=pseudo,
410440
),
411441
value,
412442
"Locator expected to have CSS",

0 commit comments

Comments
 (0)