docs: add python snippets for api classes (#5011)

This commit is contained in:
Pavel Feldman 2021-01-14 07:48:56 -08:00 committed by GitHub
parent 5408e26e02
commit 8354a91d0e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 1699 additions and 307 deletions

View file

@ -47,9 +47,8 @@ Captures the current state of the accessibility tree. The returned object repres
page.
:::note
The Chromium accessibility tree contains nodes that go unused on most platforms and by most screen readers.
Playwright will discard them as well for an easier to process tree, unless [`option: interestingOnly`] is set to
`false`.
The Chromium accessibility tree contains nodes that go unused on most platforms and by most screen readers. Playwright
will discard them as well for an easier to process tree, unless [`option: interestingOnly`] is set to `false`.
:::
An example of dumping the entire accessibility tree:
@ -59,6 +58,16 @@ const snapshot = await page.accessibility.snapshot();
console.log(snapshot);
```
```python async
snapshot = await page.accessibility.snapshot()
print(snapshot)
```
```python sync
snapshot = page.accessibility.snapshot()
print(snapshot)
```
An example of logging the focused node's name:
```js
@ -77,6 +86,36 @@ function findFocusedNode(node) {
}
```
```python async
def find_focused_node(node):
if (node.get("focused"))
return node
for child in (node.get("children") or []):
found_node = find_focused_node(child)
return found_node
return null
snapshot = await page.accessibility.snapshot()
node = find_focused_node(snapshot)
if node:
print(node["name"])
```
```python sync
def find_focused_node(node):
if (node.get("focused"))
return node
for child in (node.get("children") or []):
found_node = find_focused_node(child)
return found_node
return null
snapshot = page.accessibility.snapshot()
node = find_focused_node(snapshot)
if node:
print(node["name"])
```
### option: Accessibility.snapshot.interestingOnly
- `interestingOnly` <[boolean]>

View file

@ -14,6 +14,37 @@ const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'.
})();
```
```python async
import asyncio
from playwright.async_api import async_playwright
async def run(playwright):
firefox = playwright.firefox
browser = await firefox.launch()
page = await browser.new_page()
await page.goto("https://example.com")
await browser.close()
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
```
```python sync
from playwright.sync_api import sync_playwright
def run(playwright):
firefox = playwright.firefox
browser = firefox.launch()
page = browser.new_page()
page.goto("https://example.com")
browser.close()
with sync_playwright() as playwright:
run(playwright)
```
## event: Browser.disconnected
Emitted when Browser gets disconnected from the browser application. This might happen because of one of the following:
@ -25,8 +56,8 @@ Emitted when Browser gets disconnected from the browser application. This might
In case this browser is obtained using [`method: BrowserType.launch`], closes the browser and all of its pages (if any
were opened).
In case this browser is connected to, clears all created contexts belonging to this
browser and disconnects from the browser server.
In case this browser is connected to, clears all created contexts belonging to this browser and disconnects from the
browser server.
The [Browser] object itself is considered to be disposed and cannot be used anymore.
@ -43,6 +74,20 @@ const context = await browser.newContext();
console.log(browser.contexts().length); // prints `1`
```
```python async
browser = await pw.webkit.launch()
print(len(browser.contexts())) # prints `0`
context = await browser.new_context()
print(len(browser.contexts())) # prints `1`
```
```python sync
browser = pw.webkit.launch()
print(len(browser.contexts())) # prints `0`
context = browser.new_context()
print(len(browser.contexts())) # prints `1`
```
## method: Browser.isConnected
- returns: <[boolean]>
@ -64,6 +109,24 @@ Creates a new browser context. It won't share cookies/cache with other browser c
})();
```
```python async
browser = await playwright.firefox.launch() # or "chromium" or "webkit".
# create a new incognito browser context.
context = await browser.new_context()
# create a new page in a pristine context.
page = await context.new_page()
await page.goto("https://example.com")
```
```python sync
browser = playwright.firefox.launch() # or "chromium" or "webkit".
# create a new incognito browser context.
context = browser.new_context()
# create a new page in a pristine context.
page = context.new_page()
page.goto("https://example.com")
```
### option: Browser.newContext.-inline- = %%-shared-context-params-list-%%
### option: Browser.newContext.proxy = %%-context-option-proxy-%%
@ -76,8 +139,8 @@ Creates a new browser context. It won't share cookies/cache with other browser c
Creates a new page in a new browser context. Closing this page will close the context as well.
This is a convenience API that should only be used for the single-page scenarios and short snippets. Production code and
testing frameworks should explicitly create [`method: Browser.newContext`] followed by the [`method:
BrowserContext.newPage`] to control their exact life times.
testing frameworks should explicitly create [`method: Browser.newContext`] followed by the
[`method: BrowserContext.newPage`] to control their exact life times.
### option: Browser.newPage.-inline- = %%-shared-context-params-list-%%

View file

@ -19,6 +19,26 @@ await page.goto('https://example.com');
await context.close();
```
```python async
# create a new incognito browser context
context = await browser.new_context()
# create a new page inside context.
page = await context.new_page()
await page.goto("https://example.com")
# dispose context once it"s no longer needed.
await context.close()
```
```python sync
# create a new incognito browser context
context = browser.new_context()
# create a new page inside context.
page = context.new_page()
page.goto("https://example.com")
# dispose context once it"s no longer needed.
context.close()
```
## event: BrowserContext.close
Emitted when Browser context gets closed. This might happen because of one of the following:
@ -44,9 +64,23 @@ const [page] = await Promise.all([
console.log(await page.evaluate('location.href'));
```
```python async
async with context.expect_page() as page_info:
await page.click("a[target=_blank]"),
page = await page_info.value
print(await page.evaluate("location.href"))
```
```python sync
with context.expect_page() as page_info:
page.click("a[target=_blank]"),
page = page_info.value
print(page.evaluate("location.href"))
```
:::note
Use [`method: Page.waitForLoadState`] to wait until the page gets to a particular state (you should not
need it in most cases).
Use [`method: Page.waitForLoadState`] to wait until the page gets to a particular state (you should not need it in most
cases).
:::
## async method: BrowserContext.addCookies
@ -58,6 +92,14 @@ obtained via [`method: BrowserContext.cookies`].
await browserContext.addCookies([cookieObject1, cookieObject2]);
```
```python async
await browser_context.add_cookies([cookie_object1, cookie_object2])
```
```python sync
browser_context.add_cookies([cookie_object1, cookie_object2])
```
### param: BrowserContext.addCookies.cookies
- `cookies` <[Array]<[Object]>>
- `name` <[string]>
@ -74,7 +116,8 @@ await browserContext.addCookies([cookieObject1, cookieObject2]);
Adds a script which would be evaluated in one of the following scenarios:
* Whenever a page is created in the browser context or is navigated.
* Whenever a child frame is attached or navigated in any page in the browser context. In this case, the script is evaluated in the context of the newly attached frame.
* Whenever a child frame is attached or navigated in any page in the browser context. In this case, the script is
evaluated in the context of the newly attached frame.
The script is evaluated after the document was created but before any of its scripts were run. This is useful to amend
the JavaScript environment, e.g. to seed `Math.random`.
@ -93,6 +136,16 @@ await browserContext.addInitScript({
});
```
```python async
# in your playwright script, assuming the preload.js file is in same directory.
await browser_context.add_init_script(path="preload.js")
```
```python sync
# in your playwright script, assuming the preload.js file is in same directory.
browser_context.add_init_script(path="preload.js")
```
:::note
The order of evaluation of multiple scripts installed via [`method: BrowserContext.addInitScript`] and
[`method: Page.addInitScript`] is not defined.
@ -101,7 +154,8 @@ The order of evaluation of multiple scripts installed via [`method: BrowserConte
### param: BrowserContext.addInitScript.script
* langs: js
- `script` <[function]|[string]|[Object]>
- `path` <[path]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `path` <[path]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the
current working directory. Optional.
- `content` <[string]> Raw script content. Optional.
Script to be evaluated in all pages in the browser context.
@ -132,6 +186,20 @@ await context.grantPermissions(['clipboard-read']);
context.clearPermissions();
```
```python async
context = await browser.new_context()
await context.grant_permissions(["clipboard-read"])
# do stuff ..
context.clear_permissions()
```
```python sync
context = browser.new_context()
context.grant_permissions(["clipboard-read"])
# do stuff ..
context.clear_permissions()
```
## async method: BrowserContext.close
Closes the browser context. All the pages that belong to the browser context will be closed.
@ -162,11 +230,11 @@ Optional list of URLs.
## async method: BrowserContext.exposeBinding
The method adds a function called [`param: name`] on the `window` object of every frame in every page in the context.
When called, the function executes [`param: callback`] and returns a [Promise] which resolves to the return
value of [`param: callback`]. If the [`param: callback`] returns a [Promise], it will be awaited.
When called, the function executes [`param: callback`] and returns a [Promise] which resolves to the return value of
[`param: callback`]. If the [`param: callback`] returns a [Promise], it will be awaited.
The first argument of the [`param: callback`] function contains information about the caller: `{
browserContext: BrowserContext, page: Page, frame: Frame }`.
The first argument of the [`param: callback`] function contains information about the caller: `{ browserContext:
BrowserContext, page: Page, frame: Frame }`.
See [`method: Page.exposeBinding`] for page-only version.
@ -193,6 +261,57 @@ const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'.
})();
```
```python async
import asyncio
from playwright.async_api import async_playwright
async def run(playwright):
webkit = playwright.webkit
browser = await webkit.launch(headless=false)
context = await browser.new_context()
await context.expose_binding("pageURL", lambda source: source["page"].url)
page = await context.new_page()
await page.set_content("""
<script>
async function onClick() {
document.querySelector('div').textContent = await window.pageURL();
}
</script>
<button onclick="onClick()">Click me</button>
<div></div>
""")
await page.click("button")
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
```
```python sync
from playwright.sync_api import sync_playwright
def run(playwright):
webkit = playwright.webkit
browser = webkit.launch(headless=false)
context = browser.new_context()
context.expose_binding("pageURL", lambda source: source["page"].url)
page = context.new_page()
page.set_content("""
<script>
async function onClick() {
document.querySelector('div').textContent = await window.pageURL();
}
</script>
<button onclick="onClick()">Click me</button>
<div></div>
""")
page.click("button")
with sync_playwright() as playwright:
run(playwright)
```
An example of passing an element handle:
```js
@ -208,6 +327,34 @@ await page.setContent(`
`);
```
```python async
async def print(source, element):
print(await element.text_content())
await context.expose_binding("clicked", print, handle=true)
await page.set_content("""
<script>
document.addEventListener('click', event => window.clicked(event.target));
</script>
<div>Click me</div>
<div>Or click me</div>
""")
```
```python sync
def print(source, element):
print(element.text_content())
context.expose_binding("clicked", print, handle=true)
page.set_content("""
<script>
document.addEventListener('click', event => window.clicked(event.target));
</script>
<div>Click me</div>
<div>Or click me</div>
""")
```
### param: BrowserContext.exposeBinding.name
- `name` <[string]>
@ -227,8 +374,8 @@ supported. When passing by value, multiple arguments are supported.
## async method: BrowserContext.exposeFunction
The method adds a function called [`param: name`] on the `window` object of every frame in every page in the context.
When called, the function executes [`param: callback`] and returns a [Promise] which resolves to the return
value of [`param: callback`].
When called, the function executes [`param: callback`] and returns a [Promise] which resolves to the return value of
[`param: callback`].
If the [`param: callback`] returns a [Promise], it will be awaited.
@ -258,6 +405,72 @@ const crypto = require('crypto');
})();
```
```python async
import asyncio
import hashlib
from playwright.async_api import async_playwright
async def sha1(text):
m = hashlib.sha1()
m.update(bytes(text, "utf8"))
return m.hexdigest()
async def run(playwright):
webkit = playwright.webkit
browser = await webkit.launch(headless=False)
context = await browser.new_context()
await context.expose_function("sha1", sha1)
page = await context.new_page()
await page.set_content("""
<script>
async function onClick() {
document.querySelector('div').textContent = await window.sha1('PLAYWRIGHT');
}
</script>
<button onclick="onClick()">Click me</button>
<div></div>
""")
await page.click("button")
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
```
```python sync
import hashlib
from playwright.sync_api import sync_playwright
def sha1(text):
m = hashlib.sha1()
m.update(bytes(text, "utf8"))
return m.hexdigest()
def run(playwright):
webkit = playwright.webkit
browser = webkit.launch(headless=False)
context = browser.new_context()
context.expose_function("sha1", sha1)
page = context.new_page()
page.expose_function("sha1", sha1)
page.set_content("""
<script>
async function onClick() {
document.querySelector('div').textContent = await window.sha1('PLAYWRIGHT');
}
</script>
<button onclick="onClick()">Click me</button>
<div></div>
""")
page.click("button")
with sync_playwright() as playwright:
run(playwright)
```
### param: BrowserContext.exposeFunction.name
- `name` <[string]>
@ -277,22 +490,22 @@ specified.
- `permissions` <[Array]<[string]>>
A permission or an array of permissions to grant. Permissions can be one of the following values:
* `'geolocation'`
* `'midi'`
* `'midi-sysex'` (system-exclusive midi)
* `'notifications'`
* `'push'`
* `'camera'`
* `'microphone'`
* `'background-sync'`
* `'ambient-light-sensor'`
* `'accelerometer'`
* `'gyroscope'`
* `'magnetometer'`
* `'accessibility-events'`
* `'clipboard-read'`
* `'clipboard-write'`
* `'payment-handler'`
* `'geolocation'`
* `'midi'`
* `'midi-sysex'` (system-exclusive midi)
* `'notifications'`
* `'push'`
* `'camera'`
* `'microphone'`
* `'background-sync'`
* `'ambient-light-sensor'`
* `'accelerometer'`
* `'gyroscope'`
* `'magnetometer'`
* `'accessibility-events'`
* `'clipboard-read'`
* `'clipboard-write'`
* `'payment-handler'`
### option: BrowserContext.grantPermissions.origin
- `origin` <[string]>
@ -325,6 +538,22 @@ await page.goto('https://example.com');
await browser.close();
```
```python async
context = await browser.new_context()
page = await context.new_page()
await context.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())
await page.goto("https://example.com")
await browser.close()
```
```python sync
context = browser.new_context()
page = context.new_page()
context.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())
page.goto("https://example.com")
browser.close()
```
or the same snippet using a regex pattern instead:
```js
@ -335,6 +564,23 @@ await page.goto('https://example.com');
await browser.close();
```
```python async
context = await browser.new_context()
page = await context.new_page()
await context.route(r"(\.png$)|(\.jpg$)", lambda page = await context.new_page()
await page.goto("https://example.com")
await browser.close()
```
```python sync
context = browser.new_context()
page = context.new_page()
context.route(r"(\.png$)|(\.jpg$)", lambda page = await context.new_page()
page = context.new_page()
page.goto("https://example.com")
browser.close()
```
Page routes (set up with [`method: Page.route`]) take precedence over browser context routes when request matches both
handlers.
@ -377,8 +623,8 @@ Maximum navigation time in milliseconds
This setting will change the default maximum time for all the methods accepting [`param: timeout`] option.
:::note
[`method: Page.setDefaultNavigationTimeout`], [`method: Page.setDefaultTimeout`] and [`method:
BrowserContext.setDefaultNavigationTimeout`] take priority over [`method: BrowserContext.setDefaultTimeout`].
[`method: Page.setDefaultNavigationTimeout`], [`method: Page.setDefaultTimeout`] and
[`method: BrowserContext.setDefaultNavigationTimeout`] take priority over [`method: BrowserContext.setDefaultTimeout`].
:::
### param: BrowserContext.setDefaultTimeout.timeout
@ -409,9 +655,17 @@ Sets the context's geolocation. Passing `null` or `undefined` emulates position
await browserContext.setGeolocation({latitude: 59.95, longitude: 30.31667});
```
```python async
await browser_context.set_geolocation({"latitude": 59.95, "longitude": 30.31667})
```
```python sync
browser_context.set_geolocation({"latitude": 59.95, "longitude": 30.31667})
```
:::note
Consider using [`method: BrowserContext.grantPermissions`] to grant permissions for the browser context
pages to read its geolocation.
Consider using [`method: BrowserContext.grantPermissions`] to grant permissions for the browser context pages to read
its geolocation.
:::
### param: BrowserContext.setGeolocation.geolocation
@ -423,8 +677,7 @@ pages to read its geolocation.
## async method: BrowserContext.setHTTPCredentials
* langs: js
**DEPRECATED** Browsers may cache credentials after successful authentication.
Create a new browser context instead.
**DEPRECATED** Browsers may cache credentials after successful authentication. Create a new browser context instead.
### param: BrowserContext.setHTTPCredentials.httpCredentials
- `httpCredentials` <[null]|[Object]>
@ -472,8 +725,8 @@ routes for the [`param: url`].
### param: BrowserContext.unroute.url
- `url` <[string]|[RegExp]|[function]\([URL]\):[boolean]>
A glob pattern, regex pattern or predicate receiving [URL] used to register a routing with [`method:
BrowserContext.route`].
A glob pattern, regex pattern or predicate receiving [URL] used to register a routing with
[`method: BrowserContext.route`].
### param: BrowserContext.unroute.handler
- `handler` <[function]\([Route], [Request]\)>
@ -491,6 +744,16 @@ const context = await browser.newContext();
await context.grantPermissions(['geolocation']);
```
```python async
context = await browser.new_context()
await context.grant_permissions(["geolocation"])
```
```python sync
context = browser.new_context()
context.grant_permissions(["geolocation"])
```
### param: BrowserContext.waitForEvent.event
- `event` <[string]>
@ -500,6 +763,7 @@ Event name, same one would pass into `browserContext.on(event)`.
* langs: js
- `optionsOrPredicate` <[function]|[Object]>
- `predicate` <[function]> receives the event data and resolves to truthy value when the waiting should resolve.
- `timeout` <[float]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the [`method: BrowserContext.setDefaultTimeout`].
- `timeout` <[float]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to
disable timeout. The default value can be changed by using the [`method: BrowserContext.setDefaultTimeout`].
Either a predicate that receives an event or an options object. Optional.
Either a predicate that receives an event or an options object. Optional.

View file

@ -15,6 +15,39 @@ const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
})();
```
```python async
import asyncio
from playwright.async_api import async_playwright
async def run(playwright):
chromium = playwright.chromium
browser = await chromium.launch()
page = await browser.new_page()
await page.goto("https://example.com")
# other actions...
await browser.close()
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
```
```python sync
from playwright.sync_api import sync_playwright
def run(playwright):
chromium = playwright.chromium
browser = chromium.launch()
page = browser.new_page()
page.goto("https://example.com")
# other actions...
browser.close()
with sync_playwright() as playwright:
run(playwright)
```
## async method: BrowserType.connect
* langs: js
- returns: <[Browser]>
@ -24,9 +57,11 @@ This methods attaches Playwright to an existing browser instance.
### param: BrowserType.connect.params
- `params` <[Object]>
- `wsEndpoint` <[string]> A browser websocket endpoint to connect to.
- `slowMo` <[float]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. Defaults to 0.
- `slowMo` <[float]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you
can see what is going on. Defaults to 0.
- `logger` <[Logger]> Logger sink for Playwright logging. Optional.
- `timeout` <[float]> Maximum time in milliseconds to wait for the connection to be established. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
- `timeout` <[float]> Maximum time in milliseconds to wait for the connection to be established. Defaults to
`30000` (30 seconds). Pass `0` to disable timeout.
## method: BrowserType.executablePath
- returns: <[string]>
@ -46,20 +81,32 @@ const browser = await chromium.launch({ // Or 'firefox' or 'webkit'.
});
```
```python async
browser = await playwright.chromium.launch( # or "firefox" or "webkit".
ignore_default_args=["--mute-audio"]
)
```
```python sync
browser = playwright.chromium.launch( # or "firefox" or "webkit".
ignore_default_args=["--mute-audio"]
)
```
> **Chromium-only** Playwright can also be used to control the Chrome browser, but it works best with the version of
Chromium it is bundled with. There is no guarantee it will work with any other version. Use [`option: executablePath`]
option with extreme caution.
>
> If Google Chrome (rather than Chromium) is preferred, a [Chrome
Canary](https://www.google.com/chrome/browser/canary.html) or [Dev
Channel](https://www.chromium.org/getting-involved/dev-channel) build is suggested.
> If Google Chrome (rather than Chromium) is preferred, a
[Chrome Canary](https://www.google.com/chrome/browser/canary.html) or
[Dev Channel](https://www.chromium.org/getting-involved/dev-channel) build is suggested.
>
> In [`method: BrowserType.launch`] above, any mention of Chromium also applies to Chrome.
>
> See [`this article`](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) for
a description of the differences between Chromium and Chrome. [`This
article`](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md) describes
some differences for Linux users.
a description of the differences between Chromium and Chrome.
[`This article`](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md)
describes some differences for Linux users.
### option: BrowserType.launch.headless
- `headless` <[boolean]>
@ -90,8 +137,11 @@ array is given, then filters out the given default arguments. Dangerous option;
### option: BrowserType.launch.proxy
- `proxy` <[Object]>
- `server` <[string]> Proxy to be used for all requests. HTTP and SOCKS proxies are supported, for example `http://myproxy.com:3128` or `socks5://myproxy.com:3128`. Short form `myproxy.com:3128` is considered an HTTP proxy.
- `bypass` <[string]> Optional coma-separated domains to bypass proxy, for example `".com, chromium.org, .domain.com"`.
- `server` <[string]> Proxy to be used for all requests. HTTP and SOCKS proxies are supported, for example
`http://myproxy.com:3128` or `socks5://myproxy.com:3128`. Short form `myproxy.com:3128` is considered an HTTP
proxy.
- `bypass` <[string]> Optional coma-separated domains to bypass proxy, for example `".com, chromium.org,
.domain.com"`.
- `username` <[string]> Optional username to use if HTTP proxy requires authentication.
- `password` <[string]> Optional password to use if HTTP proxy requires authentication.
@ -149,8 +199,8 @@ Specify environment variables that will be visible to the browser. Defaults to `
### option: BrowserType.launch.devtools
- `devtools` <[boolean]>
**Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the [`option:
headless`] option will be set `false`.
**Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the
[`option: headless`] option will be set `false`.
### option: BrowserType.launch.slowMo
- `slowMo` <[float]>
@ -201,8 +251,11 @@ arguments. Dangerous option; use with care. Defaults to `false`.
### option: BrowserType.launchPersistentContext.proxy
- `proxy` <[Object]>
- `server` <[string]> Proxy to be used for all requests. HTTP and SOCKS proxies are supported, for example `http://myproxy.com:3128` or `socks5://myproxy.com:3128`. Short form `myproxy.com:3128` is considered an HTTP proxy.
- `bypass` <[string]> Optional coma-separated domains to bypass proxy, for example `".com, chromium.org, .domain.com"`.
- `server` <[string]> Proxy to be used for all requests. HTTP and SOCKS proxies are supported, for example
`http://myproxy.com:3128` or `socks5://myproxy.com:3128`. Short form `myproxy.com:3128` is considered an HTTP
proxy.
- `bypass` <[string]> Optional coma-separated domains to bypass proxy, for example `".com, chromium.org,
.domain.com"`.
- `username` <[string]> Optional username to use if HTTP proxy requires authentication.
- `password` <[string]> Optional password to use if HTTP proxy requires authentication.
@ -248,8 +301,8 @@ Specify environment variables that will be visible to the browser. Defaults to `
### option: BrowserType.launchPersistentContext.devtools
- `devtools` <[boolean]>
**Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the [`option:
headless`] option will be set `false`.
**Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the
[`option: headless`] option will be set `false`.
### option: BrowserType.launchPersistentContext.slowMo
- `slowMo` <[float]>
@ -315,8 +368,11 @@ arguments. Dangerous option; use with care. Defaults to `false`.
### option: BrowserType.launchServer.proxy
- `proxy` <[Object]>
- `server` <[string]> Proxy to be used for all requests. HTTP and SOCKS proxies are supported, for example `http://myproxy.com:3128` or `socks5://myproxy.com:3128`. Short form `myproxy.com:3128` is considered an HTTP proxy.
- `bypass` <[string]> Optional coma-separated domains to bypass proxy, for example `".com, chromium.org, .domain.com"`.
- `server` <[string]> Proxy to be used for all requests. HTTP and SOCKS proxies are supported, for example
`http://myproxy.com:3128` or `socks5://myproxy.com:3128`. Short form `myproxy.com:3128` is considered an HTTP
proxy.
- `bypass` <[string]> Optional coma-separated domains to bypass proxy, for example `".com, chromium.org,
.domain.com"`.
- `username` <[string]> Optional username to use if HTTP proxy requires authentication.
- `password` <[string]> Optional password to use if HTTP proxy requires authentication.
@ -374,8 +430,8 @@ Specify environment variables that will be visible to the browser. Defaults to `
### option: BrowserType.launchServer.devtools
- `devtools` <[boolean]>
**Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the [`option:
headless`] option will be set `false`.
**Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the
[`option: headless`] option will be set `false`.
## method: BrowserType.name
- returns: <[string]>

View file

@ -6,8 +6,10 @@ The `CDPSession` instances are used to talk raw Chrome Devtools Protocol:
* protocol events can be subscribed to with `session.on` method.
Useful links:
* Documentation on DevTools Protocol can be found here: [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/).
* Getting Started with DevTools Protocol: https://github.com/aslushnikov/getting-started-with-cdp/blob/master/README.md
* Documentation on DevTools Protocol can be found here:
[DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/).
* Getting Started with DevTools Protocol:
https://github.com/aslushnikov/getting-started-with-cdp/blob/master/README.md
```js
const client = await page.context().newCDPSession(page);
@ -20,6 +22,28 @@ await client.send('Animation.setPlaybackRate', {
});
```
```python async
client = await page.context().new_cdp_session(page)
await client.send("animation.enable")
client.on("animation.animation_created", lambda: print("animation created!"))
response = await client.send("animation.get_playback_rate")
print("playback rate is " + response["playback_rate"])
await client.send("animation.set_playback_rate", {
playback_rate: response["playback_rate"] / 2
})
```
```python sync
client = page.context().new_cdp_session(page)
client.send("animation.enable")
client.on("animation.animation_created", lambda: print("animation created!"))
response = client.send("animation.get_playback_rate")
print("playback rate is " + response["playback_rate"])
client.send("animation.set_playback_rate", {
playback_rate: response["playback_rate"] / 2
})
```
## async method: CDPSession.detach
Detaches the CDPSession from the target. Once detached, the CDPSession object won't emit any events and can't be used to

View file

@ -7,6 +7,16 @@ Chromium-specific features including background pages, service worker support, e
const backgroundPage = await context.waitForEvent('backgroundpage');
```
```python async
# FIXME
background_page = await context.wait_for_event("backgroundpage")
```
```python sync
# FIXME
background_page = context.wait_for_event("backgroundpage")
```
## event: ChromiumBrowserContext.backgroundpage
- type: <[Page]>

View file

@ -1,3 +1,4 @@
# class: Dialog
[Dialog] objects are dispatched by page via the [`event: Page.dialog`] event.
@ -19,6 +20,48 @@ const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
})();
```
```python async
import asyncio
from playwright.async_api import async_playwright
async def handle_dialog(dialog):
print(dialog.message)
await dialog.dismiss()
async def run(playwright):
chromium = playwright.chromium
browser = await chromium.launch()
page = await browser.new_page()
page.on("dialog", handle_dialog)
page.evaluate("alert('1')")
await browser.close()
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
```
```python sync
# FIXME
from playwright.sync_api import sync_playwright
def handle_dialog(dialog):
print(dialog.message)
await dialog.dismiss()
def run(playwright):
chromium = playwright.chromium
browser = chromium.launch()
page = browser.new_page()
page.on("dialog", handle_dialog)
page.evaluate("alert('1')")
browser.close()
with sync_playwright() as playwright:
run(playwright)
```
## async method: Dialog.accept
Returns when the dialog has been accepted.

View file

@ -14,14 +14,28 @@ const [ download ] = await Promise.all([
]);
// wait for download to complete
const path = await download.path();
...
```
```python async
async with page.expect_download() as download_info:
await page.click("a")
download = await download_info.value
# waits for download to complete
path = await download.path()
```
```python sync
with page.expect_download() as download_info:
page.click("a")
download = download_info.value
# wait for download to complete
path = download.path()
```
:::note
Browser context **must** be created with the [`option: acceptDownloads`] set to `true` when user needs access to the
downloaded content. If [`option: acceptDownloads`] is not set, download events are
emitted, but the actual download is not performed and user has no access to the
downloaded files.
downloaded content. If [`option: acceptDownloads`] is not set, download events are emitted, but the actual download is
not performed and user has no access to the downloaded files.
:::
## async method: Download.createReadStream

View file

@ -16,8 +16,43 @@ const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
})();
```
ElementHandle prevents DOM element from garbage collection unless the handle is disposed with [`method:
JSHandle.dispose`]. ElementHandles are auto-disposed when their origin frame gets navigated.
```python async
import asyncio
from playwright.async_api import async_playwright
async def run(playwright):
chromium = playwright.chromium
browser = await chromium.launch()
page = await browser.new_page()
await page.goto("https://example.com")
href_element = await page.query_selector("a")
await href_element.click()
# ...
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
```
```python sync
from playwright.sync_api import sync_playwright
def run(playwright):
chromium = playwright.chromium
browser = chromium.launch()
page = browser.new_page()
page.goto("https://example.com")
href_element = page.query_selector("a")
href_element.click()
# ...
with sync_playwright() as playwright:
run(playwright)
```
ElementHandle prevents DOM element from garbage collection unless the handle is disposed with
[`method: JSHandle.dispose`]. ElementHandles are auto-disposed when their origin frame gets navigated.
ElementHandle instances can be used as an argument in [`method: Page.$eval`] and [`method: Page.evaluate`] methods.
@ -26,8 +61,9 @@ ElementHandle instances can be used as an argument in [`method: Page.$eval`] and
- alias-python: query_selector
- returns: <[null]|[ElementHandle]>
The method finds an element matching the specified selector in the `ElementHandle`'s subtree. See [Working with
selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector, returns `null`.
The method finds an element matching the specified selector in the `ElementHandle`'s subtree. See
[Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
returns `null`.
### param: ElementHandle.$.selector = %%-query-selector-%%
@ -36,8 +72,9 @@ selectors](./selectors.md#working-with-selectors) for more details. If no elemen
- alias-python: query_selector_all
- returns: <[Array]<[ElementHandle]>>
The method finds all elements matching the specified selector in the `ElementHandle`s subtree. See [Working with
selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector, returns empty array.
The method finds all elements matching the specified selector in the `ElementHandle`s subtree. See
[Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
returns empty array.
### param: ElementHandle.$$.selector = %%-query-selector-%%
@ -49,11 +86,11 @@ selectors](./selectors.md#working-with-selectors) for more details. If no elemen
Returns the return value of [`param: pageFunction`]
The method finds an element matching the specified selector in the `ElementHandle`s subtree and passes it as a first
argument to [`param: pageFunction`]. See [Working with selectors](./selectors.md#working-with-selectors) for more details. If no
elements match the selector, the method throws an error.
argument to [`param: pageFunction`]. See [Working with selectors](./selectors.md#working-with-selectors) for more
details. If no elements match the selector, the method throws an error.
If [`param: pageFunction`] returns a [Promise], then `frame.$eval` would wait for the promise to resolve and return
its value.
If [`param: pageFunction`] returns a [Promise], then `frame.$eval` would wait for the promise to resolve and return its
value.
Examples:
@ -63,6 +100,18 @@ expect(await tweetHandle.$eval('.like', node => node.innerText)).toBe('100');
expect(await tweetHandle.$eval('.retweets', node => node.innerText)).toBe('10');
```
```python async
tweet_handle = await page.query_selector(".tweet")
assert await tweet_handle.eval_on_selector(".like", "node => node.innerText") == "100"
assert await tweet_handle.eval_on_selector(".retweets", "node => node.innerText") = "10"
```
```python sync
tweet_handle = page.query_selector(".tweet")
assert tweet_handle.eval_on_selector(".like", "node => node.innerText") == "100"
assert tweet_handle.eval_on_selector(".retweets", "node => node.innerText") = "10"
```
### param: ElementHandle.$eval.selector = %%-query-selector-%%
### param: ElementHandle.$eval.pageFunction
@ -84,11 +133,11 @@ Optional argument to pass to [`param: pageFunction`]
Returns the return value of [`param: pageFunction`]
The method finds all elements matching the specified selector in the `ElementHandle`'s subtree and passes an array of
matched elements as a first argument to [`param: pageFunction`]. See [Working with selectors](./selectors.md#working-with-selectors)
for more details.
matched elements as a first argument to [`param: pageFunction`]. See
[Working with selectors](./selectors.md#working-with-selectors) for more details.
If [`param: pageFunction`] returns a [Promise], then `frame.$$eval` would wait for the promise to resolve and return
its value.
If [`param: pageFunction`] returns a [Promise], then `frame.$$eval` would wait for the promise to resolve and return its
value.
Examples:
@ -104,6 +153,17 @@ const feedHandle = await page.$('.feed');
expect(await feedHandle.$$eval('.tweet', nodes => nodes.map(n => n.innerText))).toEqual(['Hello!', 'Hi!']);
```
```python async
# FIXME
feed_handle = await page.query_selector(".feed")
assert await feed_handle.eval_on_selector_all(".tweet", "nodes => nodes.map(n => n.innerText)") == ["hello!", "hi!"]
```
```python sync
feed_handle = page.query_selector(".feed")
assert feed_handle.eval_on_selector_all(".tweet", "nodes => nodes.map(n => n.innerText)") == ["hello!", "hi!"]
```
### param: ElementHandle.$$eval.selector = %%-query-selector-%%
### param: ElementHandle.$$eval.pageFunction
@ -142,10 +202,21 @@ const box = await elementHandle.boundingBox();
await page.mouse.click(box.x + box.width / 2, box.y + box.height / 2);
```
```python async
box = await element_handle.bounding_box()
await page.mouse.click(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)
```
```python sync
box = element_handle.bounding_box()
page.mouse.click(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)
```
## async method: ElementHandle.check
This method checks the element by performing the following steps:
1. Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already checked, this method returns immediately.
1. Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already
checked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the element, unless [`option: force`] option is set.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to click in the center of the element.
@ -203,7 +274,8 @@ This method double clicks the element by performing the following steps:
1. Wait for [actionability](./actionability.md) checks on the element, unless [`option: force`] option is set.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to double click in the center of the element, or the specified [`option: position`].
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set. Note that if the first click of the `dblclick()` triggers a navigation event, this method will reject.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set. Note that
if the first click of the `dblclick()` triggers a navigation event, this method will reject.
If the element is detached from the DOM at any moment during the action, this method rejects.
@ -238,8 +310,17 @@ is dispatched. This is equivalend to calling
await elementHandle.dispatchEvent('click');
```
Under the hood, it creates an instance of an event based on the given [`param: type`], initializes it with [`param:
eventInit`] properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default.
```python async
await element_handle.dispatch_event("click")
```
```python sync
element_handle.dispatch_event("click")
```
Under the hood, it creates an instance of an event based on the given [`param: type`], initializes it with
[`param: eventInit`] properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by
default.
Since [`param: eventInit`] is event-specific, please refer to the events documentation for the lists of initial
properties:
@ -259,6 +340,18 @@ const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
await elementHandle.dispatchEvent('dragstart', { dataTransfer });
```
```python async
# note you can only create data_transfer in chromium and firefox
data_transfer = await page.evaluate_handle("new DataTransfer()")
await element_handle.dispatch_event("#source", "dragstart", {"dataTransfer": data_transfer})
```
```python sync
# note you can only create data_transfer in chromium and firefox
data_transfer = page.evaluate_handle("new DataTransfer()")
element_handle.dispatch_event("#source", "dragstart", {"dataTransfer": data_transfer})
```
### param: ElementHandle.dispatchEvent.type
- `type` <[string]>
@ -454,20 +547,49 @@ element, the method throws an error.
```js
// single selection matching the value
handle.selectOption('blue');
handle.selectOption('select#colors', 'blue');
// single selection matching both the value and the label
handle.selectOption({ label: 'Blue' });
// single selection matching the label
handle.selectOption('select#colors', { label: 'Blue' });
// multiple selection
handle.selectOption('red', 'green', 'blue');
handle.selectOption('select#colors', ['red', 'green', 'blue']);
```
// multiple selection for blue, red and second option
handle.selectOption({ value: 'blue' }, { index: 2 }, 'red');
```python async
# single selection matching the value
await handle.select_option("select#colors", "blue")
# single selection matching the label
await handle.select_option("select#colors", label="blue")
# multiple selection
await handle.select_option("select#colors", value=["red", "green", "blue"])
```
```python sync
# single selection matching the value
handle.select_option("select#colors", "blue")
# single selection matching both the label
handle.select_option("select#colors", label="blue")
# multiple selection
handle.select_option("select#colors", value=["red", "green", "blue"])
```
```python sync
# FIXME
# single selection matching the value
handle.select_option("blue")
# single selection matching both the value and the label
handle.select_option(label="blue")
# multiple selection
handle.select_option("red", "green", "blue")
# multiple selection for blue, red and second option
handle.select_option(value="blue", { index: 2 }, "red")
```
### param: ElementHandle.selectOption.values = %%-select-options-values-%%
### option: ElementHandle.selectOption.noWaitAfter = %%-input-no-wait-after-%%
### option: ElementHandle.selectOption.timeout = %%-input-timeout-%%
## async method: ElementHandle.selectText
@ -479,8 +601,8 @@ content.
## async method: ElementHandle.setInputFiles
This method expects `elementHandle` to point to an [input
element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
This method expects `elementHandle` to point to an
[input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
are resolved relative to the the current working directory. For empty array, clears the selected files.
@ -534,6 +656,16 @@ await elementHandle.type('Hello'); // Types instantly
await elementHandle.type('World', {delay: 100}); // Types slower, like a user
```
```python async
await element_handle.type("hello") # types instantly
await element_handle.type("world", delay=100) # types slower, like a user
```
```python sync
element_handle.type("hello") # types instantly
element_handle.type("world", delay=100) # types slower, like a user
```
An example of typing into a text field and then submitting the form:
```js
@ -542,6 +674,18 @@ await elementHandle.type('some text');
await elementHandle.press('Enter');
```
```python async
element_handle = await page.query_selector("input")
await element_handle.type("some text")
await element_handle.press("Enter")
```
```python sync
element_handle = page.query_selector("input")
element_handle.type("some text")
element_handle.press("Enter")
```
### param: ElementHandle.type.text
- `text` <[string]>
@ -559,7 +703,8 @@ Time to wait between key presses in milliseconds. Defaults to 0.
## async method: ElementHandle.uncheck
This method checks the element by performing the following steps:
1. Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already unchecked, this method returns immediately.
1. Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already
unchecked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the element, unless [`option: force`] option is set.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to click in the center of the element.
@ -581,11 +726,13 @@ When all steps combined have not finished during the specified [`option: timeout
Returns when the element satisfies the [`param: state`].
Depending on the [`param: state`] parameter, this method waits for one of the [actionability](./actionability.md)
checks to pass. This method throws when the element is detached while waiting, unless waiting for the `"hidden"` state.
Depending on the [`param: state`] parameter, this method waits for one of the [actionability](./actionability.md) checks
to pass. This method throws when the element is detached while waiting, unless waiting for the `"hidden"` state.
* `"visible"` Wait until the element is [visible](./actionability.md#visible).
* `"hidden"` Wait until the element is [not visible](./actionability.md#visible) or [not attached](./actionability.md#attached). Note that waiting for hidden does not throw when the element detaches.
* `"stable"` Wait until the element is both [visible](./actionability.md#visible) and [stable](./actionability.md#stable).
* `"hidden"` Wait until the element is [not visible](./actionability.md#visible) or
[not attached](./actionability.md#attached). Note that waiting for hidden does not throw when the element detaches.
* `"stable"` Wait until the element is both [visible](./actionability.md#visible) and
[stable](./actionability.md#stable).
* `"enabled"` Wait until the element is [enabled](./actionability.md#enabled).
* `"disabled"` Wait until the element is [not enabled](./actionability.md#enabled).
* `"editable"` Wait until the element is [editable](./actionability.md#editable).
@ -602,13 +749,13 @@ A state to wait for, see below for more details.
## async method: ElementHandle.waitForSelector
- returns: <[null]|[ElementHandle]>
Returns element specified by selector when it satisfies [`option: state`] option. Returns `null` if waiting for `hidden` or
`detached`.
Returns element specified by selector when it satisfies [`option: state`] option. Returns `null` if waiting for `hidden`
or `detached`.
Wait for the [`param: selector`] relative to the element handle to satisfy [`option: state`] option (either
appear/disappear from dom, or become visible/hidden). If at the moment of calling the method [`param: selector`]
already satisfies the condition, the method will return immediately. If the selector doesn't satisfy the condition for
the [`option: timeout`] milliseconds, the function will throw.
appear/disappear from dom, or become visible/hidden). If at the moment of calling the method [`param: selector`] already
satisfies the condition, the method will return immediately. If the selector doesn't satisfy the condition for the
[`option: timeout`] milliseconds, the function will throw.
```js
await page.setContent(`<div><span></span></div>`);
@ -617,6 +764,20 @@ const div = await page.$('div');
const span = await div.waitForSelector('span', { state: 'attached' });
```
```python async
await page.set_content("<div><span></span></div>")
div = await page.query_selector("div")
# waiting for the "span" selector relative to the div.
span = await div.wait_for_selector("span", state="attached")
```
```python sync
page.set_content("<div><span></span></div>")
div = page.query_selector("div")
# waiting for the "span" selector relative to the div.
span = div.wait_for_selector("span", state="attached")
```
:::note
This method does not work across navigations, use [`method: Page.waitForSelector`] instead.
:::

View file

@ -8,6 +8,14 @@ page.on('filechooser', async (fileChooser) => {
});
```
```python async
page.on("filechooser", lambda file_chooser: file_chooser.set_files("/tmp/myfile.pdf"))
```
```python sync
page.on("filechooser", lambda file_chooser: file_chooser.set_files("/tmp/myfile.pdf"))
```
## method: FileChooser.element
- returns: <[ElementHandle]>

View file

@ -1,12 +1,14 @@
# class: Frame
At every point of time, page exposes its current frame tree via the [`method: Page.mainFrame`] and [`method:
Frame.childFrames`] methods.
At every point of time, page exposes its current frame tree via the [`method: Page.mainFrame`] and
[`method: Frame.childFrames`] methods.
[Frame] object's lifecycle is controlled by three events, dispatched on the page object:
* [`event: Page.frameattached`] - fired when the frame gets attached to the page. A Frame can be attached to the page only once.
* [`event: Page.frameattached`] - fired when the frame gets attached to the page. A Frame can be attached to the page
only once.
* [`event: Page.framenavigated`] - fired when the frame commits navigation to a different URL.
* [`event: Page.framedetached`] - fired when the frame gets detached from the page. A Frame can be detached from the page only once.
* [`event: Page.framedetached`] - fired when the frame gets detached from the page. A Frame can be detached from the
page only once.
An example of dumping frame tree:
@ -29,12 +31,47 @@ const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'.
})();
```
An example of getting text from an iframe element:
```python async
import asyncio
from playwright.async_api import async_playwright
```js
const frame = page.frames().find(frame => frame.name() === 'myframe');
const text = await frame.$eval('.selector', element => element.textContent);
console.log(text);
async def run(playwright):
firefox = playwright.firefox
browser = await firefox.launch()
page = await browser.new_page()
await page.goto("https://www.theverge.com")
dump_frame_tree(page.main_frame, "")
await browser.close()
def dump_frame_tree(frame, indent):
print(indent + frame.name + '@' + frame.url)
for child in frame.child_frames:
dump_frame_tree(child, indent + " ")
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
```
```python sync
from playwright.sync_api import sync_playwright
def run(playwright):
firefox = playwright.firefox
browser = firefox.launch()
page = browser.new_page()
page.goto("https://www.theverge.com")
dump_frame_tree(page.main_frame, "")
browser.close()
def dump_frame_tree(frame, indent):
print(indent + frame.name + '@' + frame.url)
for child in frame.child_frames:
dump_frame_tree(child, indent + " ")
with sync_playwright() as playwright:
run(playwright)
```
## async method: Frame.$
@ -44,8 +81,9 @@ console.log(text);
Returns the ElementHandle pointing to the frame element.
The method finds an element matching the specified selector within the frame. See [Working with
selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector, returns `null`.
The method finds an element matching the specified selector within the frame. See
[Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
returns `null`.
### param: Frame.$.selector = %%-query-selector-%%
@ -56,8 +94,9 @@ selectors](./selectors.md#working-with-selectors) for more details. If no elemen
Returns the ElementHandles pointing to the frame elements.
The method finds all elements matching the specified selector within the frame. See [Working with
selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector, returns empty array.
The method finds all elements matching the specified selector within the frame. See
[Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
returns empty array.
### param: Frame.$$.selector = %%-query-selector-%%
@ -69,11 +108,11 @@ selectors](./selectors.md#working-with-selectors) for more details. If no elemen
Returns the return value of [`param: pageFunction`]
The method finds an element matching the specified selector within the frame and passes it as a first argument to
[`param: pageFunction`]. See [Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match
the selector, the method throws an error.
[`param: pageFunction`]. See [Working with selectors](./selectors.md#working-with-selectors) for more details. If no
elements match the selector, the method throws an error.
If [`param: pageFunction`] returns a [Promise], then `frame.$eval` would wait for the promise to resolve and return
its value.
If [`param: pageFunction`] returns a [Promise], then `frame.$eval` would wait for the promise to resolve and return its
value.
Examples:
@ -83,6 +122,18 @@ const preloadHref = await frame.$eval('link[rel=preload]', el => el.href);
const html = await frame.$eval('.main-container', (e, suffix) => e.outerHTML + suffix, 'hello');
```
```python async
search_value = await frame.eval_on_selector("#search", "el => el.value")
preload_href = await frame.eval_on_selector("link[rel=preload]", "el => el.href")
html = await frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
```
```python sync
search_value = frame.eval_on_selector("#search", "el => el.value")
preload_href = frame.eval_on_selector("link[rel=preload]", "el => el.href")
html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
```
### param: Frame.$eval.selector = %%-query-selector-%%
### param: Frame.$eval.pageFunction
@ -104,11 +155,11 @@ Optional argument to pass to [`param: pageFunction`]
Returns the return value of [`param: pageFunction`]
The method finds all elements matching the specified selector within the frame and passes an array of matched elements
as a first argument to [`param: pageFunction`]. See [Working with selectors](./selectors.md#working-with-selectors) for more
details.
as a first argument to [`param: pageFunction`]. See [Working with selectors](./selectors.md#working-with-selectors) for
more details.
If [`param: pageFunction`] returns a [Promise], then `frame.$$eval` would wait for the promise to resolve and return
its value.
If [`param: pageFunction`] returns a [Promise], then `frame.$$eval` would wait for the promise to resolve and return its
value.
Examples:
@ -116,6 +167,14 @@ Examples:
const divsCounts = await frame.$$eval('div', (divs, min) => divs.length >= min, 10);
```
```python async
divs_counts = await frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
```
```python sync
divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
```
### param: Frame.$$eval.selector = %%-query-selector-%%
### param: Frame.$$eval.pageFunction
@ -144,7 +203,8 @@ URL of a script to be added.
### option: Frame.addScriptTag.path
- `path` <[path]>
Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory.
Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to the
current working directory.
### option: Frame.addScriptTag.content
- `content` <[string]>
@ -154,7 +214,8 @@ Raw JavaScript content to be injected into frame.
### option: Frame.addScriptTag.type
- `type` <[string]>
Script type. Use 'module' in order to load a Javascript ES6 module. See [script](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) for more details.
Script type. Use 'module' in order to load a Javascript ES6 module. See
[script](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) for more details.
## async method: Frame.addStyleTag
- returns: <[ElementHandle]>
@ -172,7 +233,8 @@ URL of the `<link>` tag.
### option: Frame.addStyleTag.path
- `path` <[path]>
Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory.
Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to the
current working directory.
### option: Frame.addStyleTag.content
- `content` <[string]>
@ -182,9 +244,12 @@ Raw CSS content to be injected into frame.
## async method: Frame.check
This method checks an element matching [`param: selector`] by performing the following steps:
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to the DOM.
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already checked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is set. If the element is detached during the checks, the whole action is retried.
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to
the DOM.
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already
checked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is
set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set.
@ -207,8 +272,10 @@ When all steps combined have not finished during the specified [`option: timeout
## async method: Frame.click
This method clicks an element matching [`param: selector`] by performing the following steps:
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is set. If the element is detached during the checks, the whole action is retried.
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to
the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is
set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to click in the center of the element, or the specified [`option: position`].
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set.
@ -242,11 +309,14 @@ Gets the full HTML contents of the frame, including the doctype.
## async method: Frame.dblclick
This method double clicks an element matching [`param: selector`] by performing the following steps:
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is set. If the element is detached during the checks, the whole action is retried.
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to
the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is
set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to double click in the center of the element, or the specified [`option: position`].
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set. Note that if the first click of the `dblclick()` triggers a navigation event, this method will reject.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set. Note that
if the first click of the `dblclick()` triggers a navigation event, this method will reject.
When all steps combined have not finished during the specified [`option: timeout`], this method rejects with a
[TimeoutError]. Passing zero timeout disables this.
@ -281,8 +351,17 @@ is dispatched. This is equivalend to calling
await frame.dispatchEvent('button#submit', 'click');
```
Under the hood, it creates an instance of an event based on the given [`param: type`], initializes it with [`param:
eventInit`] properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default.
```python async
await frame.dispatch_event("button#submit", "click")
```
```python sync
frame.dispatch_event("button#submit", "click")
```
Under the hood, it creates an instance of an event based on the given [`param: type`], initializes it with
[`param: eventInit`] properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by
default.
Since [`param: eventInit`] is event-specific, please refer to the events documentation for the lists of initial
properties:
@ -302,6 +381,19 @@ const dataTransfer = await frame.evaluateHandle(() => new DataTransfer());
await frame.dispatchEvent('#source', 'dragstart', { dataTransfer });
```
```python async
# note you can only create data_transfer in chromium and firefox
data_transfer = await frame.evaluate_handle("new DataTransfer()")
await frame.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
```
```python sync
# note you can only create data_transfer in chromium and firefox
data_transfer = frame.evaluate_handle("new DataTransfer()")
frame.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
```
### param: Frame.dispatchEvent.selector = %%-input-selector-%%
### param: Frame.dispatchEvent.type
@ -321,10 +413,10 @@ Optional event-specific initialization properties.
Returns the return value of [`param: pageFunction`]
If the function passed to the `frame.evaluate` returns a [Promise], then `frame.evaluate` would wait for the promise to
If the function passed to the [`method: Frame.evaluate`] returns a [Promise], then [`method: Frame.evaluate`] would wait for the promise to
resolve and return its value.
If the function passed to the `frame.evaluate` returns a non-[Serializable] value, then `frame.evaluate` returns
If the function passed to the [`method: Frame.evaluate`] returns a non-[Serializable] value, then[ method: `Frame.evaluate`] returns
`undefined`. DevTools Protocol also supports transferring some additional values that are not serializable by `JSON`:
`-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
@ -335,13 +427,37 @@ const result = await frame.evaluate(([x, y]) => {
console.log(result); // prints "56"
```
```python async
result = await frame.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
print(result) # prints "56"
```
```python sync
result = frame.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
print(result) # prints "56"
```
A string can also be passed in instead of a function.
```js
console.log(await frame.evaluate('1 + 2')); // prints "3"
```
[ElementHandle] instances can be passed as an argument to the `frame.evaluate`:
```python async
print(await frame.evaluate("1 + 2")) # prints "3"
x = 10
print(await frame.evaluate(f"1 + {x}")) # prints "11"
```
```python sync
print(frame.evaluate("1 + 2")) # prints "3"
x = 10
print(frame.evaluate(f"1 + {x}")) # prints "11"
```
[ElementHandle] instances can be passed as an argument to the [`method: Frame.evaluate`]:
```js
const bodyHandle = await frame.$('body');
@ -349,6 +465,18 @@ const html = await frame.evaluate(([body, suffix]) => body.innerHTML + suffix, [
await bodyHandle.dispose();
```
```python async
body_handle = await frame.query_selector("body")
html = await frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
await body_handle.dispose()
```
```python sync
body_handle = frame.query_selector("body")
html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
body_handle.dispose()
```
### param: Frame.evaluate.pageFunction
* langs: js
- `pageFunction` <[function]|[string]>
@ -365,10 +493,10 @@ Optional argument to pass to [`param: pageFunction`]
Returns the return value of [`param: pageFunction`] as in-page object (JSHandle).
The only difference between `frame.evaluate` and `frame.evaluateHandle` is that `frame.evaluateHandle` returns in-page
The only difference between [`method: Frame.evaluate`] and [`method: Frame.evaluateHandle`] is that[ method: Fframe.evaluateHandle`] returns in-page
object (JSHandle).
If the function, passed to the `frame.evaluateHandle`, returns a [Promise], then `frame.evaluateHandle` would wait for
If the function, passed to the [`method: Frame.evaluateHandle`], returns a [Promise], then[ method: Fframe.evaluateHandle`] would wait for
the promise to resolve and return its value.
```js
@ -376,13 +504,32 @@ const aWindowHandle = await frame.evaluateHandle(() => Promise.resolve(window));
aWindowHandle; // Handle for the window object.
```
```python async
# FIXME
a_window_handle = await frame.evaluate_handle("Promise.resolve(window)")
a_window_handle # handle for the window object.
```
```python sync
a_window_handle = frame.evaluate_handle("Promise.resolve(window)")
a_window_handle # handle for the window object.
```
A string can also be passed in instead of a function.
```js
const aHandle = await frame.evaluateHandle('document'); // Handle for the 'document'.
```
[JSHandle] instances can be passed as an argument to the `frame.evaluateHandle`:
```python async
a_handle = await page.evaluate_handle("document") # handle for the "document"
```
```python sync
a_handle = page.evaluate_handle("document") # handle for the "document"
```
[JSHandle] instances can be passed as an argument to the [`method: Frame.evaluateHandle`]:
```js
const aHandle = await frame.evaluateHandle(() => document.body);
@ -391,6 +538,20 @@ console.log(await resultHandle.jsonValue());
await resultHandle.dispose();
```
```python async
a_handle = await page.evaluate_handle("document.body")
result_handle = await page.evaluate_handle("body => body.innerHTML", a_handle)
print(await result_handle.json_value())
await result_handle.dispose()
```
```python sync
a_handle = page.evaluate_handle("document.body")
result_handle = page.evaluate_handle("body => body.innerHTML", a_handle)
print(result_handle.json_value())
result_handle.dispose()
```
### param: Frame.evaluateHandle.pageFunction
* langs: js
- `pageFunction` <[function]|[string]>
@ -424,8 +585,8 @@ Value to fill for the `<input>`, `<textarea>` or `[contenteditable]` element.
## async method: Frame.focus
This method fetches an element with [`param: selector`] and focuses it. If there's no element matching [`param:
selector`], the method waits until a matching element appears in the DOM.
This method fetches an element with [`param: selector`] and focuses it. If there's no element matching
[`param: selector`], the method waits until a matching element appears in the DOM.
### param: Frame.focus.selector = %%-input-selector-%%
@ -447,6 +608,18 @@ const contentFrame = await frameElement.contentFrame();
console.log(frame === contentFrame); // -> true
```
```python async
frame_element = await frame.frame_element()
content_frame = await frame_element.content_frame()
assert frame == content_frame
```
```python sync
frame_element = frame.frame_element()
content_frame = frame_element.content_frame()
assert frame == content_frame
```
## async method: Frame.getAttribute
- returns: <[null]|[string]>
@ -475,16 +648,17 @@ last redirect.
* the main resource failed to load.
`frame.goto` will not throw an error when any valid HTTP status code is returned by the remote server, including 404
"Not Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling [`method:
Response.status`].
"Not Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling
[`method: Response.status`].
:::note
`frame.goto` either throws an error or returns a main resource response. The only exceptions are navigation
to `about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.
`frame.goto` either throws an error or returns a main resource response. The only exceptions are navigation to
`about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.
:::
:::note
Headless mode doesn't support navigation to a PDF document. See the [upstream
issue](https://bugs.chromium.org/p/chromium/issues/detail?id=761295).
Headless mode doesn't support navigation to a PDF document. See the
[upstream issue](https://bugs.chromium.org/p/chromium/issues/detail?id=761295).
:::
### param: Frame.goto.url
@ -499,14 +673,16 @@ URL to navigate frame to. The url should include scheme, e.g. `https://`.
### option: Frame.goto.referer
- `referer` <[string]>
Referer header value. If provided it will take preference over the referer header value set by [`method:
Page.setExtraHTTPHeaders`].
Referer header value. If provided it will take preference over the referer header value set by
[`method: Page.setExtraHTTPHeaders`].
## async method: Frame.hover
This method hovers over an element matching [`param: selector`] by performing the following steps:
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is set. If the element is detached during the checks, the whole action is retried.
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to
the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is
set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to hover over the center of the element, or the specified [`option: position`].
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
@ -609,9 +785,8 @@ Returns frame's name attribute as specified in the tag.
If the name is empty, returns the id attribute instead.
:::note
This value is calculated once when the frame is created, and will not update if the attribute is changed
later.
:::note
This value is calculated once when the frame is created, and will not update if the attribute is changed later.
:::
## method: Frame.page
- returns: <[Page]>
@ -678,9 +853,30 @@ frame.selectOption('select#colors', { label: 'Blue' });
frame.selectOption('select#colors', 'red', 'green', 'blue');
```
```python async
# single selection matching the value
await frame.select_option("select#colors", "blue")
# single selection matching the label
await frame.select_option("select#colors", label="blue")
# multiple selection
await frame.select_option("select#colors", value=["red", "green", "blue"])
```
```python sync
# single selection matching the value
frame.select_option("select#colors", "blue")
# single selection matching both the label
frame.select_option("select#colors", label="blue")
# multiple selection
frame.select_option("select#colors", value=["red", "green", "blue"])
```
### param: Frame.selectOption.selector = %%-query-selector-%%
### param: Frame.selectOption.values = %%-select-options-values-%%
### option: Frame.selectOption.noWaitAfter = %%-input-no-wait-after-%%
### option: Frame.selectOption.timeout = %%-input-timeout-%%
## async method: Frame.setContent
@ -696,8 +892,8 @@ HTML markup to assign to the page.
## async method: Frame.setInputFiles
This method expects [`param: selector`] to point to an [input
element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
This method expects [`param: selector`] to point to an
[input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
are resolved relative to the the current working directory. For empty array, clears the selected files.
@ -713,8 +909,10 @@ are resolved relative to the the current working directory. For empty array, cle
## async method: Frame.tap
This method taps an element matching [`param: selector`] by performing the following steps:
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is set. If the element is detached during the checks, the whole action is retried.
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to
the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is
set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [`property: Page.touchscreen`] to tap the center of the element, or the specified [`option: position`].
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set.
@ -764,6 +962,16 @@ await frame.type('#mytextarea', 'Hello'); // Types instantly
await frame.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
```
```python async
await frame.type("#mytextarea", "hello") # types instantly
await frame.type("#mytextarea", "world", delay=100) # types slower, like a user
```
```python sync
frame.type("#mytextarea", "hello") # types instantly
frame.type("#mytextarea", "world", delay=100) # types slower, like a user
```
### param: Frame.type.selector = %%-input-selector-%%
### param: Frame.type.text
@ -783,9 +991,12 @@ Time to wait between key presses in milliseconds. Defaults to 0.
## async method: Frame.uncheck
This method checks an element matching [`param: selector`] by performing the following steps:
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to the DOM.
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already unchecked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is set. If the element is detached during the checks, the whole action is retried.
1. Find an element match matching [`param: selector`]. If there is none, wait until a matching element is attached to
the DOM.
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already
unchecked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is
set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set.
@ -827,6 +1038,41 @@ const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'.
})();
```
```python async
import asyncio
from playwright.async_api import async_playwright
async def run(playwright):
webkit = playwright.webkit
browser = await webkit.launch()
page = await browser.new_page()
watch_dog = page.main_frame.wait_for_function("() => window.innerWidth < 100")
await page.set_viewport_size({"width": 50, "height": 50})
await watch_dog
await browser.close()
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
```
```python sync
from playwright.sync_api import sync_playwright
def run(playwright):
webkit = playwright.webkit
browser = await webkit.launch()
page = await browser.new_page()
watch_dog = page.main_frame.wait_for_function("() => window.innerWidth < 100")
await page.set_viewport_size({"width": 50, "height": 50})
await watch_dog
await browser.close()
with sync_playwright() as playwright:
run(playwright)
```
To pass an argument to the predicate of `frame.waitForFunction` function:
```js
@ -834,6 +1080,16 @@ const selector = '.foo';
await frame.waitForFunction(selector => !!document.querySelector(selector), selector);
```
```python async
selector = ".foo"
await frame.wait_for_function("selector => !!document.querySelector(selector)", selector)
```
```python sync
selector = ".foo"
frame.wait_for_function("selector => !!document.querySelector(selector)", selector)
```
### param: Frame.waitForFunction.pageFunction
* langs: js
- `pageFunction` <[function]|[string]>
@ -866,7 +1122,18 @@ await frame.click('button'); // Click triggers navigation.
await frame.waitForLoadState(); // Waits for 'load' state by default.
```
```python async
await frame.click("button") # click triggers navigation.
await frame.wait_for_load_state() # the promise resolves after "load" event.
```
```python sync
frame.click("button") # click triggers navigation.
frame.wait_for_load_state() # the promise resolves after "load" event.
```
### param: Frame.waitForLoadState.state = %%-wait-for-load-state-state-%%
### option: Frame.waitForLoadState.timeout = %%-navigation-timeout-%%
## async method: Frame.waitForNavigation
@ -881,14 +1148,26 @@ the frame to navigate. Consider this example:
```js
const [response] = await Promise.all([
frame.waitForNavigation(), // Wait for the navigation to finish
frame.click('a.my-link'), // Clicking the link will indirectly cause a navigation
frame.waitForNavigation(), // The promise resolves after navigation has finished
frame.click('a.delayed-navigation'), // Clicking the link will indirectly cause a navigation
]);
```
```python async
async with frame.expect_navigation():
await frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
# Resolves after navigation has finished
```
```python sync
with frame.expect_navigation():
frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
# Resolves after navigation has finished
```
:::note
Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is
considered a navigation.
Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is considered
a navigation.
:::
### option: Frame.waitForNavigation.timeout = %%-navigation-timeout-%%
@ -903,33 +1182,68 @@ URL string, URL regex pattern or predicate receiving [URL] to match while waitin
## async method: Frame.waitForSelector
- returns: <[null]|[ElementHandle]>
Returns when element specified by selector satisfies [`option: state`] option. Returns `null` if waiting for `hidden`
or `detached`.
Returns when element specified by selector satisfies [`option: state`] option. Returns `null` if waiting for `hidden` or
`detached`.
Wait for the [`param: selector`] to satisfy [`option: state`] option (either appear/disappear from dom, or become
visible/hidden). If at the moment of calling the method [`param: selector`] already satisfies the condition, the
method will return immediately. If the selector doesn't satisfy the condition for the [`option: timeout`]
milliseconds, the function will throw.
visible/hidden). If at the moment of calling the method [`param: selector`] already satisfies the condition, the method
will return immediately. If the selector doesn't satisfy the condition for the [`option: timeout`] milliseconds, the
function will throw.
This method works across navigations:
```js
const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'.
const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
(async () => {
const browser = await webkit.launch();
const browser = await chromium.launch();
const page = await browser.newPage();
let currentURL;
page.mainFrame()
.waitForSelector('img')
.then(() => console.log('First URL with image: ' + currentURL));
for (currentURL of ['https://example.com', 'https://google.com', 'https://bbc.com']) {
for (let currentURL of ['https://google.com', 'https://bbc.com']) {
await page.goto(currentURL);
const element = await page.mainFrame().waitForSelector('img');
console.log('Loaded image: ' + await element.getAttribute('src'));
}
await browser.close();
})();
```
```python async
import asyncio
from playwright.async_api import async_playwright
async def run(playwright):
chromium = playwright.chromium
browser = await chromium.launch()
page = await browser.new_page()
for current_url in ["https://google.com", "https://bbc.com"]:
await page.goto(current_url, wait_until="domcontentloaded")
element = await page.main_frame.wait_for_selector("img")
print("Loaded image: " + str(await element.get_attribute("src")))
await browser.close()
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
```
```python sync
from playwright.sync_api import sync_playwright
def run(playwright):
chromium = playwright.chromium
browser = chromium.launch()
page = browser.new_page()
for current_url in ["https://google.com", "https://bbc.com"]:
page.goto(current_url, wait_until="domcontentloaded")
element = page.main_frame.wait_for_selector("img")
print("Loaded image: " + str(element.get_attribute("src")))
browser.close()
with sync_playwright() as playwright:
run(playwright)
```
### param: Frame.waitForSelector.selector = %%-query-selector-%%
### option: Frame.waitForSelector.state = %%-wait-for-selector-state-%%

View file

@ -8,12 +8,22 @@ const windowHandle = await page.evaluateHandle(() => window);
// ...
```
JSHandle prevents the referenced JavaScript object being garbage collected unless the handle is exposed with [`method:
JSHandle.dispose`]. JSHandles are auto-disposed when their origin frame gets navigated or the parent context gets
destroyed.
```python async
window_handle = await page.evaluate_handle("window")
# ...
```
JSHandle instances can be used as an argument in [`method: Page.$eval`], [`method: Page.evaluate`] and [`method:
Page.evaluateHandle`] methods.
```python sync
window_handle = page.evaluate_handle("window")
# ...
```
JSHandle prevents the referenced JavaScript object being garbage collected unless the handle is exposed with
[`method: JSHandle.dispose`]. JSHandles are auto-disposed when their origin frame gets navigated or the parent context
gets destroyed.
JSHandle instances can be used as an argument in [`method: Page.$eval`], [`method: Page.evaluate`] and
[`method: Page.evaluateHandle`] methods.
## method: JSHandle.asElement
- returns: <[null]|[ElementHandle]>
@ -31,14 +41,24 @@ Returns the return value of [`param: pageFunction`]
This method passes this handle as the first argument to [`param: pageFunction`].
If [`param: pageFunction`] returns a [Promise], then `handle.evaluate` would wait for the promise to resolve and
return its value.
If [`param: pageFunction`] returns a [Promise], then `handle.evaluate` would wait for the promise to resolve and return
its value.
Examples:
```js
const tweetHandle = await page.$('.tweet .retweets');
expect(await tweetHandle.evaluate((node, suffix) => node.innerText, ' retweets')).toBe('10 retweets');
expect(await tweetHandle.evaluate(node => node.innerText)).toBe('10 retweets');
```
```python async
tweet_handle = await page.query_selector(".tweet .retweets")
assert await tweet_handle.evaluate("node => node.innerText") == "10 retweets"
```
```python sync
tweet_handle = page.query_selector(".tweet .retweets")
assert tweet_handle.evaluate("node => node.innerText") == "10 retweets"
```
### param: JSHandle.evaluate.pageFunction
@ -91,6 +111,22 @@ const documentHandle = properties.get('document');
await handle.dispose();
```
```python async
handle = await page.evaluate_handle("{window, document}")
properties = await handle.get_properties()
window_handle = properties.get("window")
document_handle = properties.get("document")
await handle.dispose()
```
```python sync
handle = page.evaluate_handle("{window, document}")
properties = handle.get_properties()
window_handle = properties.get("window")
document_handle = properties.get("document")
handle.dispose()
```
## async method: JSHandle.getProperty
- returns: <[JSHandle]>
@ -107,6 +143,6 @@ property to get
Returns a JSON representation of the object. If the object has a `toJSON` function, it **will not be called**.
:::note
The method will return an empty JSON object if the referenced object is not stringifiable. It will throw an
error if the object has circular references.
The method will return an empty JSON object if the referenced object is not stringifiable. It will throw an error if the
object has circular references.
:::

View file

@ -3,8 +3,8 @@
Keyboard provides an api for managing a virtual keyboard. The high level api is [`method: Keyboard.type`], which takes
raw characters and generates proper keydown, keypress/input, and keyup events on your page.
For finer control, you can use [`method: Keyboard.down`], [`method: Keyboard.up`], and [`method:
Keyboard.insertText`] to manually fire events as if they were generated from a real keyboard.
For finer control, you can use [`method: Keyboard.down`], [`method: Keyboard.up`], and [`method: Keyboard.insertText`]
to manually fire events as if they were generated from a real keyboard.
An example of holding down `Shift` in order to select and delete some text:
@ -21,6 +21,28 @@ await page.keyboard.press('Backspace');
// Result text will end up saying 'Hello!'
```
```python async
await page.keyboard.type("Hello World!")
await page.keyboard.press("ArrowLeft")
await page.keyboard.down("Shift")
for i in range(6):
await page.keyboard.press("ArrowLeft")
await page.keyboard.up("Shift")
await page.keyboard.press("Backspace")
# result text will end up saying "Hello!"
```
```python sync
page.keyboard.type("Hello World!")
page.keyboard.press("ArrowLeft")
page.keyboard.down("Shift")
for i in range(6):
page.keyboard.press("ArrowLeft")
page.keyboard.up("Shift")
page.keyboard.press("Backspace")
# result text will end up saying "Hello!"
```
An example of pressing uppercase `A`
```js
@ -29,6 +51,18 @@ await page.keyboard.press('Shift+KeyA');
await page.keyboard.press('Shift+A');
```
```python async
await page.keyboard.press("Shift+KeyA")
# or
await page.keyboard.press("Shift+A")
```
```python sync
page.keyboard.press("Shift+KeyA")
# or
page.keyboard.press("Shift+A")
```
An example to trigger select-all with the keyboard
```js
@ -38,6 +72,20 @@ await page.keyboard.press('Control+A');
await page.keyboard.press('Meta+A');
```
```python async
# on windows and linux
await page.keyboard.press("Control+A")
# on mac_os
await page.keyboard.press("Meta+A")
```
```python sync
# on windows and linux
page.keyboard.press("Control+A")
# on mac_os
page.keyboard.press("Meta+A")
```
## async method: Keyboard.down
Dispatches a `keydown` event.
@ -57,8 +105,8 @@ Holding down `Shift` will type the text that corresponds to the [`param: key`] i
If [`param: key`] is a single character, it is case-sensitive, so the values `a` and `A` will generate different
respective texts.
If [`param: key`] is a modifier key, `Shift`, `Meta`, `Control`, or `Alt`, subsequent key presses will be sent with
that modifier active. To release the modifier key, use [`method: Keyboard.up`].
If [`param: key`] is a modifier key, `Shift`, `Meta`, `Control`, or `Alt`, subsequent key presses will be sent with that
modifier active. To release the modifier key, use [`method: Keyboard.up`].
After the key is pressed once, subsequent calls to [`method: Keyboard.down`] will have
[repeat](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat) set to true. To release the key, use
@ -81,6 +129,14 @@ Dispatches only `input` event, does not emit the `keydown`, `keyup` or `keypress
page.keyboard.insertText('嗨');
```
```python async
await page.keyboard.insert_text("嗨")
```
```python sync
page.keyboard.insert_text("嗨")
```
:::note
Modifier keys DO NOT effect `keyboard.insertText`. Holding down `Shift` will not type the text in upper case.
:::
@ -122,6 +178,30 @@ await page.screenshot({ path: 'O.png' });
await browser.close();
```
```python async
page = await browser.new_page()
await page.goto("https://keycode.info")
await page.keyboard.press("a")
await page.screenshot(path="a.png")
await page.keyboard.press("ArrowLeft")
await page.screenshot(path="arrow_left.png")
await page.keyboard.press("Shift+O")
await page.screenshot(path="o.png")
await browser.close()
```
```python sync
page = browser.new_page()
page.goto("https://keycode.info")
page.keyboard.press("a")
page.screenshot(path="a.png")
page.keyboard.press("ArrowLeft")
page.screenshot(path="arrow_left.png")
page.keyboard.press("Shift+O")
page.screenshot(path="o.png")
browser.close()
```
Shortcut for [`method: Keyboard.down`] and [`method: Keyboard.up`].
### param: Keyboard.press.key
@ -145,6 +225,16 @@ await page.keyboard.type('Hello'); // Types instantly
await page.keyboard.type('World', {delay: 100}); // Types slower, like a user
```
```python async
await page.keyboard.type("Hello") # types instantly
await page.keyboard.type("World", delay=100) # types slower, like a user
```
```python sync
page.keyboard.type("Hello") # types instantly
page.keyboard.type("World", delay=100) # types slower, like a user
```
:::note
Modifier keys DO NOT effect `keyboard.type`. Holding down `Shift` will not type the text in upper case.
:::

View file

@ -15,6 +15,28 @@ await page.mouse.move(0, 0);
await page.mouse.up();
```
```python async
# using page.mouse to trace a 100x100 square.
await page.mouse.move(0, 0)
await page.mouse.down()
await page.mouse.move(0, 100)
await page.mouse.move(100, 100)
await page.mouse.move(100, 0)
await page.mouse.move(0, 0)
await page.mouse.up()
```
```python sync
# using page.mouse to trace a 100x100 square.
page.mouse.move(0, 0)
page.mouse.down()
page.mouse.move(0, 100)
page.mouse.move(100, 100)
page.mouse.move(100, 0)
page.mouse.move(0, 0)
page.mouse.up()
```
## async method: Mouse.click
Shortcut for [`method: Mouse.move`], [`method: Mouse.down`], [`method: Mouse.up`].

View file

@ -1,4 +1,3 @@
# class: Page
* extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
@ -830,10 +829,10 @@ page.evaluate("matchMedia('(prefers-color-scheme: no-preference)').matches")
Returns the value of the [`param: pageFunction`] invocation.
If the function passed to the `page.evaluate` returns a [Promise], then `page.evaluate` would wait for the promise to
If the function passed to the [`method: Page.evaluate`] returns a [Promise], then [`method: Page.evaluate`] would wait for the promise to
resolve and return its value.
If the function passed to the `page.evaluate` returns a non-[Serializable] value, then `page.evaluate` resolves to
If the function passed to the [`method: Page.evaluate`] returns a non-[Serializable] value, then[ method: `Page.evaluate`] resolves to
`undefined`. DevTools Protocol also supports transferring some additional values that are not serializable by `JSON`:
`-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
@ -876,7 +875,7 @@ x = 10
print(page.evaluate(f"1 + {x}")) # prints "11"
```
[ElementHandle] instances can be passed as an argument to the `page.evaluate`:
[ElementHandle] instances can be passed as an argument to the [`method: Page.evaluate`]:
```js
const bodyHandle = await page.$('body');
@ -914,12 +913,28 @@ Optional argument to pass to [`param: pageFunction`]
Returns the value of the [`param: pageFunction`] invocation as in-page object (JSHandle).
The only difference between `page.evaluate` and `page.evaluateHandle` is that `page.evaluateHandle` returns in-page
The only difference between [`method: Page.evaluate`] and [`method: Page.evaluateHandle`] is that [`method: Page.evaluateHandle`] returns in-page
object (JSHandle).
If the function passed to the `page.evaluateHandle` returns a [Promise], then `page.evaluateHandle` would wait for the
If the function passed to the [`method: Page.evaluateHandle`] returns a [Promise], then [`method:Ppage.EvaluateHandle`] would wait for the
promise to resolve and return its value.
```js
const aWindowHandle = await page.evaluateHandle(() => Promise.resolve(window));
aWindowHandle; // Handle for the window object.
```
```python async
# FIXME
a_window_handle = await page.evaluate_handle("Promise.resolve(window)")
a_window_handle # handle for the window object.
```
```python sync
a_window_handle = page.evaluate_handle("Promise.resolve(window)")
a_window_handle # handle for the window object.
```
A string can also be passed in instead of a function:
```js
@ -934,7 +949,7 @@ a_handle = await page.evaluate_handle("document") # handle for the "document"
a_handle = page.evaluate_handle("document") # handle for the "document"
```
[JSHandle] instances can be passed as an argument to the `page.evaluateHandle`:
[JSHandle] instances can be passed as an argument to the [`method: Page.evaluateHandle`]:
```js
const aHandle = await page.evaluateHandle(() => document.body);
@ -2234,6 +2249,7 @@ await page.wait_for_function("selector => !!document.querySelector(selector)", s
```
```python sync
selector = ".foo"
page.wait_for_function("selector => !!document.querySelector(selector)", selector)
```

View file

@ -1,7 +1,8 @@
# class: Playwright
Playwright module provides a method to launch a browser instance.
The following is a typical example of using Playwright to drive automation:
Playwright module provides a method to launch a browser instance. The following is a typical example of using Playwright
to drive automation:
```js
const { chromium, firefox, webkit } = require('playwright');
@ -14,7 +15,41 @@ const { chromium, firefox, webkit } = require('playwright');
})();
```
By default, the `playwright` NPM package automatically downloads browser executables during installation. The `playwright-core` NPM package can be used to skip automatic downloads.
```python async
import asyncio
from playwright.async_api import async_playwright
async def run(playwright):
chromium = playwright.chromium # or "firefox" or "webkit".
browser = await chromium.launch()
page = await browser.new_page()
await page.goto("http://example.com")
# other actions...
await browser.close()
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
```
```python sync
from playwright.sync_api import sync_playwright
def run(playwright):
chromium = playwright.chromium # or "firefox" or "webkit".
browser = chromium.launch()
page = browser.new_page()
page.goto("http://example.com")
# other actions...
browser.close()
with sync_playwright() as playwright:
run(playwright)
```
By default, the `playwright` NPM package automatically downloads browser executables during installation. The
`playwright-core` NPM package can be used to skip automatic downloads.
## property: Playwright.chromium
- type: <[BrowserType]>
@ -42,18 +77,56 @@ const iPhone = devices['iPhone 6'];
})();
```
```python async
import asyncio
from playwright.async_api import async_playwright
async def run(playwright):
webkit = playwright.webkit
iphone = playwright.devices["iPhone 6"]
browser = await webkit.launch()
context = await browser.new_context(**iphone)
page = await context.new_page()
await page.goto("http://example.com")
# other actions...
await browser.close()
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
```
```python sync
from playwright.sync_api import sync_playwright
def run(playwright):
webkit = playwright.webkit
iphone = playwright.devices["iPhone 6"]
browser = webkit.launch()
context = browser.new_context(**iphone)
page = context.new_page()
page.goto("http://example.com")
# other actions...
browser.close()
with sync_playwright() as playwright:
run(playwright)
```
## property: Playwright.errors
* langs: js
- type: <[Object]>
- `TimeoutError` <[function]> A class of [TimeoutError].
Playwright methods might throw errors if they are unable to fulfill a request. For example, [`method: Page.waitForSelector`]
might fail if the selector doesn't match any nodes during the given timeframe.
Playwright methods might throw errors if they are unable to fulfill a request. For example,
[`method: Page.waitForSelector`] might fail if the selector doesn't match any nodes during the given timeframe.
For certain types of errors Playwright uses specific error classes.
These classes are available via [`playwright.errors`](#playwrighterrors).
For certain types of errors Playwright uses specific error classes. These classes are available via
[`playwright.errors`](#playwrighterrors).
An example of handling a timeout error:
```js
try {
await page.waitForSelector('.foo');
@ -64,6 +137,20 @@ try {
}
```
```python async
try:
await page.wait_for_selector(".foo")
except TimeoutError as e:
# do something if this is a timeout.
```
```python sync
try:
page.wait_for_selector(".foo")
except TimeoutError as e:
# do something if this is a timeout.
```
## property: Playwright.firefox
- type: <[BrowserType]>
@ -72,7 +159,8 @@ This object can be used to launch or connect to Firefox, returning instances of
## property: Playwright.selectors
- type: <[Selectors]>
Selectors can be used to install custom selector engines. See [Working with selectors](./selectors.md#working-with-selectors) for more information.
Selectors can be used to install custom selector engines. See
[Working with selectors](./selectors.md#working-with-selectors) for more information.
## property: Playwright.webkit
- type: <[BrowserType]>

View file

@ -9,8 +9,8 @@ If request fails at some point, then instead of `'requestfinished'` event (and p
the [`event: Page.requestfailed`] event is emitted.
:::note
HTTP Error responses, such as 404 or 503, are still successful responses from HTTP standpoint, so request
will complete with `'requestfinished'` event.
HTTP Error responses, such as 404 or 503, are still successful responses from HTTP standpoint, so request will complete
with `'requestfinished'` event.
:::
If request gets a 'redirect' response, the request is successfully finished with the 'requestfinished' event, and a new
@ -31,6 +31,10 @@ page.on('requestfailed', request => {
});
```
```py
page.on("requestfailed", lambda: request => print(request.url + " " + request.failure)
```
## method: Request.frame
- returns: <[Frame]>
@ -85,6 +89,16 @@ const response = await page.goto('http://example.com');
console.log(response.request().redirectedFrom().url()); // 'http://example.com'
```
```python async
response = await page.goto("http://example.com")
print(response.request.redirected_from.url) # "http://example.com"
```
```python sync
response = page.goto("http://example.com")
print(response.request.redirected_from.url) # "http://example.com"
```
If the website `https://google.com` has no redirects:
```js
@ -92,6 +106,16 @@ const response = await page.goto('https://google.com');
console.log(response.request().redirectedFrom()); // null
```
```python async
response = await page.goto("https://google.com")
print(response.request.redirected_from) # None
```
```python sync
response = page.goto("https://google.com")
print(response.request.redirected_from) # None
```
## method: Request.redirectedTo
- returns: <[null]|[Request]>
@ -103,6 +127,10 @@ This method is the opposite of [`method: Request.redirectedFrom`]:
console.log(request.redirectedFrom().redirectedTo() === request); // true
```
```py
assert request.redirected_from.redirected_to == request
```
## method: Request.resourceType
- returns: <[string]>
@ -118,27 +146,50 @@ Returns the matching [Response] object, or `null` if the response was not receiv
## method: Request.timing
- returns: <[Object]>
- `startTime` <[float]> Request start time in milliseconds elapsed since January 1, 1970 00:00:00 UTC
- `domainLookupStart` <[float]> Time immediately before the browser starts the domain name lookup for the resource. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `domainLookupEnd` <[float]> Time immediately after the browser starts the domain name lookup for the resource. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `connectStart` <[float]> Time immediately before the user agent starts establishing the connection to the server to retrieve the resource. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `secureConnectionStart` <[float]> Time immediately before the browser starts the handshake process to secure the current connection. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `connectEnd` <[float]> Time immediately before the user agent starts establishing the connection to the server to retrieve the resource. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `requestStart` <[float]> Time immediately before the browser starts requesting the resource from the server, cache, or local resource. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `responseStart` <[float]> Time immediately after the browser starts requesting the resource from the server, cache, or local resource. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `responseEnd` <[float]> Time immediately after the browser receives the last byte of the resource or immediately before the transport connection is closed, whichever comes first. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `domainLookupStart` <[float]> Time immediately before the browser starts the domain name lookup for the
resource. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `domainLookupEnd` <[float]> Time immediately after the browser starts the domain name lookup for the resource.
The value is given in milliseconds relative to `startTime`, -1 if not available.
- `connectStart` <[float]> Time immediately before the user agent starts establishing the connection to the server
to retrieve the resource. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `secureConnectionStart` <[float]> Time immediately before the browser starts the handshake process to secure the
current connection. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `connectEnd` <[float]> Time immediately before the user agent starts establishing the connection to the server
to retrieve the resource. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `requestStart` <[float]> Time immediately before the browser starts requesting the resource from the server,
cache, or local resource. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `responseStart` <[float]> Time immediately after the browser starts requesting the resource from the server,
cache, or local resource. The value is given in milliseconds relative to `startTime`, -1 if not available.
- `responseEnd` <[float]> Time immediately after the browser receives the last byte of the resource or immediately
before the transport connection is closed, whichever comes first. The value is given in milliseconds relative to
`startTime`, -1 if not available.
Returns resource timing information for given request. Most of the timing values become available upon the response,
`responseEnd` becomes available when request finishes. Find more information at [Resource Timing
API](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming).
`responseEnd` becomes available when request finishes. Find more information at
[Resource Timing API](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming).
```js
const [request] = await Promise.all([
page.waitForEvent('requestfinished'),
page.goto(httpsServer.EMPTY_PAGE)
page.goto('http://example.com')
]);
console.log(request.timing());
```
```python async
async with page.expect_event("requestfinished") as request_info:
await page.goto("http://example.com")
request = await request_info.value
print(request.timing)
```
```python sync
with page.expect_event("requestfinished") as request_info:
page.goto("http://example.com")
request = request_info.value
print(request.timing)
```
## method: Request.url
- returns: <[string]>

View file

@ -1,7 +1,7 @@
# class: Route
Whenever a network route is set up with [`method: Page.route`] or [`method: BrowserContext.route`], the `Route`
object allows to handle the route.
Whenever a network route is set up with [`method: Page.route`] or [`method: BrowserContext.route`], the `Route` object
allows to handle the route.
## async method: Route.abort
@ -11,20 +11,22 @@ Aborts the route's request.
- `errorCode` <[string]>
Optional error code. Defaults to `failed`, could be one of the following:
* `'aborted'` - An operation was aborted (due to user action)
* `'accessdenied'` - Permission to access a resource, other than the network, was denied
* `'addressunreachable'` - The IP address is unreachable. This usually means that there is no route to the specified host or network.
* `'blockedbyclient'` - The client chose to block the request.
* `'blockedbyresponse'` - The request failed because the response was delivered along with requirements which are not met ('X-Frame-Options' and 'Content-Security-Policy' ancestor checks, for instance).
* `'connectionaborted'` - A connection timed out as a result of not receiving an ACK for data sent.
* `'connectionclosed'` - A connection was closed (corresponding to a TCP FIN).
* `'connectionfailed'` - A connection attempt failed.
* `'connectionrefused'` - A connection attempt was refused.
* `'connectionreset'` - A connection was reset (corresponding to a TCP RST).
* `'internetdisconnected'` - The Internet connection has been lost.
* `'namenotresolved'` - The host name could not be resolved.
* `'timedout'` - An operation timed out.
* `'failed'` - A generic failure occurred.
* `'aborted'` - An operation was aborted (due to user action)
* `'accessdenied'` - Permission to access a resource, other than the network, was denied
* `'addressunreachable'` - The IP address is unreachable. This usually means that there is no route to the specified
host or network.
* `'blockedbyclient'` - The client chose to block the request.
* `'blockedbyresponse'` - The request failed because the response was delivered along with requirements which are not
met ('X-Frame-Options' and 'Content-Security-Policy' ancestor checks, for instance).
* `'connectionaborted'` - A connection timed out as a result of not receiving an ACK for data sent.
* `'connectionclosed'` - A connection was closed (corresponding to a TCP FIN).
* `'connectionfailed'` - A connection attempt failed.
* `'connectionrefused'` - A connection attempt was refused.
* `'connectionreset'` - A connection was reset (corresponding to a TCP RST).
* `'internetdisconnected'` - The Internet connection has been lost.
* `'namenotresolved'` - The host name could not be resolved.
* `'timedout'` - An operation timed out.
* `'failed'` - A generic failure occurred.
## async method: Route.continue
* langs:
@ -44,6 +46,32 @@ await page.route('**/*', (route, request) => {
});
```
```python async
async def handle(route, request):
# override headers
headers = {
**request.headers,
"foo": "bar" # set "foo" header
"origin": None # remove "origin" header
}
await route.continue(headers=headers)
}
await page.route("**/*", handle)
```
```python sync
def handle(route, request):
# override headers
headers = {
**request.headers,
"foo": "bar" # set "foo" header
"origin": None # remove "origin" header
}
route.continue(headers=headers)
}
page.route("**/*", handle)
```
### option: Route.continue.url
- `url` <[string]>
@ -64,7 +92,6 @@ If set changes the post data of request
If set changes the request HTTP headers. Header values will be converted to a string.
## async method: Route.fulfill
Fulfills route's request with given response.
@ -81,12 +108,34 @@ await page.route('**/*', route => {
});
```
```python async
await page.route("**/*", lambda route: route.fulfill(
status=404,
content_type="text/plain",
body="not found!"))
```
```python sync
page.route("**/*", lambda route: route.fulfill(
status=404,
content_type="text/plain",
body="not found!"))
```
An example of serving static file:
```js
await page.route('**/xhr_endpoint', route => route.fulfill({ path: 'mock_data.json' }));
```
```python async
await page.route("**/xhr_endpoint", lambda route: route.fulfill(path="mock_data.json"))
```
```python sync
page.route("**/xhr_endpoint", lambda route: route.fulfill(path="mock_data.json"))
```
### option: Route.fulfill.status
- `status` <[int]>
@ -110,7 +159,8 @@ Response body.
### option: Route.fulfill.path
- `path` <[path]>
File path to respond with. The content type will be inferred from file extension. If `path` is a relative path, then it is resolved relative to the current working directory.
File path to respond with. The content type will be inferred from file extension. If `path` is a relative path, then it
is resolved relative to the current working directory.
## method: Route.request
- returns: <[Request]>

View file

@ -1,7 +1,7 @@
# class: Selectors
Selectors can be used to install custom selector engines. See [Working with selectors](./selectors.md#working-with-selectors) for more
information.
Selectors can be used to install custom selector engines. See
[Working with selectors](./selectors.md#working-with-selectors) for more information.
## async method: Selectors.register
@ -42,6 +42,14 @@ const { selectors, firefox } = require('playwright'); // Or 'chromium' or 'webk
})();
```
```python async
# FIXME: add snippet
```
```python sync
# FIXME: add snippet
```
### param: Selectors.register.name
- `name` <[string]>
@ -51,7 +59,8 @@ contain `[a-zA-Z0-9_]` characters.
### param: Selectors.register.script
* langs: js
- `script` <[function]|[string]|[Object]>
- `path` <[path]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `path` <[path]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the
current working directory. Optional.
- `content` <[string]> Raw script content. Optional.
Script that evaluates to a selector engine instance.

View file

@ -6,6 +6,14 @@ When browser context is created with the `videosPath` option, each page has a vi
console.log(await page.video().path());
```
```python async
print(await page.video.path())
```
```python sync
print(page.video.path())
```
## async method: Video.path
- returns: <[path]>

View file

@ -15,6 +15,18 @@ for (const worker of page.workers())
console.log(' ' + worker.url());
```
```py
def handle_worker(worker):
print("worker created: " + worker.url)
worker.on("close", lambda: print("worker destroyed: " + worker.url))
page.on('worker', handle_worker)
print("current workers:")
for worker in page.workers:
print(" " + worker.url)
```
## event: Worker.close
- type: <[Worker]>

108
types/types.d.ts vendored
View file

@ -75,12 +75,16 @@ export interface Page {
/**
* Returns the value of the `pageFunction` invocation.
*
* If the function passed to the `page.evaluate` returns a [Promise], then `page.evaluate` would wait for the promise to
* resolve and return its value.
* If the function passed to the
* [page.evaluate()](https://github.com/microsoft/playwright/blob/master/docs/api.md#pageevaluate) returns a [Promise],
* then [page.evaluate()](https://github.com/microsoft/playwright/blob/master/docs/api.md#pageevaluate) would wait for the
* promise to resolve and return its value.
*
* If the function passed to the `page.evaluate` returns a non-[Serializable] value, then `page.evaluate` resolves to
* `undefined`. DevTools Protocol also supports transferring some additional values that are not serializable by `JSON`:
* `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
* If the function passed to the
* [page.evaluate()](https://github.com/microsoft/playwright/blob/master/docs/api.md#pageevaluate) returns a
* non-[Serializable] value, then[ method: `Page.evaluate`] resolves to `undefined`. DevTools Protocol also supports
* transferring some additional values that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and
* bigint literals.
*
* Passing argument to `pageFunction`:
*
@ -99,7 +103,8 @@ export interface Page {
* console.log(await page.evaluate(`1 + ${x}`)); // prints "11"
* ```
*
* [ElementHandle] instances can be passed as an argument to the `page.evaluate`:
* [ElementHandle] instances can be passed as an argument to the
* [page.evaluate()](https://github.com/microsoft/playwright/blob/master/docs/api.md#pageevaluate):
*
* ```js
* const bodyHandle = await page.$('body');
@ -118,11 +123,20 @@ export interface Page {
/**
* Returns the value of the `pageFunction` invocation as in-page object (JSHandle).
*
* The only difference between `page.evaluate` and `page.evaluateHandle` is that `page.evaluateHandle` returns in-page
* object (JSHandle).
* The only difference between
* [page.evaluate()](https://github.com/microsoft/playwright/blob/master/docs/api.md#pageevaluate) and
* [page.evaluateHandle()](https://github.com/microsoft/playwright/blob/master/docs/api.md#pageevaluatehandle) is that
* [page.evaluateHandle()](https://github.com/microsoft/playwright/blob/master/docs/api.md#pageevaluatehandle) returns
* in-page object (JSHandle).
*
* If the function passed to the `page.evaluateHandle` returns a [Promise], then `page.evaluateHandle` would wait for the
* promise to resolve and return its value.
* If the function passed to the
* [page.evaluateHandle()](https://github.com/microsoft/playwright/blob/master/docs/api.md#pageevaluatehandle) returns a
* [Promise], then [`method:Ppage.EvaluateHandle`] would wait for the promise to resolve and return its value.
*
* ```js
* const aWindowHandle = await page.evaluateHandle(() => Promise.resolve(window));
* aWindowHandle; // Handle for the window object.
* ```
*
* A string can also be passed in instead of a function:
*
@ -130,7 +144,8 @@ export interface Page {
* const aHandle = await page.evaluateHandle('document'); // Handle for the 'document'
* ```
*
* [JSHandle] instances can be passed as an argument to the `page.evaluateHandle`:
* [JSHandle] instances can be passed as an argument to the
* [page.evaluateHandle()](https://github.com/microsoft/playwright/blob/master/docs/api.md#pageevaluatehandle):
*
* ```js
* const aHandle = await page.evaluateHandle(() => document.body);
@ -3190,25 +3205,21 @@ export interface Page {
* })();
* ```
*
* An example of getting text from an iframe element:
*
* ```js
* const frame = page.frames().find(frame => frame.name() === 'myframe');
* const text = await frame.$eval('.selector', element => element.textContent);
* console.log(text);
* ```
*
*/
export interface Frame {
/**
* Returns the return value of `pageFunction`
*
* If the function passed to the `frame.evaluate` returns a [Promise], then `frame.evaluate` would wait for the promise to
* resolve and return its value.
* If the function passed to the
* [frame.evaluate()](https://github.com/microsoft/playwright/blob/master/docs/api.md#frameevaluate) returns a [Promise],
* then [frame.evaluate()](https://github.com/microsoft/playwright/blob/master/docs/api.md#frameevaluate) would wait for
* the promise to resolve and return its value.
*
* If the function passed to the `frame.evaluate` returns a non-[Serializable] value, then `frame.evaluate` returns
* `undefined`. DevTools Protocol also supports transferring some additional values that are not serializable by `JSON`:
* `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
* If the function passed to the
* [frame.evaluate()](https://github.com/microsoft/playwright/blob/master/docs/api.md#frameevaluate) returns a
* non-[Serializable] value, then[ method: `Frame.evaluate`] returns `undefined`. DevTools Protocol also supports
* transferring some additional values that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and
* bigint literals.
*
* ```js
* const result = await frame.evaluate(([x, y]) => {
@ -3223,7 +3234,8 @@ export interface Frame {
* console.log(await frame.evaluate('1 + 2')); // prints "3"
* ```
*
* [ElementHandle] instances can be passed as an argument to the `frame.evaluate`:
* [ElementHandle] instances can be passed as an argument to the
* [frame.evaluate()](https://github.com/microsoft/playwright/blob/master/docs/api.md#frameevaluate):
*
* ```js
* const bodyHandle = await frame.$('body');
@ -3240,11 +3252,14 @@ export interface Frame {
/**
* Returns the return value of `pageFunction` as in-page object (JSHandle).
*
* The only difference between `frame.evaluate` and `frame.evaluateHandle` is that `frame.evaluateHandle` returns in-page
* object (JSHandle).
* The only difference between
* [frame.evaluate()](https://github.com/microsoft/playwright/blob/master/docs/api.md#frameevaluate) and
* [frame.evaluateHandle()](https://github.com/microsoft/playwright/blob/master/docs/api.md#frameevaluatehandle) is
* that[ method: Fframe.evaluateHandle`] returns in-page object (JSHandle).
*
* If the function, passed to the `frame.evaluateHandle`, returns a [Promise], then `frame.evaluateHandle` would wait for
* the promise to resolve and return its value.
* If the function, passed to the
* [frame.evaluateHandle()](https://github.com/microsoft/playwright/blob/master/docs/api.md#frameevaluatehandle), returns
* a [Promise], then[ method: Fframe.evaluateHandle`] would wait for the promise to resolve and return its value.
*
* ```js
* const aWindowHandle = await frame.evaluateHandle(() => Promise.resolve(window));
@ -3257,7 +3272,8 @@ export interface Frame {
* const aHandle = await frame.evaluateHandle('document'); // Handle for the 'document'.
* ```
*
* [JSHandle] instances can be passed as an argument to the `frame.evaluateHandle`:
* [JSHandle] instances can be passed as an argument to the
* [frame.evaluateHandle()](https://github.com/microsoft/playwright/blob/master/docs/api.md#frameevaluatehandle):
*
* ```js
* const aHandle = await frame.evaluateHandle(() => document.body);
@ -3387,17 +3403,15 @@ export interface Frame {
* This method works across navigations:
*
* ```js
* const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'.
* const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
*
* (async () => {
* const browser = await webkit.launch();
* const browser = await chromium.launch();
* const page = await browser.newPage();
* let currentURL;
* page.mainFrame()
* .waitForSelector('img')
* .then(() => console.log('First URL with image: ' + currentURL));
* for (currentURL of ['https://example.com', 'https://google.com', 'https://bbc.com']) {
* for (let currentURL of ['https://google.com', 'https://bbc.com']) {
* await page.goto(currentURL);
* const element = await page.mainFrame().waitForSelector('img');
* console.log('Loaded image: ' + await element.getAttribute('src'));
* }
* await browser.close();
* })();
@ -4424,8 +4438,8 @@ export interface Frame {
*
* ```js
* const [response] = await Promise.all([
* frame.waitForNavigation(), // Wait for the navigation to finish
* frame.click('a.my-link'), // Clicking the link will indirectly cause a navigation
* frame.waitForNavigation(), // The promise resolves after navigation has finished
* frame.click('a.delayed-navigation'), // Clicking the link will indirectly cause a navigation
* ]);
* ```
*
@ -5235,7 +5249,7 @@ export interface JSHandle<T = any> {
*
* ```js
* const tweetHandle = await page.$('.tweet .retweets');
* expect(await tweetHandle.evaluate((node, suffix) => node.innerText, ' retweets')).toBe('10 retweets');
* expect(await tweetHandle.evaluate(node => node.innerText)).toBe('10 retweets');
* ```
*
* @param pageFunction Function to be evaluated in browser context
@ -5926,16 +5940,13 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
*
* ```js
* // single selection matching the value
* handle.selectOption('blue');
* handle.selectOption('select#colors', 'blue');
*
* // single selection matching both the value and the label
* handle.selectOption({ label: 'Blue' });
* // single selection matching the label
* handle.selectOption('select#colors', { label: 'Blue' });
*
* // multiple selection
* handle.selectOption('red', 'green', 'blue');
*
* // multiple selection for blue, red and second option
* handle.selectOption({ value: 'blue' }, { index: 2 }, 'red');
* handle.selectOption('select#colors', ['red', 'green', 'blue']);
* ```
*
* @param values Options to select. If the `<select>` has the `multiple` attribute, all matching options are selected, otherwise only the first option matching one of the passed options is selected. String values are equivalent to `{value:'string'}`. Option
@ -8011,7 +8022,6 @@ export interface Dialog {
* ]);
* // wait for download to complete
* const path = await download.path();
* ...
* ```
*
* > NOTE: Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the
@ -8596,7 +8606,7 @@ export interface Request {
* ```js
* const [request] = await Promise.all([
* page.waitForEvent('requestfinished'),
* page.goto(httpsServer.EMPTY_PAGE)
* page.goto('http://example.com')
* ]);
* console.log(request.timing());
* ```

View file

@ -1,13 +1,8 @@
// @ts-check
const { outputHelp } = require("commander");
const fs = require("fs");
const { createImportSpecifier } = require("typescript");
const md = require("../markdown");
const inputFile = "docs/src/api/class-page.md";
const fileContent = fs.readFileSync(inputFile).toString();
const nodes = md.parse(fileContent);
/**
* @param {string[]} input
@ -99,11 +94,6 @@ function multiplyComment(spec) {
return children;
}
md.visitAll(nodes, node => {
if (node.children)
node.children = multiplyComment(node.children);
});
/**
* @param {string} name
*/
@ -112,5 +102,19 @@ function toSnakeCase(name) {
return name.replace(toSnakeCaseRegex, `_$1`).toLowerCase();
}
const out = md.render(nodes, 120);
fs.writeFileSync(inputFile, out);
for (const name of fs.readdirSync("docs/src")) {
if (!name.endsWith(".md"))
continue;
const inputFile = `docs/src/${name}`;
const fileContent = fs.readFileSync(inputFile).toString();
const nodes = md.parse(fileContent);
md.visitAll(nodes, node => {
if (node.children)
node.children = multiplyComment(node.children);
});
const out = md.render(nodes, 120);
fs.writeFileSync(inputFile, out);
}