Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Playwright is a Python library to automate [Chromium](https://www.chromium.org/H

| | Linux | macOS | Windows |
| :--- | :---: | :---: | :---: |
| Chromium <!-- GEN:chromium-version -->134.0.6998.35<!-- GEN:stop --> | ✅ | ✅ | ✅ |
| Chromium <!-- GEN:chromium-version -->136.0.7103.25<!-- GEN:stop --> | ✅ | ✅ | ✅ |
| WebKit <!-- GEN:webkit-version -->18.4<!-- GEN:stop --> | ✅ | ✅ | ✅ |
| Firefox <!-- GEN:firefox-version -->135.0<!-- GEN:stop --> | ✅ | ✅ | ✅ |
| Firefox <!-- GEN:firefox-version -->137.0<!-- GEN:stop --> | ✅ | ✅ | ✅ |

## Documentation

Expand Down
33 changes: 33 additions & 0 deletions playwright/_impl/_assertions.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,39 @@ async def not_to_have_class(
__tracebackhide__ = True
await self._not.to_have_class(expected, timeout)

async def to_contain_class(
self,
expected: Union[
Sequence[str],
str,
],
timeout: float = None,
) -> None:
__tracebackhide__ = True
if isinstance(expected, collections.abc.Sequence) and not isinstance(
expected, str
):
expected_text = to_expected_text_values(expected)
else:
expected_text = to_expected_text_values([expected])
await self._expect_impl(
"to.contain.class",
FrameExpectOptions(expectedText=expected_text, timeout=timeout),
expected,
"Locator expected to contain class",
)

async def not_to_contain_class(
self,
expected: Union[
Sequence[str],
str,
],
timeout: float = None,
) -> None:
__tracebackhide__ = True
await self._not.to_contain_class(expected, timeout)

async def to_have_count(
self,
count: int,
Expand Down
1 change: 1 addition & 0 deletions playwright/_impl/_fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ async def new_context(
storageState: Union[StorageState, str, Path] = None,
clientCertificates: List[ClientCertificate] = None,
failOnStatusCode: bool = None,
maxRedirects: int = None,
) -> "APIRequestContext":
params = locals_to_params(locals())
if "storageState" in params:
Expand Down
2 changes: 1 addition & 1 deletion playwright/_impl/_locator.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ async def screenshot(
),
)

async def aria_snapshot(self, timeout: float = None) -> str:
async def aria_snapshot(self, timeout: float = None, ref: bool = None) -> str:
return await self._frame._channel.send(
"ariaSnapshot",
{
Expand Down
147 changes: 126 additions & 21 deletions playwright/async_api/_generated.py
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,10 @@ async def handle(route, request):
`route.continue_()` will immediately send the request to the network, other matching handlers won't be
invoked. Use `route.fallback()` If you want next matching handler in the chain to be invoked.

**NOTE** The `Cookie` header cannot be overridden using this method. If a value is provided, it will be ignored,
and the cookie will be loaded from the browser's cookie store. To set custom cookies, use
`browser_context.add_cookies()`.

Parameters
----------
url : Union[str, None]
Expand Down Expand Up @@ -9486,8 +9490,8 @@ async def handle_route(route: Route):
Parameters
----------
url : Union[Callable[[str], bool], Pattern[str], str]
A glob pattern, regex pattern or predicate receiving [URL] to match while routing. When a `baseURL` via the context
options was provided and the passed URL is a path, it gets merged via the
A glob pattern, regex pattern, or predicate that receives a [URL] to match during routing. If `baseURL` is set in
the context options and the provided URL is a string that does not start with `*`, it is resolved using the
[`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor.
handler : Union[Callable[[Route, Request], Any], Callable[[Route], Any]]
handler function to route the request.
Expand Down Expand Up @@ -13216,8 +13220,8 @@ async def handle_route(route: Route):
Parameters
----------
url : Union[Callable[[str], bool], Pattern[str], str]
A glob pattern, regex pattern or predicate receiving [URL] to match while routing. When a `baseURL` via the context
options was provided and the passed URL is a path, it gets merged via the
A glob pattern, regex pattern, or predicate that receives a [URL] to match during routing. If `baseURL` is set in
the context options and the provided URL is a string that does not start with `*`, it is resolved using the
[`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor.
handler : Union[Callable[[Route, Request], Any], Callable[[Route], Any]]
handler function to route the request.
Expand Down Expand Up @@ -13464,9 +13468,6 @@ async def storage_state(
state snapshot. If your application uses IndexedDB to store authentication tokens, like Firebase Authentication,
enable this.

**NOTE** IndexedDBs with typed arrays are currently not supported.


Returns
-------
{cookies: List[{name: str, value: str, domain: str, path: str, expires: float, httpOnly: bool, secure: bool, sameSite: Union["Lax", "None", "Strict"]}], origins: List[{origin: str, localStorage: List[{name: str, value: str}]}]}
Expand Down Expand Up @@ -14418,7 +14419,7 @@ async def launch(
headless : Union[bool, None]
Whether to run browser in headless mode. More details for
[Chromium](https://developers.google.com/web/updates/2017/04/headless-chrome) and
[Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode). Defaults to `true` unless the
[Firefox](https://hacks.mozilla.org/2017/12/using-headless-mode-in-firefox/). Defaults to `true` unless the
`devtools` option is `true`.
devtools : Union[bool, None]
**Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the
Expand Down Expand Up @@ -14543,11 +14544,15 @@ async def launch_persistent_context(
Parameters
----------
user_data_dir : Union[pathlib.Path, str]
Path to a User Data Directory, which stores browser session data like cookies and local storage. More details for
Path to a User Data Directory, which stores browser session data like cookies and local storage. Pass an empty
string to create a temporary directory.

More details for
[Chromium](https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md#introduction) and
[Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options#User_Profile). Note that Chromium's
user data directory is the **parent** directory of the "Profile Path" seen at `chrome://version`. Pass an empty
string to use a temporary directory instead.
[Firefox](https://wiki.mozilla.org/Firefox/CommandLineOptions#User_profile). Chromium's user data directory is the
**parent** directory of the "Profile Path" seen at `chrome://version`.

Note that browsers do not allow launching multiple instances with the same User Data Directory.
channel : Union[str, None]
Browser distribution channel.

Expand Down Expand Up @@ -14581,7 +14586,7 @@ async def launch_persistent_context(
headless : Union[bool, None]
Whether to run browser in headless mode. More details for
[Chromium](https://developers.google.com/web/updates/2017/04/headless-chrome) and
[Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode). Defaults to `true` unless the
[Firefox](https://hacks.mozilla.org/2017/12/using-headless-mode-in-firefox/). Defaults to `true` unless the
`devtools` option is `true`.
devtools : Union[bool, None]
**Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the
Expand Down Expand Up @@ -15630,8 +15635,8 @@ async def evaluate(
arg : Union[Any, None]
Optional argument to pass to `expression`.
timeout : Union[float, None]
Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can
be changed by using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods.
Maximum time in milliseconds to wait for the locator before evaluating. Note that after locator is resolved,
evaluation itself is not limited by the timeout. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.

Returns
-------
Expand Down Expand Up @@ -15720,8 +15725,8 @@ async def evaluate_handle(
arg : Union[Any, None]
Optional argument to pass to `expression`.
timeout : Union[float, None]
Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can
be changed by using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods.
Maximum time in milliseconds to wait for the locator before evaluating. Note that after locator is resolved,
evaluation itself is not limited by the timeout. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.

Returns
-------
Expand Down Expand Up @@ -17215,7 +17220,12 @@ async def screenshot(
)
)

async def aria_snapshot(self, *, timeout: typing.Optional[float] = None) -> str:
async def aria_snapshot(
self,
*,
timeout: typing.Optional[float] = None,
ref: typing.Optional[bool] = None,
) -> str:
"""Locator.aria_snapshot

Captures the aria snapshot of the given element. Read more about [aria snapshots](https://playwright.dev/python/docs/aria-snapshots) and
Expand Down Expand Up @@ -17260,14 +17270,17 @@ async def aria_snapshot(self, *, timeout: typing.Optional[float] = None) -> str:
timeout : Union[float, None]
Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can
be changed by using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods.
ref : Union[bool, None]
Generate symbolic reference for each element. One can use `aria-ref=<ref>` locator immediately after capturing the
snapshot to perform actions on the element.

Returns
-------
str
"""

return mapping.from_maybe_impl(
await self._impl_obj.aria_snapshot(timeout=timeout)
await self._impl_obj.aria_snapshot(timeout=timeout, ref=ref)
)

async def scroll_into_view_if_needed(
Expand Down Expand Up @@ -18700,6 +18713,7 @@ async def new_context(
] = None,
client_certificates: typing.Optional[typing.List[ClientCertificate]] = None,
fail_on_status_code: typing.Optional[bool] = None,
max_redirects: typing.Optional[int] = None,
) -> "APIRequestContext":
"""APIRequest.new_context

Expand Down Expand Up @@ -18751,6 +18765,10 @@ async def new_context(
fail_on_status_code : Union[bool, None]
Whether to throw on response codes other than 2xx and 3xx. By default response object is returned for all status
codes.
max_redirects : Union[int, None]
Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is
exceeded. Defaults to `20`. Pass `0` to not follow redirects. This can be overwritten for each request
individually.

Returns
-------
Expand All @@ -18769,6 +18787,7 @@ async def new_context(
storageState=storage_state,
clientCertificates=client_certificates,
failOnStatusCode=fail_on_status_code,
maxRedirects=max_redirects,
)
)

Expand Down Expand Up @@ -19133,7 +19152,7 @@ async def to_have_class(
"""LocatorAssertions.to_have_class

Ensures the `Locator` points to an element with given CSS classes. When a string is provided, it must fully match
the element's `class` attribute. To match individual classes or perform partial matches, use a regular expression:
the element's `class` attribute. To match individual classes use `locator_assertions.to_contain_class()`.

**Usage**

Expand All @@ -19145,8 +19164,8 @@ async def to_have_class(
from playwright.async_api import expect

locator = page.locator(\"#component\")
await expect(locator).to_have_class(re.compile(r\"(^|\\\\s)selected(\\\\s|$)\"))
await expect(locator).to_have_class(\"middle selected row\")
await expect(locator).to_have_class(re.compile(r\"(^|\\\\s)selected(\\\\s|$)\"))
```

When an array is passed, the method asserts that the list of elements located matches the corresponding list of
Expand Down Expand Up @@ -19206,6 +19225,92 @@ async def not_to_have_class(
)
)

async def to_contain_class(
self,
expected: typing.Union[typing.Sequence[str], str],
*,
timeout: typing.Optional[float] = None,
) -> None:
"""LocatorAssertions.to_contain_class

Ensures the `Locator` points to an element with given CSS classes. All classes from the asserted value, separated
by spaces, must be present in the
[Element.classList](https://developer.mozilla.org/en-US/docs/Web/API/Element/classList) in any order.

**Usage**

```html
<div class='middle selected row' id='component'></div>
```

```py
from playwright.async_api import expect

locator = page.locator(\"#component\")
await expect(locator).to_contain_class(\"middle selected row\")
await expect(locator).to_contain_class(\"selected\")
await expect(locator).to_contain_class(\"row middle\")
```

When an array is passed, the method asserts that the list of elements located matches the corresponding list of
expected class lists. Each element's class attribute is matched against the corresponding class in the array:

```html
<div class='list'></div>
<div class='component inactive'></div>
<div class='component active'></div>
<div class='component inactive'></div>
</div>
```

```py
from playwright.async_api import expect

locator = page.locator(\"list > .component\")
await expect(locator).to_contain_class([\"inactive\", \"active\", \"inactive\"])
```

Parameters
----------
expected : Union[Sequence[str], str]
A string containing expected class names, separated by spaces, or a list of such strings to assert multiple
elements.
timeout : Union[float, None]
Time to retry the assertion for in milliseconds. Defaults to `5000`.
"""
__tracebackhide__ = True

return mapping.from_maybe_impl(
await self._impl_obj.to_contain_class(
expected=mapping.to_impl(expected), timeout=timeout
)
)

async def not_to_contain_class(
self,
expected: typing.Union[typing.Sequence[str], str],
*,
timeout: typing.Optional[float] = None,
) -> None:
"""LocatorAssertions.not_to_contain_class

The opposite of `locator_assertions.to_contain_class()`.

Parameters
----------
expected : Union[Sequence[str], str]
Expected class or RegExp or a list of those.
timeout : Union[float, None]
Time to retry the assertion for in milliseconds. Defaults to `5000`.
"""
__tracebackhide__ = True

return mapping.from_maybe_impl(
await self._impl_obj.not_to_contain_class(
expected=mapping.to_impl(expected), timeout=timeout
)
)

async def to_have_count(
self, count: int, *, timeout: typing.Optional[float] = None
) -> None:
Expand Down
Loading
Loading