playwright-ruby-client 0.0.8 → 1.58.1.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/AGENTS.md +4 -0
- data/CLAUDE/api_generation.md +28 -0
- data/CLAUDE/ci_expectations.md +23 -0
- data/CLAUDE/gem_release_flow.md +39 -0
- data/CLAUDE/past_upgrade_pr_patterns.md +42 -0
- data/CLAUDE/playwright_upgrade_workflow.md +35 -0
- data/CLAUDE/rspec_debugging.md +30 -0
- data/CLAUDE/unimplemented_examples.md +18 -0
- data/CLAUDE.md +32 -0
- data/CONTRIBUTING.md +5 -0
- data/README.md +60 -16
- data/documentation/README.md +33 -0
- data/documentation/babel.config.js +3 -0
- data/documentation/docs/api/api_request.md +7 -0
- data/documentation/docs/api/api_request_context.md +298 -0
- data/documentation/docs/api/api_response.md +114 -0
- data/documentation/docs/api/browser.md +237 -0
- data/documentation/docs/api/browser_context.md +503 -0
- data/documentation/docs/api/browser_type.md +184 -0
- data/documentation/docs/api/cdp_session.md +44 -0
- data/documentation/docs/api/clock.md +154 -0
- data/documentation/docs/api/console_message.md +85 -0
- data/documentation/docs/api/dialog.md +84 -0
- data/documentation/docs/api/download.md +111 -0
- data/documentation/docs/api/element_handle.md +694 -0
- data/documentation/docs/api/experimental/_category_.yml +3 -0
- data/documentation/docs/api/experimental/android.md +42 -0
- data/documentation/docs/api/experimental/android_device.md +109 -0
- data/documentation/docs/api/experimental/android_input.md +43 -0
- data/documentation/docs/api/experimental/android_socket.md +7 -0
- data/documentation/docs/api/experimental/android_web_view.md +7 -0
- data/documentation/docs/api/file_chooser.md +53 -0
- data/documentation/docs/api/frame.md +1218 -0
- data/documentation/docs/api/frame_locator.md +348 -0
- data/documentation/docs/api/js_handle.md +121 -0
- data/documentation/docs/api/keyboard.md +170 -0
- data/documentation/docs/api/locator.md +1495 -0
- data/documentation/docs/api/locator_assertions.md +827 -0
- data/documentation/docs/api/mouse.md +86 -0
- data/documentation/docs/api/page.md +1946 -0
- data/documentation/docs/api/page_assertions.md +65 -0
- data/documentation/docs/api/playwright.md +66 -0
- data/documentation/docs/api/request.md +255 -0
- data/documentation/docs/api/response.md +176 -0
- data/documentation/docs/api/route.md +205 -0
- data/documentation/docs/api/selectors.md +63 -0
- data/documentation/docs/api/touchscreen.md +22 -0
- data/documentation/docs/api/tracing.md +129 -0
- data/documentation/docs/api/web_socket.md +51 -0
- data/documentation/docs/api/worker.md +83 -0
- data/documentation/docs/article/api_coverage.mdx +11 -0
- data/documentation/docs/article/getting_started.md +161 -0
- data/documentation/docs/article/guides/_category_.yml +3 -0
- data/documentation/docs/article/guides/download_playwright_driver.md +55 -0
- data/documentation/docs/article/guides/inspector.md +31 -0
- data/documentation/docs/article/guides/launch_browser.md +121 -0
- data/documentation/docs/article/guides/playwright_on_alpine_linux.md +112 -0
- data/documentation/docs/article/guides/rails_integration.md +278 -0
- data/documentation/docs/article/guides/rails_integration_with_null_driver.md +145 -0
- data/documentation/docs/article/guides/recording_video.md +79 -0
- data/documentation/docs/article/guides/rspec_integration.md +59 -0
- data/documentation/docs/article/guides/semi_automation.md +71 -0
- data/documentation/docs/article/guides/use_storage_state.md +78 -0
- data/documentation/docs/include/api_coverage.md +671 -0
- data/documentation/docusaurus.config.js +114 -0
- data/documentation/package.json +39 -0
- data/documentation/sidebars.js +15 -0
- data/documentation/src/components/HomepageFeatures.js +61 -0
- data/documentation/src/components/HomepageFeatures.module.css +13 -0
- data/documentation/src/css/custom.css +44 -0
- data/documentation/src/pages/index.js +49 -0
- data/documentation/src/pages/index.module.css +41 -0
- data/documentation/src/pages/markdown-page.md +7 -0
- data/documentation/static/.nojekyll +0 -0
- data/documentation/static/img/playwright-logo.svg +9 -0
- data/documentation/static/img/playwright-ruby-client.png +0 -0
- data/documentation/static/img/undraw_dropdown_menu.svg +1 -0
- data/documentation/static/img/undraw_web_development.svg +1 -0
- data/documentation/static/img/undraw_windows.svg +1 -0
- data/documentation/yarn.lock +9005 -0
- data/lib/playwright/{input_types/android_input.rb → android_input_impl.rb} +5 -1
- data/lib/playwright/api_implementation.rb +18 -0
- data/lib/playwright/api_response_impl.rb +77 -0
- data/lib/playwright/channel.rb +62 -1
- data/lib/playwright/channel_owner.rb +70 -7
- data/lib/playwright/channel_owners/android.rb +16 -3
- data/lib/playwright/channel_owners/android_device.rb +22 -66
- data/lib/playwright/channel_owners/api_request_context.rb +247 -0
- data/lib/playwright/channel_owners/artifact.rb +40 -0
- data/lib/playwright/channel_owners/binding_call.rb +70 -0
- data/lib/playwright/channel_owners/browser.rb +114 -22
- data/lib/playwright/channel_owners/browser_context.rb +589 -15
- data/lib/playwright/channel_owners/browser_type.rb +90 -1
- data/lib/playwright/channel_owners/cdp_session.rb +19 -0
- data/lib/playwright/channel_owners/dialog.rb +32 -0
- data/lib/playwright/channel_owners/element_handle.rb +107 -43
- data/lib/playwright/channel_owners/fetch_request.rb +8 -0
- data/lib/playwright/channel_owners/frame.rb +334 -104
- data/lib/playwright/channel_owners/js_handle.rb +9 -13
- data/lib/playwright/channel_owners/local_utils.rb +82 -0
- data/lib/playwright/channel_owners/page.rb +778 -95
- data/lib/playwright/channel_owners/playwright.rb +25 -30
- data/lib/playwright/channel_owners/request.rb +120 -18
- data/lib/playwright/channel_owners/response.rb +113 -0
- data/lib/playwright/channel_owners/route.rb +181 -0
- data/lib/playwright/channel_owners/stream.rb +30 -0
- data/lib/playwright/channel_owners/tracing.rb +117 -0
- data/lib/playwright/channel_owners/web_socket.rb +96 -0
- data/lib/playwright/channel_owners/worker.rb +46 -0
- data/lib/playwright/channel_owners/writable_stream.rb +14 -0
- data/lib/playwright/clock_impl.rb +67 -0
- data/lib/playwright/connection.rb +111 -63
- data/lib/playwright/console_message_impl.rb +29 -0
- data/lib/playwright/download_impl.rb +32 -0
- data/lib/playwright/errors.rb +42 -5
- data/lib/playwright/event_emitter.rb +17 -3
- data/lib/playwright/event_emitter_proxy.rb +49 -0
- data/lib/playwright/events.rb +10 -5
- data/lib/playwright/file_chooser_impl.rb +24 -0
- data/lib/playwright/frame_locator_impl.rb +66 -0
- data/lib/playwright/har_router.rb +89 -0
- data/lib/playwright/http_headers.rb +14 -0
- data/lib/playwright/input_files.rb +102 -15
- data/lib/playwright/javascript/expression.rb +7 -11
- data/lib/playwright/javascript/regex.rb +23 -0
- data/lib/playwright/javascript/source_url.rb +16 -0
- data/lib/playwright/javascript/value_parser.rb +108 -19
- data/lib/playwright/javascript/value_serializer.rb +47 -8
- data/lib/playwright/javascript/visitor_info.rb +26 -0
- data/lib/playwright/javascript.rb +2 -10
- data/lib/playwright/{input_types/keyboard.rb → keyboard_impl.rb} +6 -2
- data/lib/playwright/locator_assertions_impl.rb +571 -0
- data/lib/playwright/locator_impl.rb +544 -0
- data/lib/playwright/locator_utils.rb +136 -0
- data/lib/playwright/mouse_impl.rb +57 -0
- data/lib/playwright/page_assertions_impl.rb +154 -0
- data/lib/playwright/playwright_api.rb +102 -30
- data/lib/playwright/raw_headers.rb +61 -0
- data/lib/playwright/route_handler.rb +78 -0
- data/lib/playwright/select_option_values.rb +34 -13
- data/lib/playwright/selectors_impl.rb +45 -0
- data/lib/playwright/test.rb +102 -0
- data/lib/playwright/timeout_settings.rb +9 -4
- data/lib/playwright/touchscreen_impl.rb +14 -0
- data/lib/playwright/transport.rb +61 -10
- data/lib/playwright/url_matcher.rb +24 -2
- data/lib/playwright/utils.rb +48 -13
- data/lib/playwright/version.rb +2 -1
- data/lib/playwright/video.rb +54 -0
- data/lib/playwright/waiter.rb +166 -0
- data/lib/playwright/web_socket_client.rb +167 -0
- data/lib/playwright/web_socket_transport.rb +116 -0
- data/lib/playwright.rb +188 -11
- data/lib/playwright_api/android.rb +46 -11
- data/lib/playwright_api/android_device.rb +182 -31
- data/lib/playwright_api/android_input.rb +22 -13
- data/lib/playwright_api/android_socket.rb +18 -0
- data/lib/playwright_api/android_web_view.rb +24 -0
- data/lib/playwright_api/api_request.rb +26 -0
- data/lib/playwright_api/api_request_context.rb +311 -0
- data/lib/playwright_api/api_response.rb +92 -0
- data/lib/playwright_api/browser.rb +116 -103
- data/lib/playwright_api/browser_context.rb +290 -389
- data/lib/playwright_api/browser_type.rb +96 -118
- data/lib/playwright_api/cdp_session.rb +36 -39
- data/lib/playwright_api/clock.rb +121 -0
- data/lib/playwright_api/console_message.rb +35 -19
- data/lib/playwright_api/dialog.rb +53 -50
- data/lib/playwright_api/download.rb +49 -43
- data/lib/playwright_api/element_handle.rb +354 -402
- data/lib/playwright_api/file_chooser.rb +15 -18
- data/lib/playwright_api/frame.rb +703 -603
- data/lib/playwright_api/frame_locator.rb +285 -0
- data/lib/playwright_api/js_handle.rb +50 -76
- data/lib/playwright_api/keyboard.rb +67 -146
- data/lib/playwright_api/locator.rb +1304 -0
- data/lib/playwright_api/locator_assertions.rb +704 -0
- data/lib/playwright_api/mouse.rb +23 -29
- data/lib/playwright_api/page.rb +1196 -1176
- data/lib/playwright_api/page_assertions.rb +60 -0
- data/lib/playwright_api/playwright.rb +54 -122
- data/lib/playwright_api/request.rb +112 -74
- data/lib/playwright_api/response.rb +92 -20
- data/lib/playwright_api/route.rb +152 -62
- data/lib/playwright_api/selectors.rb +47 -61
- data/lib/playwright_api/touchscreen.rb +8 -2
- data/lib/playwright_api/tracing.rb +128 -0
- data/lib/playwright_api/web_socket.rb +43 -5
- data/lib/playwright_api/worker.rb +74 -34
- data/playwright.gemspec +14 -9
- data/sig/playwright.rbs +658 -0
- metadata +216 -50
- data/docs/api_coverage.md +0 -354
- data/lib/playwright/channel_owners/chromium_browser.rb +0 -8
- data/lib/playwright/channel_owners/chromium_browser_context.rb +0 -8
- data/lib/playwright/channel_owners/console_message.rb +0 -21
- data/lib/playwright/channel_owners/firefox_browser.rb +0 -8
- data/lib/playwright/channel_owners/selectors.rb +0 -4
- data/lib/playwright/channel_owners/webkit_browser.rb +0 -8
- data/lib/playwright/input_type.rb +0 -19
- data/lib/playwright/input_types/mouse.rb +0 -4
- data/lib/playwright/input_types/touchscreen.rb +0 -4
- data/lib/playwright/javascript/function.rb +0 -67
- data/lib/playwright/wait_helper.rb +0 -73
- data/lib/playwright_api/accessibility.rb +0 -93
- data/lib/playwright_api/binding_call.rb +0 -23
- data/lib/playwright_api/chromium_browser_context.rb +0 -57
- data/lib/playwright_api/video.rb +0 -24
data/lib/playwright_api/page.rb
CHANGED
|
@@ -1,49 +1,15 @@
|
|
|
1
1
|
module Playwright
|
|
2
|
-
#
|
|
3
|
-
#
|
|
2
|
+
#
|
|
4
3
|
# Page provides methods to interact with a single tab in a `Browser`, or an
|
|
5
|
-
# [extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium. One
|
|
6
|
-
# instance might have multiple
|
|
7
|
-
#
|
|
4
|
+
# [extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium. One `Browser`
|
|
5
|
+
# instance might have multiple `Page` instances.
|
|
6
|
+
#
|
|
8
7
|
# This example creates a page, navigates it to a URL, and then saves a screenshot:
|
|
9
|
-
#
|
|
10
8
|
#
|
|
11
|
-
# ```js
|
|
12
|
-
# const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'.
|
|
13
|
-
#
|
|
14
|
-
# (async () => {
|
|
15
|
-
# const browser = await webkit.launch();
|
|
16
|
-
# const context = await browser.newContext();
|
|
17
|
-
# const page = await context.newPage();
|
|
18
|
-
# await page.goto('https://example.com');
|
|
19
|
-
# await page.screenshot({path: 'screenshot.png'});
|
|
20
|
-
# await browser.close();
|
|
21
|
-
# })();
|
|
22
|
-
# ```
|
|
23
|
-
#
|
|
24
|
-
# ```python async
|
|
25
|
-
# import asyncio
|
|
26
|
-
# from playwright.async_api import async_playwright
|
|
27
|
-
#
|
|
28
|
-
# async def run(playwright):
|
|
29
|
-
# webkit = playwright.webkit
|
|
30
|
-
# browser = await webkit.launch()
|
|
31
|
-
# context = await browser.new_context()
|
|
32
|
-
# page = await context.new_page()
|
|
33
|
-
# await page.goto("https://example.com")
|
|
34
|
-
# await page.screenshot(path="screenshot.png")
|
|
35
|
-
# await browser.close()
|
|
36
|
-
#
|
|
37
|
-
# async def main():
|
|
38
|
-
# async with async_playwright() as playwright:
|
|
39
|
-
# await run(playwright)
|
|
40
|
-
# asyncio.run(main())
|
|
41
|
-
# ```
|
|
42
|
-
#
|
|
43
9
|
# ```python sync
|
|
44
|
-
# from playwright.sync_api import sync_playwright
|
|
45
|
-
#
|
|
46
|
-
# def run(playwright):
|
|
10
|
+
# from playwright.sync_api import sync_playwright, Playwright
|
|
11
|
+
#
|
|
12
|
+
# def run(playwright: Playwright):
|
|
47
13
|
# webkit = playwright.webkit
|
|
48
14
|
# browser = webkit.launch()
|
|
49
15
|
# context = browser.new_context()
|
|
@@ -51,38 +17,23 @@ module Playwright
|
|
|
51
17
|
# page.goto("https://example.com")
|
|
52
18
|
# page.screenshot(path="screenshot.png")
|
|
53
19
|
# browser.close()
|
|
54
|
-
#
|
|
20
|
+
#
|
|
55
21
|
# with sync_playwright() as playwright:
|
|
56
22
|
# run(playwright)
|
|
57
23
|
# ```
|
|
58
|
-
#
|
|
24
|
+
#
|
|
59
25
|
# The Page class emits various events (described below) which can be handled using any of Node's native
|
|
60
26
|
# [`EventEmitter`](https://nodejs.org/api/events.html#events_class_eventemitter) methods, such as `on`, `once` or
|
|
61
27
|
# `removeListener`.
|
|
62
|
-
#
|
|
28
|
+
#
|
|
63
29
|
# This example logs a message for a single page `load` event:
|
|
64
|
-
#
|
|
65
30
|
#
|
|
66
|
-
# ```js
|
|
67
|
-
# page.once('load', () => console.log('Page loaded!'));
|
|
68
|
-
# ```
|
|
69
|
-
#
|
|
70
31
|
# ```py
|
|
71
32
|
# page.once("load", lambda: print("page loaded!"))
|
|
72
33
|
# ```
|
|
73
|
-
#
|
|
34
|
+
#
|
|
74
35
|
# To unsubscribe from events use the `removeListener` method:
|
|
75
|
-
#
|
|
76
36
|
#
|
|
77
|
-
# ```js
|
|
78
|
-
# function logRequest(interceptedRequest) {
|
|
79
|
-
# console.log('A request was made:', interceptedRequest.url());
|
|
80
|
-
# }
|
|
81
|
-
# page.on('request', logRequest);
|
|
82
|
-
# // Sometime later...
|
|
83
|
-
# page.removeListener('request', logRequest);
|
|
84
|
-
# ```
|
|
85
|
-
#
|
|
86
37
|
# ```py
|
|
87
38
|
# def log_request(intercepted_request):
|
|
88
39
|
# print("a request was made:", intercepted_request.url)
|
|
@@ -92,14 +43,10 @@ module Playwright
|
|
|
92
43
|
# ```
|
|
93
44
|
class Page < PlaywrightApi
|
|
94
45
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
# Browser-specific Coverage implementation, only available for Chromium atm. See
|
|
100
|
-
# `ChromiumCoverage`(#class-chromiumcoverage) for more details.
|
|
101
|
-
def coverage # property
|
|
102
|
-
raise NotImplementedError.new('coverage is not implemented yet.')
|
|
46
|
+
#
|
|
47
|
+
# Playwright has ability to mock clock and passage of time.
|
|
48
|
+
def clock # property
|
|
49
|
+
wrap_impl(@impl.clock)
|
|
103
50
|
end
|
|
104
51
|
|
|
105
52
|
def keyboard # property
|
|
@@ -110,172 +57,92 @@ module Playwright
|
|
|
110
57
|
wrap_impl(@impl.mouse)
|
|
111
58
|
end
|
|
112
59
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
# return value resolves to `null`.
|
|
119
|
-
#
|
|
120
|
-
# Shortcut for main frame's [`method: Frame.$`].
|
|
121
|
-
def query_selector(selector)
|
|
122
|
-
wrap_impl(@impl.query_selector(unwrap_impl(selector)))
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# The method finds all elements matching the specified selector within the page. If no elements match the selector, the
|
|
126
|
-
# return value resolves to `[]`.
|
|
127
|
-
#
|
|
128
|
-
# Shortcut for main frame's [`method: Frame.$$`].
|
|
129
|
-
def query_selector_all(selector)
|
|
130
|
-
wrap_impl(@impl.query_selector_all(unwrap_impl(selector)))
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# The method finds an element matching the specified selector within the page and passes it as a first argument to
|
|
134
|
-
# `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`.
|
|
135
|
-
#
|
|
136
|
-
# If `pageFunction` returns a [Promise], then [`method: Page.$eval`] would wait for the promise to resolve and return its
|
|
137
|
-
# value.
|
|
138
|
-
#
|
|
139
|
-
# Examples:
|
|
140
|
-
#
|
|
141
|
-
#
|
|
142
|
-
# ```js
|
|
143
|
-
# const searchValue = await page.$eval('#search', el => el.value);
|
|
144
|
-
# const preloadHref = await page.$eval('link[rel=preload]', el => el.href);
|
|
145
|
-
# const html = await page.$eval('.main-container', (e, suffix) => e.outerHTML + suffix, 'hello');
|
|
146
|
-
# ```
|
|
147
|
-
#
|
|
148
|
-
# ```python async
|
|
149
|
-
# search_value = await page.eval_on_selector("#search", "el => el.value")
|
|
150
|
-
# preload_href = await page.eval_on_selector("link[rel=preload]", "el => el.href")
|
|
151
|
-
# html = await page.eval_on_selector(".main-container", "(e, suffix) => e.outer_html + suffix", "hello")
|
|
152
|
-
# ```
|
|
153
|
-
#
|
|
154
|
-
# ```python sync
|
|
155
|
-
# search_value = page.eval_on_selector("#search", "el => el.value")
|
|
156
|
-
# preload_href = page.eval_on_selector("link[rel=preload]", "el => el.href")
|
|
157
|
-
# html = page.eval_on_selector(".main-container", "(e, suffix) => e.outer_html + suffix", "hello")
|
|
158
|
-
# ```
|
|
159
|
-
#
|
|
160
|
-
# Shortcut for main frame's [`method: Frame.$eval`].
|
|
161
|
-
def eval_on_selector(selector, pageFunction, arg: nil)
|
|
162
|
-
wrap_impl(@impl.eval_on_selector(unwrap_impl(selector), unwrap_impl(pageFunction), arg: unwrap_impl(arg)))
|
|
60
|
+
#
|
|
61
|
+
# API testing helper associated with this page. This method returns the same instance as
|
|
62
|
+
# [`property: BrowserContext.request`] on the page's context. See [`property: BrowserContext.request`] for more details.
|
|
63
|
+
def request # property
|
|
64
|
+
wrap_impl(@impl.request)
|
|
163
65
|
end
|
|
164
66
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
#
|
|
168
|
-
# If `pageFunction` returns a [Promise], then [`method: Page.$$eval`] would wait for the promise to resolve and return its
|
|
169
|
-
# value.
|
|
170
|
-
#
|
|
171
|
-
# Examples:
|
|
172
|
-
#
|
|
173
|
-
#
|
|
174
|
-
# ```js
|
|
175
|
-
# const divCounts = await page.$$eval('div', (divs, min) => divs.length >= min, 10);
|
|
176
|
-
# ```
|
|
177
|
-
#
|
|
178
|
-
# ```python async
|
|
179
|
-
# div_counts = await page.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
|
|
180
|
-
# ```
|
|
181
|
-
#
|
|
182
|
-
# ```python sync
|
|
183
|
-
# div_counts = page.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
|
|
184
|
-
# ```
|
|
185
|
-
def eval_on_selector_all(selector, pageFunction, arg: nil)
|
|
186
|
-
wrap_impl(@impl.eval_on_selector_all(unwrap_impl(selector), unwrap_impl(pageFunction), arg: unwrap_impl(arg)))
|
|
67
|
+
def touchscreen # property
|
|
68
|
+
wrap_impl(@impl.touchscreen)
|
|
187
69
|
end
|
|
188
70
|
|
|
71
|
+
#
|
|
189
72
|
# Adds a script which would be evaluated in one of the following scenarios:
|
|
190
73
|
# - Whenever the page is navigated.
|
|
191
|
-
# - Whenever the child frame is attached or navigated. In this case, the script is evaluated in the context of the newly
|
|
192
|
-
#
|
|
193
|
-
#
|
|
74
|
+
# - Whenever the child frame is attached or navigated. In this case, the script is evaluated in the context of the newly attached frame.
|
|
75
|
+
#
|
|
194
76
|
# The script is evaluated after the document was created but before any of its scripts were run. This is useful to amend
|
|
195
77
|
# the JavaScript environment, e.g. to seed `Math.random`.
|
|
196
|
-
#
|
|
197
|
-
# An example of overriding `Math.random` before the page loads:
|
|
198
|
-
#
|
|
199
78
|
#
|
|
200
|
-
#
|
|
201
|
-
#
|
|
202
|
-
# Math.random
|
|
203
|
-
# ```
|
|
204
|
-
#
|
|
79
|
+
# **Usage**
|
|
80
|
+
#
|
|
81
|
+
# An example of overriding `Math.random` before the page loads:
|
|
205
82
|
#
|
|
206
|
-
# ```js
|
|
207
|
-
# // In your playwright script, assuming the preload.js file is in same directory
|
|
208
|
-
# await page.addInitScript({ path: './preload.js' });
|
|
209
|
-
# ```
|
|
210
|
-
#
|
|
211
|
-
# ```python async
|
|
212
|
-
# # in your playwright script, assuming the preload.js file is in same directory
|
|
213
|
-
# await page.add_init_script(path="./preload.js")
|
|
214
|
-
# ```
|
|
215
|
-
#
|
|
216
83
|
# ```python sync
|
|
217
84
|
# # in your playwright script, assuming the preload.js file is in same directory
|
|
218
85
|
# page.add_init_script(path="./preload.js")
|
|
219
86
|
# ```
|
|
220
|
-
#
|
|
221
|
-
#
|
|
87
|
+
#
|
|
88
|
+
# **NOTE**: The order of evaluation of multiple scripts installed via [`method: BrowserContext.addInitScript`] and
|
|
222
89
|
# [`method: Page.addInitScript`] is not defined.
|
|
223
|
-
def add_init_script(
|
|
224
|
-
|
|
90
|
+
def add_init_script(path: nil, script: nil)
|
|
91
|
+
wrap_impl(@impl.add_init_script(path: unwrap_impl(path), script: unwrap_impl(script)))
|
|
225
92
|
end
|
|
226
93
|
|
|
94
|
+
#
|
|
227
95
|
# Adds a `<script>` tag into the page with the desired url or content. Returns the added tag when the script's onload
|
|
228
96
|
# fires or when the script content was injected into frame.
|
|
229
|
-
#
|
|
230
|
-
# Shortcut for main frame's [`method: Frame.addScriptTag`].
|
|
231
97
|
def add_script_tag(content: nil, path: nil, type: nil, url: nil)
|
|
232
98
|
wrap_impl(@impl.add_script_tag(content: unwrap_impl(content), path: unwrap_impl(path), type: unwrap_impl(type), url: unwrap_impl(url)))
|
|
233
99
|
end
|
|
234
100
|
|
|
101
|
+
#
|
|
235
102
|
# Adds a `<link rel="stylesheet">` tag into the page with the desired url or a `<style type="text/css">` tag with the
|
|
236
103
|
# content. Returns the added tag when the stylesheet's onload fires or when the CSS content was injected into frame.
|
|
237
|
-
#
|
|
238
|
-
# Shortcut for main frame's [`method: Frame.addStyleTag`].
|
|
239
104
|
def add_style_tag(content: nil, path: nil, url: nil)
|
|
240
105
|
wrap_impl(@impl.add_style_tag(content: unwrap_impl(content), path: unwrap_impl(path), url: unwrap_impl(url)))
|
|
241
106
|
end
|
|
242
107
|
|
|
108
|
+
#
|
|
243
109
|
# Brings page to front (activates tab).
|
|
244
110
|
def bring_to_front
|
|
245
|
-
|
|
111
|
+
wrap_impl(@impl.bring_to_front)
|
|
246
112
|
end
|
|
247
113
|
|
|
114
|
+
#
|
|
248
115
|
# This method checks an element matching `selector` by performing the following steps:
|
|
249
|
-
# 1. Find an element
|
|
250
|
-
# 1. Ensure that matched element is a checkbox or a radio input. If not, this method
|
|
251
|
-
#
|
|
252
|
-
# 1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the
|
|
253
|
-
# element is detached during the checks, the whole action is retried.
|
|
116
|
+
# 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
|
117
|
+
# 1. Ensure that matched element is a checkbox or a radio input. If not, this method throws. If the element is already checked, this method returns immediately.
|
|
118
|
+
# 1. Wait for [actionability](../actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
|
|
254
119
|
# 1. Scroll the element into view if needed.
|
|
255
120
|
# 1. Use [`property: Page.mouse`] to click in the center of the element.
|
|
256
|
-
# 1.
|
|
257
|
-
#
|
|
258
|
-
#
|
|
259
|
-
#
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
121
|
+
# 1. Ensure that the element is now checked. If not, this method throws.
|
|
122
|
+
#
|
|
123
|
+
# When all steps combined have not finished during the specified `timeout`, this method throws a
|
|
124
|
+
# `TimeoutError`. Passing zero timeout disables this.
|
|
125
|
+
def check(
|
|
126
|
+
selector,
|
|
127
|
+
force: nil,
|
|
128
|
+
noWaitAfter: nil,
|
|
129
|
+
position: nil,
|
|
130
|
+
strict: nil,
|
|
131
|
+
timeout: nil,
|
|
132
|
+
trial: nil)
|
|
133
|
+
wrap_impl(@impl.check(unwrap_impl(selector), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
|
|
265
134
|
end
|
|
266
135
|
|
|
136
|
+
#
|
|
267
137
|
# This method clicks an element matching `selector` by performing the following steps:
|
|
268
|
-
# 1. Find an element
|
|
269
|
-
# 1. Wait for [actionability](
|
|
270
|
-
# element is detached during the checks, the whole action is retried.
|
|
138
|
+
# 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
|
139
|
+
# 1. Wait for [actionability](../actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
|
|
271
140
|
# 1. Scroll the element into view if needed.
|
|
272
141
|
# 1. Use [`property: Page.mouse`] to click in the center of the element, or the specified `position`.
|
|
273
142
|
# 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
|
274
|
-
#
|
|
275
|
-
# When all steps combined have not finished during the specified `timeout`, this method
|
|
276
|
-
# Passing zero timeout disables this.
|
|
277
|
-
#
|
|
278
|
-
# Shortcut for main frame's [`method: Frame.click`].
|
|
143
|
+
#
|
|
144
|
+
# When all steps combined have not finished during the specified `timeout`, this method throws a
|
|
145
|
+
# `TimeoutError`. Passing zero timeout disables this.
|
|
279
146
|
def click(
|
|
280
147
|
selector,
|
|
281
148
|
button: nil,
|
|
@@ -285,46 +152,47 @@ module Playwright
|
|
|
285
152
|
modifiers: nil,
|
|
286
153
|
noWaitAfter: nil,
|
|
287
154
|
position: nil,
|
|
288
|
-
|
|
289
|
-
|
|
155
|
+
strict: nil,
|
|
156
|
+
timeout: nil,
|
|
157
|
+
trial: nil)
|
|
158
|
+
wrap_impl(@impl.click(unwrap_impl(selector), button: unwrap_impl(button), clickCount: unwrap_impl(clickCount), delay: unwrap_impl(delay), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
|
|
290
159
|
end
|
|
291
160
|
|
|
161
|
+
#
|
|
292
162
|
# If `runBeforeUnload` is `false`, does not run any unload handlers and waits for the page to be closed. If
|
|
293
163
|
# `runBeforeUnload` is `true` the method will run unload handlers, but will **not** wait for the page to close.
|
|
294
|
-
#
|
|
164
|
+
#
|
|
295
165
|
# By default, `page.close()` **does not** run `beforeunload` handlers.
|
|
296
|
-
#
|
|
297
|
-
#
|
|
298
|
-
# via [`event: Page.dialog`] event.
|
|
299
|
-
def close(runBeforeUnload: nil)
|
|
300
|
-
wrap_impl(@impl.close(runBeforeUnload: unwrap_impl(runBeforeUnload)))
|
|
166
|
+
#
|
|
167
|
+
# **NOTE**: if `runBeforeUnload` is passed as true, a `beforeunload` dialog might be summoned and should be handled
|
|
168
|
+
# manually via [`event: Page.dialog`] event.
|
|
169
|
+
def close(reason: nil, runBeforeUnload: nil)
|
|
170
|
+
wrap_impl(@impl.close(reason: unwrap_impl(reason), runBeforeUnload: unwrap_impl(runBeforeUnload)))
|
|
301
171
|
end
|
|
302
172
|
|
|
173
|
+
#
|
|
303
174
|
# Gets the full HTML contents of the page, including the doctype.
|
|
304
175
|
def content
|
|
305
176
|
wrap_impl(@impl.content)
|
|
306
177
|
end
|
|
307
178
|
|
|
179
|
+
#
|
|
308
180
|
# Get the browser context that the page belongs to.
|
|
309
181
|
def context
|
|
310
182
|
wrap_impl(@impl.context)
|
|
311
183
|
end
|
|
312
184
|
|
|
185
|
+
#
|
|
313
186
|
# This method double clicks an element matching `selector` by performing the following steps:
|
|
314
|
-
# 1. Find an element
|
|
315
|
-
# 1. Wait for [actionability](
|
|
316
|
-
# element is detached during the checks, the whole action is retried.
|
|
187
|
+
# 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
|
188
|
+
# 1. Wait for [actionability](../actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
|
|
317
189
|
# 1. Scroll the element into view if needed.
|
|
318
190
|
# 1. Use [`property: Page.mouse`] to double click in the center of the element, or the specified `position`.
|
|
319
|
-
#
|
|
320
|
-
#
|
|
321
|
-
#
|
|
322
|
-
#
|
|
323
|
-
#
|
|
324
|
-
#
|
|
325
|
-
# > NOTE: `page.dblclick()` dispatches two `click` events and a single `dblclick` event.
|
|
326
|
-
#
|
|
327
|
-
# Shortcut for main frame's [`method: Frame.dblclick`].
|
|
191
|
+
#
|
|
192
|
+
# When all steps combined have not finished during the specified `timeout`, this method throws a
|
|
193
|
+
# `TimeoutError`. Passing zero timeout disables this.
|
|
194
|
+
#
|
|
195
|
+
# **NOTE**: `page.dblclick()` dispatches two `click` events and a single `dblclick` event.
|
|
328
196
|
def dblclick(
|
|
329
197
|
selector,
|
|
330
198
|
button: nil,
|
|
@@ -333,366 +201,255 @@ module Playwright
|
|
|
333
201
|
modifiers: nil,
|
|
334
202
|
noWaitAfter: nil,
|
|
335
203
|
position: nil,
|
|
336
|
-
|
|
337
|
-
|
|
204
|
+
strict: nil,
|
|
205
|
+
timeout: nil,
|
|
206
|
+
trial: nil)
|
|
207
|
+
wrap_impl(@impl.dblclick(unwrap_impl(selector), button: unwrap_impl(button), delay: unwrap_impl(delay), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
|
|
338
208
|
end
|
|
339
209
|
|
|
340
|
-
#
|
|
341
|
-
#
|
|
210
|
+
#
|
|
211
|
+
# The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the element, `click`
|
|
212
|
+
# is dispatched. This is equivalent to calling
|
|
342
213
|
# [element.click()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click).
|
|
343
|
-
#
|
|
344
214
|
#
|
|
345
|
-
#
|
|
346
|
-
#
|
|
347
|
-
# ```
|
|
348
|
-
#
|
|
349
|
-
# ```python async
|
|
350
|
-
# await page.dispatch_event("button#submit", "click")
|
|
351
|
-
# ```
|
|
352
|
-
#
|
|
215
|
+
# **Usage**
|
|
216
|
+
#
|
|
353
217
|
# ```python sync
|
|
354
218
|
# page.dispatch_event("button#submit", "click")
|
|
355
219
|
# ```
|
|
356
|
-
#
|
|
357
|
-
# Under the hood, it creates an instance of an event based on the given `type`, initializes it with
|
|
358
|
-
# and dispatches it on the element. Events are `composed`, `cancelable` and bubble by
|
|
359
|
-
#
|
|
360
|
-
#
|
|
220
|
+
#
|
|
221
|
+
# Under the hood, it creates an instance of an event based on the given `type`, initializes it with
|
|
222
|
+
# `eventInit` properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by
|
|
223
|
+
# default.
|
|
224
|
+
#
|
|
225
|
+
# Since `eventInit` is event-specific, please refer to the events documentation for the lists of initial
|
|
226
|
+
# properties:
|
|
227
|
+
# - [DeviceMotionEvent](https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent/DeviceMotionEvent)
|
|
228
|
+
# - [DeviceOrientationEvent](https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent/DeviceOrientationEvent)
|
|
361
229
|
# - [DragEvent](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/DragEvent)
|
|
230
|
+
# - [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event/Event)
|
|
362
231
|
# - [FocusEvent](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/FocusEvent)
|
|
363
232
|
# - [KeyboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent)
|
|
364
233
|
# - [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent)
|
|
365
234
|
# - [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/PointerEvent)
|
|
366
235
|
# - [TouchEvent](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/TouchEvent)
|
|
367
|
-
# - [
|
|
368
|
-
#
|
|
236
|
+
# - [WheelEvent](https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/WheelEvent)
|
|
237
|
+
#
|
|
369
238
|
# You can also specify `JSHandle` as the property value if you want live objects to be passed into the event:
|
|
370
|
-
#
|
|
371
239
|
#
|
|
372
|
-
# ```js
|
|
373
|
-
# // Note you can only create DataTransfer in Chromium and Firefox
|
|
374
|
-
# const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
|
|
375
|
-
# await page.dispatchEvent('#source', 'dragstart', { dataTransfer });
|
|
376
|
-
# ```
|
|
377
|
-
#
|
|
378
|
-
# ```python async
|
|
379
|
-
# # note you can only create data_transfer in chromium and firefox
|
|
380
|
-
# data_transfer = await page.evaluate_handle("new DataTransfer()")
|
|
381
|
-
# await page.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
|
|
382
|
-
# ```
|
|
383
|
-
#
|
|
384
240
|
# ```python sync
|
|
385
241
|
# # note you can only create data_transfer in chromium and firefox
|
|
386
242
|
# data_transfer = page.evaluate_handle("new DataTransfer()")
|
|
387
243
|
# page.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
|
|
388
244
|
# ```
|
|
389
|
-
def dispatch_event(
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
#
|
|
399
|
-
#
|
|
400
|
-
#
|
|
401
|
-
#
|
|
402
|
-
#
|
|
403
|
-
#
|
|
404
|
-
#
|
|
405
|
-
#
|
|
406
|
-
#
|
|
407
|
-
#
|
|
408
|
-
#
|
|
409
|
-
#
|
|
410
|
-
#
|
|
411
|
-
#
|
|
412
|
-
#
|
|
413
|
-
#
|
|
414
|
-
# ```
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
#
|
|
430
|
-
#
|
|
431
|
-
#
|
|
432
|
-
#
|
|
245
|
+
def dispatch_event(
|
|
246
|
+
selector,
|
|
247
|
+
type,
|
|
248
|
+
eventInit: nil,
|
|
249
|
+
strict: nil,
|
|
250
|
+
timeout: nil)
|
|
251
|
+
wrap_impl(@impl.dispatch_event(unwrap_impl(selector), unwrap_impl(type), eventInit: unwrap_impl(eventInit), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
#
|
|
255
|
+
# This method drags the source element to the target element.
|
|
256
|
+
# It will first move to the source element, perform a `mousedown`,
|
|
257
|
+
# then move to the target element and perform a `mouseup`.
|
|
258
|
+
#
|
|
259
|
+
# **Usage**
|
|
260
|
+
#
|
|
261
|
+
# ```python sync
|
|
262
|
+
# page.drag_and_drop("#source", "#target")
|
|
263
|
+
# # or specify exact positions relative to the top-left corners of the elements:
|
|
264
|
+
# page.drag_and_drop(
|
|
265
|
+
# "#source",
|
|
266
|
+
# "#target",
|
|
267
|
+
# source_position={"x": 34, "y": 7},
|
|
268
|
+
# target_position={"x": 10, "y": 20}
|
|
269
|
+
# )
|
|
270
|
+
# ```
|
|
271
|
+
def drag_and_drop(
|
|
272
|
+
source,
|
|
273
|
+
target,
|
|
274
|
+
force: nil,
|
|
275
|
+
noWaitAfter: nil,
|
|
276
|
+
sourcePosition: nil,
|
|
277
|
+
steps: nil,
|
|
278
|
+
strict: nil,
|
|
279
|
+
targetPosition: nil,
|
|
280
|
+
timeout: nil,
|
|
281
|
+
trial: nil)
|
|
282
|
+
wrap_impl(@impl.drag_and_drop(unwrap_impl(source), unwrap_impl(target), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), sourcePosition: unwrap_impl(sourcePosition), steps: unwrap_impl(steps), strict: unwrap_impl(strict), targetPosition: unwrap_impl(targetPosition), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
#
|
|
286
|
+
# This method changes the `CSS media type` through the `media` argument, and/or the `'prefers-colors-scheme'` media feature, using the `colorScheme` argument.
|
|
287
|
+
#
|
|
288
|
+
# **Usage**
|
|
289
|
+
#
|
|
433
290
|
# ```python sync
|
|
434
291
|
# page.evaluate("matchMedia('screen').matches")
|
|
435
292
|
# # → True
|
|
436
293
|
# page.evaluate("matchMedia('print').matches")
|
|
437
294
|
# # → False
|
|
438
|
-
#
|
|
295
|
+
#
|
|
439
296
|
# page.emulate_media(media="print")
|
|
440
297
|
# page.evaluate("matchMedia('screen').matches")
|
|
441
298
|
# # → False
|
|
442
299
|
# page.evaluate("matchMedia('print').matches")
|
|
443
300
|
# # → True
|
|
444
|
-
#
|
|
301
|
+
#
|
|
445
302
|
# page.emulate_media()
|
|
446
303
|
# page.evaluate("matchMedia('screen').matches")
|
|
447
304
|
# # → True
|
|
448
305
|
# page.evaluate("matchMedia('print').matches")
|
|
449
306
|
# # → False
|
|
450
307
|
# ```
|
|
451
|
-
#
|
|
452
|
-
#
|
|
453
|
-
# ```js
|
|
454
|
-
# await page.emulateMedia({ colorScheme: 'dark' });
|
|
455
|
-
# await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches);
|
|
456
|
-
# // → true
|
|
457
|
-
# await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches);
|
|
458
|
-
# // → false
|
|
459
|
-
# await page.evaluate(() => matchMedia('(prefers-color-scheme: no-preference)').matches);
|
|
460
|
-
# // → false
|
|
461
|
-
# ```
|
|
462
|
-
#
|
|
463
|
-
# ```python async
|
|
464
|
-
# await page.emulate_media(color_scheme="dark")
|
|
465
|
-
# await page.evaluate("matchMedia('(prefers-color-scheme: dark)').matches")
|
|
466
|
-
# # → True
|
|
467
|
-
# await page.evaluate("matchMedia('(prefers-color-scheme: light)').matches")
|
|
468
|
-
# # → False
|
|
469
|
-
# await page.evaluate("matchMedia('(prefers-color-scheme: no-preference)').matches")
|
|
470
|
-
# # → False
|
|
471
|
-
# ```
|
|
472
|
-
#
|
|
308
|
+
#
|
|
473
309
|
# ```python sync
|
|
474
310
|
# page.emulate_media(color_scheme="dark")
|
|
475
311
|
# page.evaluate("matchMedia('(prefers-color-scheme: dark)').matches")
|
|
476
312
|
# # → True
|
|
477
313
|
# page.evaluate("matchMedia('(prefers-color-scheme: light)').matches")
|
|
478
314
|
# # → False
|
|
479
|
-
# page.evaluate("matchMedia('(prefers-color-scheme: no-preference)').matches")
|
|
480
315
|
# ```
|
|
481
|
-
def emulate_media(
|
|
482
|
-
|
|
316
|
+
def emulate_media(
|
|
317
|
+
colorScheme: nil,
|
|
318
|
+
contrast: nil,
|
|
319
|
+
forcedColors: nil,
|
|
320
|
+
media: nil,
|
|
321
|
+
reducedMotion: nil)
|
|
322
|
+
wrap_impl(@impl.emulate_media(colorScheme: unwrap_impl(colorScheme), contrast: unwrap_impl(contrast), forcedColors: unwrap_impl(forcedColors), media: unwrap_impl(media), reducedMotion: unwrap_impl(reducedMotion)))
|
|
483
323
|
end
|
|
484
324
|
|
|
485
|
-
#
|
|
486
|
-
#
|
|
487
|
-
# If
|
|
488
|
-
#
|
|
489
|
-
#
|
|
490
|
-
# If
|
|
491
|
-
#
|
|
492
|
-
#
|
|
493
|
-
#
|
|
494
|
-
#
|
|
495
|
-
#
|
|
496
|
-
#
|
|
497
|
-
#
|
|
498
|
-
#
|
|
499
|
-
# return Promise.resolve(x * y);
|
|
500
|
-
# }, [7, 8]);
|
|
501
|
-
# console.log(result); // prints "56"
|
|
325
|
+
#
|
|
326
|
+
# The method finds an element matching the specified selector within the page and passes it as a first argument to
|
|
327
|
+
# `expression`. If no elements match the selector, the method throws an error. Returns the value of
|
|
328
|
+
# `expression`.
|
|
329
|
+
#
|
|
330
|
+
# If `expression` returns a [Promise], then [`method: Page.evalOnSelector`] would wait for the promise to resolve and
|
|
331
|
+
# return its value.
|
|
332
|
+
#
|
|
333
|
+
# **Usage**
|
|
334
|
+
#
|
|
335
|
+
# ```python sync
|
|
336
|
+
# search_value = page.eval_on_selector("#search", "el => el.value")
|
|
337
|
+
# preload_href = page.eval_on_selector("link[rel=preload]", "el => el.href")
|
|
338
|
+
# html = page.eval_on_selector(".main-container", "(e, suffix) => e.outer_html + suffix", "hello")
|
|
502
339
|
# ```
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
340
|
+
def eval_on_selector(selector, expression, arg: nil, strict: nil)
|
|
341
|
+
wrap_impl(@impl.eval_on_selector(unwrap_impl(selector), unwrap_impl(expression), arg: unwrap_impl(arg), strict: unwrap_impl(strict)))
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
#
|
|
345
|
+
# The method finds all elements matching the specified selector within the page and passes an array of matched elements as
|
|
346
|
+
# a first argument to `expression`. Returns the result of `expression` invocation.
|
|
347
|
+
#
|
|
348
|
+
# If `expression` returns a [Promise], then [`method: Page.evalOnSelectorAll`] would wait for the promise to resolve and
|
|
349
|
+
# return its value.
|
|
350
|
+
#
|
|
351
|
+
# **Usage**
|
|
352
|
+
#
|
|
353
|
+
# ```python sync
|
|
354
|
+
# div_counts = page.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
|
|
507
355
|
# ```
|
|
508
|
-
|
|
356
|
+
def eval_on_selector_all(selector, expression, arg: nil)
|
|
357
|
+
wrap_impl(@impl.eval_on_selector_all(unwrap_impl(selector), unwrap_impl(expression), arg: unwrap_impl(arg)))
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
#
|
|
361
|
+
# Returns the value of the `expression` invocation.
|
|
362
|
+
#
|
|
363
|
+
# If the function passed to the [`method: Page.evaluate`] returns a [Promise], then [`method: Page.evaluate`] would wait
|
|
364
|
+
# for the promise to resolve and return its value.
|
|
365
|
+
#
|
|
366
|
+
# If the function passed to the [`method: Page.evaluate`] returns a non-[Serializable] value, then
|
|
367
|
+
# [`method: Page.evaluate`] resolves to `undefined`. Playwright also supports transferring some
|
|
368
|
+
# additional values that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`.
|
|
369
|
+
#
|
|
370
|
+
# **Usage**
|
|
371
|
+
#
|
|
372
|
+
# Passing argument to `expression`:
|
|
373
|
+
#
|
|
509
374
|
# ```python sync
|
|
510
375
|
# result = page.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
|
|
511
376
|
# print(result) # prints "56"
|
|
512
377
|
# ```
|
|
513
|
-
#
|
|
378
|
+
#
|
|
514
379
|
# A string can also be passed in instead of a function:
|
|
515
|
-
#
|
|
516
380
|
#
|
|
517
|
-
# ```js
|
|
518
|
-
# console.log(await page.evaluate('1 + 2')); // prints "3"
|
|
519
|
-
# const x = 10;
|
|
520
|
-
# console.log(await page.evaluate(`1 + ${x}`)); // prints "11"
|
|
521
|
-
# ```
|
|
522
|
-
#
|
|
523
|
-
# ```python async
|
|
524
|
-
# print(await page.evaluate("1 + 2")) # prints "3"
|
|
525
|
-
# x = 10
|
|
526
|
-
# print(await page.evaluate(f"1 + {x}")) # prints "11"
|
|
527
|
-
# ```
|
|
528
|
-
#
|
|
529
381
|
# ```python sync
|
|
530
382
|
# print(page.evaluate("1 + 2")) # prints "3"
|
|
531
383
|
# x = 10
|
|
532
384
|
# print(page.evaluate(f"1 + {x}")) # prints "11"
|
|
533
385
|
# ```
|
|
534
|
-
#
|
|
386
|
+
#
|
|
535
387
|
# `ElementHandle` instances can be passed as an argument to the [`method: Page.evaluate`]:
|
|
536
|
-
#
|
|
537
388
|
#
|
|
538
|
-
# ```js
|
|
539
|
-
# const bodyHandle = await page.$('body');
|
|
540
|
-
# const html = await page.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']);
|
|
541
|
-
# await bodyHandle.dispose();
|
|
542
|
-
# ```
|
|
543
|
-
#
|
|
544
|
-
# ```python async
|
|
545
|
-
# body_handle = await page.query_selector("body")
|
|
546
|
-
# html = await page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
|
|
547
|
-
# await body_handle.dispose()
|
|
548
|
-
# ```
|
|
549
|
-
#
|
|
550
389
|
# ```python sync
|
|
551
|
-
# body_handle = page.
|
|
390
|
+
# body_handle = page.evaluate("document.body")
|
|
552
391
|
# html = page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
|
|
553
392
|
# body_handle.dispose()
|
|
554
393
|
# ```
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
#
|
|
562
|
-
#
|
|
563
|
-
#
|
|
564
|
-
# [`method: Page.evaluateHandle`] returns
|
|
565
|
-
#
|
|
566
|
-
#
|
|
567
|
-
#
|
|
568
|
-
#
|
|
569
|
-
#
|
|
570
|
-
# ```js
|
|
571
|
-
# const aWindowHandle = await page.evaluateHandle(() => Promise.resolve(window));
|
|
572
|
-
# aWindowHandle; // Handle for the window object.
|
|
573
|
-
# ```
|
|
574
|
-
#
|
|
575
|
-
# ```python async
|
|
576
|
-
# # FIXME
|
|
577
|
-
# a_window_handle = await page.evaluate_handle("Promise.resolve(window)")
|
|
578
|
-
# a_window_handle # handle for the window object.
|
|
579
|
-
# ```
|
|
580
|
-
#
|
|
394
|
+
def evaluate(expression, arg: nil)
|
|
395
|
+
wrap_impl(@impl.evaluate(unwrap_impl(expression), arg: unwrap_impl(arg)))
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
#
|
|
399
|
+
# Returns the value of the `expression` invocation as a `JSHandle`.
|
|
400
|
+
#
|
|
401
|
+
# The only difference between [`method: Page.evaluate`] and [`method: Page.evaluateHandle`] is that [`method: Page.evaluateHandle`] returns `JSHandle`.
|
|
402
|
+
#
|
|
403
|
+
# If the function passed to the [`method: Page.evaluateHandle`] returns a [Promise], then [`method: Page.evaluateHandle`] would wait for the
|
|
404
|
+
# promise to resolve and return its value.
|
|
405
|
+
#
|
|
406
|
+
# **Usage**
|
|
407
|
+
#
|
|
581
408
|
# ```python sync
|
|
582
409
|
# a_window_handle = page.evaluate_handle("Promise.resolve(window)")
|
|
583
410
|
# a_window_handle # handle for the window object.
|
|
584
411
|
# ```
|
|
585
|
-
#
|
|
412
|
+
#
|
|
586
413
|
# A string can also be passed in instead of a function:
|
|
587
|
-
#
|
|
588
414
|
#
|
|
589
|
-
# ```js
|
|
590
|
-
# const aHandle = await page.evaluateHandle('document'); // Handle for the 'document'
|
|
591
|
-
# ```
|
|
592
|
-
#
|
|
593
|
-
# ```python async
|
|
594
|
-
# a_handle = await page.evaluate_handle("document") # handle for the "document"
|
|
595
|
-
# ```
|
|
596
|
-
#
|
|
597
415
|
# ```python sync
|
|
598
416
|
# a_handle = page.evaluate_handle("document") # handle for the "document"
|
|
599
417
|
# ```
|
|
600
|
-
#
|
|
418
|
+
#
|
|
601
419
|
# `JSHandle` instances can be passed as an argument to the [`method: Page.evaluateHandle`]:
|
|
602
|
-
#
|
|
603
420
|
#
|
|
604
|
-
# ```js
|
|
605
|
-
# const aHandle = await page.evaluateHandle(() => document.body);
|
|
606
|
-
# const resultHandle = await page.evaluateHandle(body => body.innerHTML, aHandle);
|
|
607
|
-
# console.log(await resultHandle.jsonValue());
|
|
608
|
-
# await resultHandle.dispose();
|
|
609
|
-
# ```
|
|
610
|
-
#
|
|
611
|
-
# ```python async
|
|
612
|
-
# a_handle = await page.evaluate_handle("document.body")
|
|
613
|
-
# result_handle = await page.evaluate_handle("body => body.innerHTML", a_handle)
|
|
614
|
-
# print(await result_handle.json_value())
|
|
615
|
-
# await result_handle.dispose()
|
|
616
|
-
# ```
|
|
617
|
-
#
|
|
618
421
|
# ```python sync
|
|
619
422
|
# a_handle = page.evaluate_handle("document.body")
|
|
620
423
|
# result_handle = page.evaluate_handle("body => body.innerHTML", a_handle)
|
|
621
424
|
# print(result_handle.json_value())
|
|
622
425
|
# result_handle.dispose()
|
|
623
426
|
# ```
|
|
624
|
-
def evaluate_handle(
|
|
625
|
-
wrap_impl(@impl.evaluate_handle(unwrap_impl(
|
|
427
|
+
def evaluate_handle(expression, arg: nil)
|
|
428
|
+
wrap_impl(@impl.evaluate_handle(unwrap_impl(expression), arg: unwrap_impl(arg)))
|
|
626
429
|
end
|
|
627
430
|
|
|
628
|
-
#
|
|
629
|
-
#
|
|
630
|
-
# a [Promise]
|
|
631
|
-
#
|
|
632
|
-
#
|
|
633
|
-
#
|
|
634
|
-
#
|
|
431
|
+
#
|
|
432
|
+
# The method adds a function called `name` on the `window` object of every frame in this page. When called, the
|
|
433
|
+
# function executes `callback` and returns a [Promise] which resolves to the return value of `callback`.
|
|
434
|
+
# If the `callback` returns a [Promise], it will be awaited.
|
|
435
|
+
#
|
|
436
|
+
# The first argument of the `callback` function contains information about the caller: `{ browserContext:
|
|
437
|
+
# BrowserContext, page: Page, frame: Frame }`.
|
|
438
|
+
#
|
|
635
439
|
# See [`method: BrowserContext.exposeBinding`] for the context-wide version.
|
|
636
|
-
#
|
|
637
|
-
#
|
|
638
|
-
#
|
|
440
|
+
#
|
|
441
|
+
# **NOTE**: Functions installed via [`method: Page.exposeBinding`] survive navigations.
|
|
442
|
+
#
|
|
443
|
+
# **Usage**
|
|
444
|
+
#
|
|
639
445
|
# An example of exposing page URL to all frames in a page:
|
|
640
|
-
#
|
|
641
|
-
#
|
|
642
|
-
# ```js
|
|
643
|
-
# const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'.
|
|
644
|
-
#
|
|
645
|
-
# (async () => {
|
|
646
|
-
# const browser = await webkit.launch({ headless: false });
|
|
647
|
-
# const context = await browser.newContext();
|
|
648
|
-
# const page = await context.newPage();
|
|
649
|
-
# await page.exposeBinding('pageURL', ({ page }) => page.url());
|
|
650
|
-
# await page.setContent(`
|
|
651
|
-
# <script>
|
|
652
|
-
# async function onClick() {
|
|
653
|
-
# document.querySelector('div').textContent = await window.pageURL();
|
|
654
|
-
# }
|
|
655
|
-
# </script>
|
|
656
|
-
# <button onclick="onClick()">Click me</button>
|
|
657
|
-
# <div></div>
|
|
658
|
-
# `);
|
|
659
|
-
# await page.click('button');
|
|
660
|
-
# })();
|
|
661
|
-
# ```
|
|
662
|
-
#
|
|
663
|
-
# ```python async
|
|
664
|
-
# import asyncio
|
|
665
|
-
# from playwright.async_api import async_playwright
|
|
666
|
-
#
|
|
667
|
-
# async def run(playwright):
|
|
668
|
-
# webkit = playwright.webkit
|
|
669
|
-
# browser = await webkit.launch(headless=false)
|
|
670
|
-
# context = await browser.new_context()
|
|
671
|
-
# page = await context.new_page()
|
|
672
|
-
# await page.expose_binding("pageURL", lambda source: source["page"].url)
|
|
673
|
-
# await page.set_content("""
|
|
674
|
-
# <script>
|
|
675
|
-
# async function onClick() {
|
|
676
|
-
# document.querySelector('div').textContent = await window.pageURL();
|
|
677
|
-
# }
|
|
678
|
-
# </script>
|
|
679
|
-
# <button onclick="onClick()">Click me</button>
|
|
680
|
-
# <div></div>
|
|
681
|
-
# """)
|
|
682
|
-
# await page.click("button")
|
|
683
|
-
#
|
|
684
|
-
# async def main():
|
|
685
|
-
# async with async_playwright() as playwright:
|
|
686
|
-
# await run(playwright)
|
|
687
|
-
# asyncio.run(main())
|
|
688
|
-
# ```
|
|
689
|
-
#
|
|
446
|
+
#
|
|
690
447
|
# ```python sync
|
|
691
|
-
# from playwright.sync_api import sync_playwright
|
|
692
|
-
#
|
|
693
|
-
# def run(playwright):
|
|
448
|
+
# from playwright.sync_api import sync_playwright, Playwright
|
|
449
|
+
#
|
|
450
|
+
# def run(playwright: Playwright):
|
|
694
451
|
# webkit = playwright.webkit
|
|
695
|
-
# browser = webkit.launch(headless=
|
|
452
|
+
# browser = webkit.launch(headless=False)
|
|
696
453
|
# context = browser.new_context()
|
|
697
454
|
# page = context.new_page()
|
|
698
455
|
# page.expose_binding("pageURL", lambda source: source["page"].url)
|
|
@@ -706,369 +463,544 @@ module Playwright
|
|
|
706
463
|
# <div></div>
|
|
707
464
|
# """)
|
|
708
465
|
# page.click("button")
|
|
709
|
-
#
|
|
466
|
+
#
|
|
710
467
|
# with sync_playwright() as playwright:
|
|
711
468
|
# run(playwright)
|
|
712
469
|
# ```
|
|
713
|
-
#
|
|
714
|
-
# An example of passing an element handle:
|
|
715
|
-
#
|
|
716
|
-
#
|
|
717
|
-
# ```js
|
|
718
|
-
# await page.exposeBinding('clicked', async (source, element) => {
|
|
719
|
-
# console.log(await element.textContent());
|
|
720
|
-
# }, { handle: true });
|
|
721
|
-
# await page.setContent(`
|
|
722
|
-
# <script>
|
|
723
|
-
# document.addEventListener('click', event => window.clicked(event.target));
|
|
724
|
-
# </script>
|
|
725
|
-
# <div>Click me</div>
|
|
726
|
-
# <div>Or click me</div>
|
|
727
|
-
# `);
|
|
728
|
-
# ```
|
|
729
|
-
#
|
|
730
|
-
# ```python async
|
|
731
|
-
# async def print(source, element):
|
|
732
|
-
# print(await element.text_content())
|
|
733
|
-
#
|
|
734
|
-
# await page.expose_binding("clicked", print, handle=true)
|
|
735
|
-
# await page.set_content("""
|
|
736
|
-
# <script>
|
|
737
|
-
# document.addEventListener('click', event => window.clicked(event.target));
|
|
738
|
-
# </script>
|
|
739
|
-
# <div>Click me</div>
|
|
740
|
-
# <div>Or click me</div>
|
|
741
|
-
# """)
|
|
742
|
-
# ```
|
|
743
|
-
#
|
|
744
|
-
# ```python sync
|
|
745
|
-
# def print(source, element):
|
|
746
|
-
# print(element.text_content())
|
|
747
|
-
#
|
|
748
|
-
# page.expose_binding("clicked", print, handle=true)
|
|
749
|
-
# page.set_content("""
|
|
750
|
-
# <script>
|
|
751
|
-
# document.addEventListener('click', event => window.clicked(event.target));
|
|
752
|
-
# </script>
|
|
753
|
-
# <div>Click me</div>
|
|
754
|
-
# <div>Or click me</div>
|
|
755
|
-
# """)
|
|
756
|
-
# ```
|
|
757
470
|
def expose_binding(name, callback, handle: nil)
|
|
758
|
-
|
|
471
|
+
wrap_impl(@impl.expose_binding(unwrap_impl(name), unwrap_impl(callback), handle: unwrap_impl(handle)))
|
|
759
472
|
end
|
|
760
473
|
|
|
761
|
-
#
|
|
762
|
-
#
|
|
763
|
-
#
|
|
474
|
+
#
|
|
475
|
+
# The method adds a function called `name` on the `window` object of every frame in the page. When called, the
|
|
476
|
+
# function executes `callback` and returns a [Promise] which resolves to the return value of `callback`.
|
|
477
|
+
#
|
|
764
478
|
# If the `callback` returns a [Promise], it will be awaited.
|
|
765
|
-
#
|
|
479
|
+
#
|
|
766
480
|
# See [`method: BrowserContext.exposeFunction`] for context-wide exposed function.
|
|
767
|
-
#
|
|
768
|
-
#
|
|
769
|
-
#
|
|
770
|
-
#
|
|
771
|
-
#
|
|
772
|
-
#
|
|
773
|
-
#
|
|
774
|
-
# const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'.
|
|
775
|
-
# const crypto = require('crypto');
|
|
776
|
-
#
|
|
777
|
-
# (async () => {
|
|
778
|
-
# const browser = await webkit.launch({ headless: false });
|
|
779
|
-
# const page = await browser.newPage();
|
|
780
|
-
# await page.exposeFunction('sha1', text => crypto.createHash('sha1').update(text).digest('hex'));
|
|
781
|
-
# await page.setContent(`
|
|
782
|
-
# <script>
|
|
783
|
-
# async function onClick() {
|
|
784
|
-
# document.querySelector('div').textContent = await window.sha1('PLAYWRIGHT');
|
|
785
|
-
# }
|
|
786
|
-
# </script>
|
|
787
|
-
# <button onclick="onClick()">Click me</button>
|
|
788
|
-
# <div></div>
|
|
789
|
-
# `);
|
|
790
|
-
# await page.click('button');
|
|
791
|
-
# })();
|
|
792
|
-
# ```
|
|
793
|
-
#
|
|
794
|
-
# ```python async
|
|
795
|
-
# import asyncio
|
|
796
|
-
# import hashlib
|
|
797
|
-
# from playwright.async_api import async_playwright
|
|
798
|
-
#
|
|
799
|
-
# async def sha1(text):
|
|
800
|
-
# m = hashlib.sha1()
|
|
801
|
-
# m.update(bytes(text, "utf8"))
|
|
802
|
-
# return m.hexdigest()
|
|
803
|
-
#
|
|
804
|
-
#
|
|
805
|
-
# async def run(playwright):
|
|
806
|
-
# webkit = playwright.webkit
|
|
807
|
-
# browser = await webkit.launch(headless=False)
|
|
808
|
-
# page = await browser.new_page()
|
|
809
|
-
# await page.expose_function("sha1", sha1)
|
|
810
|
-
# await page.set_content("""
|
|
811
|
-
# <script>
|
|
812
|
-
# async function onClick() {
|
|
813
|
-
# document.querySelector('div').textContent = await window.sha1('PLAYWRIGHT');
|
|
814
|
-
# }
|
|
815
|
-
# </script>
|
|
816
|
-
# <button onclick="onClick()">Click me</button>
|
|
817
|
-
# <div></div>
|
|
818
|
-
# """)
|
|
819
|
-
# await page.click("button")
|
|
820
|
-
#
|
|
821
|
-
# async def main():
|
|
822
|
-
# async with async_playwright() as playwright:
|
|
823
|
-
# await run(playwright)
|
|
824
|
-
# asyncio.run(main())
|
|
825
|
-
# ```
|
|
826
|
-
#
|
|
481
|
+
#
|
|
482
|
+
# **NOTE**: Functions installed via [`method: Page.exposeFunction`] survive navigations.
|
|
483
|
+
#
|
|
484
|
+
# **Usage**
|
|
485
|
+
#
|
|
486
|
+
# An example of adding a `sha256` function to the page:
|
|
487
|
+
#
|
|
827
488
|
# ```python sync
|
|
828
489
|
# import hashlib
|
|
829
|
-
# from playwright.sync_api import sync_playwright
|
|
830
|
-
#
|
|
831
|
-
# def
|
|
832
|
-
# m = hashlib.
|
|
490
|
+
# from playwright.sync_api import sync_playwright, Playwright
|
|
491
|
+
#
|
|
492
|
+
# def sha256(text):
|
|
493
|
+
# m = hashlib.sha256()
|
|
833
494
|
# m.update(bytes(text, "utf8"))
|
|
834
495
|
# return m.hexdigest()
|
|
835
|
-
#
|
|
836
|
-
#
|
|
837
|
-
# def run(playwright):
|
|
496
|
+
#
|
|
497
|
+
#
|
|
498
|
+
# def run(playwright: Playwright):
|
|
838
499
|
# webkit = playwright.webkit
|
|
839
500
|
# browser = webkit.launch(headless=False)
|
|
840
501
|
# page = browser.new_page()
|
|
841
|
-
# page.expose_function("
|
|
502
|
+
# page.expose_function("sha256", sha256)
|
|
842
503
|
# page.set_content("""
|
|
843
504
|
# <script>
|
|
844
505
|
# async function onClick() {
|
|
845
|
-
# document.querySelector('div').textContent = await window.
|
|
506
|
+
# document.querySelector('div').textContent = await window.sha256('PLAYWRIGHT');
|
|
846
507
|
# }
|
|
847
508
|
# </script>
|
|
848
509
|
# <button onclick="onClick()">Click me</button>
|
|
849
510
|
# <div></div>
|
|
850
511
|
# """)
|
|
851
512
|
# page.click("button")
|
|
852
|
-
#
|
|
513
|
+
#
|
|
853
514
|
# with sync_playwright() as playwright:
|
|
854
515
|
# run(playwright)
|
|
855
516
|
# ```
|
|
856
517
|
def expose_function(name, callback)
|
|
857
|
-
|
|
518
|
+
wrap_impl(@impl.expose_function(unwrap_impl(name), unwrap_impl(callback)))
|
|
858
519
|
end
|
|
859
520
|
|
|
860
|
-
#
|
|
861
|
-
# element, fills it and triggers an `input` event after filling.
|
|
862
|
-
#
|
|
863
|
-
#
|
|
864
|
-
#
|
|
865
|
-
# To send fine-grained keyboard events, use [`method:
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
521
|
+
#
|
|
522
|
+
# This method waits for an element matching `selector`, waits for [actionability](../actionability.md) checks, focuses the element, fills it and triggers an `input` event after filling. Note that you can pass an empty string to clear the input field.
|
|
523
|
+
#
|
|
524
|
+
# If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
|
525
|
+
#
|
|
526
|
+
# To send fine-grained keyboard events, use [`method: Locator.pressSequentially`].
|
|
527
|
+
def fill(
|
|
528
|
+
selector,
|
|
529
|
+
value,
|
|
530
|
+
force: nil,
|
|
531
|
+
noWaitAfter: nil,
|
|
532
|
+
strict: nil,
|
|
533
|
+
timeout: nil)
|
|
534
|
+
wrap_impl(@impl.fill(unwrap_impl(selector), unwrap_impl(value), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
870
535
|
end
|
|
871
536
|
|
|
872
|
-
#
|
|
873
|
-
#
|
|
874
|
-
#
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
wrap_impl(@impl.focus(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
|
|
537
|
+
#
|
|
538
|
+
# This method fetches an element with `selector` and focuses it. If there's no element matching
|
|
539
|
+
# `selector`, the method waits until a matching element appears in the DOM.
|
|
540
|
+
def focus(selector, strict: nil, timeout: nil)
|
|
541
|
+
wrap_impl(@impl.focus(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
878
542
|
end
|
|
879
543
|
|
|
544
|
+
#
|
|
880
545
|
# Returns frame matching the specified criteria. Either `name` or `url` must be specified.
|
|
881
|
-
#
|
|
882
546
|
#
|
|
883
|
-
#
|
|
884
|
-
#
|
|
885
|
-
# ```
|
|
886
|
-
#
|
|
547
|
+
# **Usage**
|
|
548
|
+
#
|
|
887
549
|
# ```py
|
|
888
550
|
# frame = page.frame(name="frame-name")
|
|
889
551
|
# ```
|
|
890
|
-
#
|
|
891
552
|
#
|
|
892
|
-
# ```js
|
|
893
|
-
# const frame = page.frame({ url: /.*domain.*/ });
|
|
894
|
-
# ```
|
|
895
|
-
#
|
|
896
553
|
# ```py
|
|
897
554
|
# frame = page.frame(url=r".*domain.*")
|
|
898
555
|
# ```
|
|
899
|
-
def frame(
|
|
900
|
-
wrap_impl(@impl.frame(unwrap_impl(
|
|
556
|
+
def frame(name: nil, url: nil)
|
|
557
|
+
wrap_impl(@impl.frame(name: unwrap_impl(name), url: unwrap_impl(url)))
|
|
901
558
|
end
|
|
902
559
|
|
|
903
|
-
#
|
|
904
|
-
|
|
905
|
-
|
|
560
|
+
#
|
|
561
|
+
# When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements
|
|
562
|
+
# in that iframe.
|
|
563
|
+
#
|
|
564
|
+
# **Usage**
|
|
565
|
+
#
|
|
566
|
+
# Following snippet locates element with text "Submit" in the iframe with id `my-frame`,
|
|
567
|
+
# like `<iframe id="my-frame">`:
|
|
568
|
+
#
|
|
569
|
+
# ```python sync
|
|
570
|
+
# locator = page.frame_locator("#my-iframe").get_by_text("Submit")
|
|
571
|
+
# locator.click()
|
|
572
|
+
# ```
|
|
573
|
+
def frame_locator(selector)
|
|
574
|
+
wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
|
|
906
575
|
end
|
|
907
576
|
|
|
577
|
+
#
|
|
578
|
+
# An array of all frames attached to the page.
|
|
579
|
+
def frames
|
|
580
|
+
wrap_impl(@impl.frames)
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
#
|
|
908
584
|
# Returns element attribute value.
|
|
909
|
-
def get_attribute(selector, name, timeout: nil)
|
|
910
|
-
|
|
585
|
+
def get_attribute(selector, name, strict: nil, timeout: nil)
|
|
586
|
+
wrap_impl(@impl.get_attribute(unwrap_impl(selector), unwrap_impl(name), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
#
|
|
590
|
+
# Allows locating elements by their alt text.
|
|
591
|
+
#
|
|
592
|
+
# **Usage**
|
|
593
|
+
#
|
|
594
|
+
# For example, this method will find the image by alt text "Playwright logo":
|
|
595
|
+
#
|
|
596
|
+
# ```html
|
|
597
|
+
# <img alt='Playwright logo'>
|
|
598
|
+
# ```
|
|
599
|
+
#
|
|
600
|
+
# ```python sync
|
|
601
|
+
# page.get_by_alt_text("Playwright logo").click()
|
|
602
|
+
# ```
|
|
603
|
+
def get_by_alt_text(text, exact: nil)
|
|
604
|
+
wrap_impl(@impl.get_by_alt_text(unwrap_impl(text), exact: unwrap_impl(exact)))
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
#
|
|
608
|
+
# Allows locating input elements by the text of the associated `<label>` or `aria-labelledby` element, or by the `aria-label` attribute.
|
|
609
|
+
#
|
|
610
|
+
# **Usage**
|
|
611
|
+
#
|
|
612
|
+
# For example, this method will find inputs by label "Username" and "Password" in the following DOM:
|
|
613
|
+
#
|
|
614
|
+
# ```html
|
|
615
|
+
# <input aria-label="Username">
|
|
616
|
+
# <label for="password-input">Password:</label>
|
|
617
|
+
# <input id="password-input">
|
|
618
|
+
# ```
|
|
619
|
+
#
|
|
620
|
+
# ```python sync
|
|
621
|
+
# page.get_by_label("Username").fill("john")
|
|
622
|
+
# page.get_by_label("Password").fill("secret")
|
|
623
|
+
# ```
|
|
624
|
+
def get_by_label(text, exact: nil)
|
|
625
|
+
wrap_impl(@impl.get_by_label(unwrap_impl(text), exact: unwrap_impl(exact)))
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
#
|
|
629
|
+
# Allows locating input elements by the placeholder text.
|
|
630
|
+
#
|
|
631
|
+
# **Usage**
|
|
632
|
+
#
|
|
633
|
+
# For example, consider the following DOM structure.
|
|
634
|
+
#
|
|
635
|
+
# ```html
|
|
636
|
+
# <input type="email" placeholder="name@example.com" />
|
|
637
|
+
# ```
|
|
638
|
+
#
|
|
639
|
+
# You can fill the input after locating it by the placeholder text:
|
|
640
|
+
#
|
|
641
|
+
# ```python sync
|
|
642
|
+
# page.get_by_placeholder("name@example.com").fill("playwright@microsoft.com")
|
|
643
|
+
# ```
|
|
644
|
+
def get_by_placeholder(text, exact: nil)
|
|
645
|
+
wrap_impl(@impl.get_by_placeholder(unwrap_impl(text), exact: unwrap_impl(exact)))
|
|
646
|
+
end
|
|
647
|
+
|
|
648
|
+
#
|
|
649
|
+
# Allows locating elements by their [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles), [ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and [accessible name](https://w3c.github.io/accname/#dfn-accessible-name).
|
|
650
|
+
#
|
|
651
|
+
# **Usage**
|
|
652
|
+
#
|
|
653
|
+
# Consider the following DOM structure.
|
|
654
|
+
#
|
|
655
|
+
# ```html
|
|
656
|
+
# <h3>Sign up</h3>
|
|
657
|
+
# <label>
|
|
658
|
+
# <input type="checkbox" /> Subscribe
|
|
659
|
+
# </label>
|
|
660
|
+
# <br/>
|
|
661
|
+
# <button>Submit</button>
|
|
662
|
+
# ```
|
|
663
|
+
#
|
|
664
|
+
# You can locate each element by it's implicit role:
|
|
665
|
+
#
|
|
666
|
+
# ```python sync
|
|
667
|
+
# expect(page.get_by_role("heading", name="Sign up")).to_be_visible()
|
|
668
|
+
#
|
|
669
|
+
# page.get_by_role("checkbox", name="Subscribe").check()
|
|
670
|
+
#
|
|
671
|
+
# page.get_by_role("button", name=re.compile("submit", re.IGNORECASE)).click()
|
|
672
|
+
# ```
|
|
673
|
+
#
|
|
674
|
+
# **Details**
|
|
675
|
+
#
|
|
676
|
+
# Role selector **does not replace** accessibility audits and conformance tests, but rather gives early feedback about the ARIA guidelines.
|
|
677
|
+
#
|
|
678
|
+
# Many html elements have an implicitly [defined role](https://w3c.github.io/html-aam/#html-element-role-mappings) that is recognized by the role selector. You can find all the [supported roles here](https://www.w3.org/TR/wai-aria-1.2/#role_definitions). ARIA guidelines **do not recommend** duplicating implicit roles and attributes by setting `role` and/or `aria-*` attributes to default values.
|
|
679
|
+
def get_by_role(
|
|
680
|
+
role,
|
|
681
|
+
checked: nil,
|
|
682
|
+
disabled: nil,
|
|
683
|
+
exact: nil,
|
|
684
|
+
expanded: nil,
|
|
685
|
+
includeHidden: nil,
|
|
686
|
+
level: nil,
|
|
687
|
+
name: nil,
|
|
688
|
+
pressed: nil,
|
|
689
|
+
selected: nil)
|
|
690
|
+
wrap_impl(@impl.get_by_role(unwrap_impl(role), checked: unwrap_impl(checked), disabled: unwrap_impl(disabled), exact: unwrap_impl(exact), expanded: unwrap_impl(expanded), includeHidden: unwrap_impl(includeHidden), level: unwrap_impl(level), name: unwrap_impl(name), pressed: unwrap_impl(pressed), selected: unwrap_impl(selected)))
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
#
|
|
694
|
+
# Locate element by the test id.
|
|
695
|
+
#
|
|
696
|
+
# **Usage**
|
|
697
|
+
#
|
|
698
|
+
# Consider the following DOM structure.
|
|
699
|
+
#
|
|
700
|
+
# ```html
|
|
701
|
+
# <button data-testid="directions">Itinéraire</button>
|
|
702
|
+
# ```
|
|
703
|
+
#
|
|
704
|
+
# You can locate the element by it's test id:
|
|
705
|
+
#
|
|
706
|
+
# ```python sync
|
|
707
|
+
# page.get_by_test_id("directions").click()
|
|
708
|
+
# ```
|
|
709
|
+
#
|
|
710
|
+
# **Details**
|
|
711
|
+
#
|
|
712
|
+
# By default, the `data-testid` attribute is used as a test id. Use [`method: Selectors.setTestIdAttribute`] to configure a different test id attribute if necessary.
|
|
713
|
+
def get_by_test_id(testId)
|
|
714
|
+
wrap_impl(@impl.get_by_test_id(unwrap_impl(testId)))
|
|
715
|
+
end
|
|
716
|
+
alias_method :get_by_testid, :get_by_test_id
|
|
717
|
+
|
|
718
|
+
#
|
|
719
|
+
# Allows locating elements that contain given text.
|
|
720
|
+
#
|
|
721
|
+
# See also [`method: Locator.filter`] that allows to match by another criteria, like an accessible role, and then filter by the text content.
|
|
722
|
+
#
|
|
723
|
+
# **Usage**
|
|
724
|
+
#
|
|
725
|
+
# Consider the following DOM structure:
|
|
726
|
+
#
|
|
727
|
+
# ```html
|
|
728
|
+
# <div>Hello <span>world</span></div>
|
|
729
|
+
# <div>Hello</div>
|
|
730
|
+
# ```
|
|
731
|
+
#
|
|
732
|
+
# You can locate by text substring, exact string, or a regular expression:
|
|
733
|
+
#
|
|
734
|
+
# ```python sync
|
|
735
|
+
# # Matches <span>
|
|
736
|
+
# page.get_by_text("world")
|
|
737
|
+
#
|
|
738
|
+
# # Matches first <div>
|
|
739
|
+
# page.get_by_text("Hello world")
|
|
740
|
+
#
|
|
741
|
+
# # Matches second <div>
|
|
742
|
+
# page.get_by_text("Hello", exact=True)
|
|
743
|
+
#
|
|
744
|
+
# # Matches both <div>s
|
|
745
|
+
# page.get_by_text(re.compile("Hello"))
|
|
746
|
+
#
|
|
747
|
+
# # Matches second <div>
|
|
748
|
+
# page.get_by_text(re.compile("^hello$", re.IGNORECASE))
|
|
749
|
+
# ```
|
|
750
|
+
#
|
|
751
|
+
# **Details**
|
|
752
|
+
#
|
|
753
|
+
# Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into one, turns line breaks into spaces and ignores leading and trailing whitespace.
|
|
754
|
+
#
|
|
755
|
+
# Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
|
|
756
|
+
def get_by_text(text, exact: nil)
|
|
757
|
+
wrap_impl(@impl.get_by_text(unwrap_impl(text), exact: unwrap_impl(exact)))
|
|
911
758
|
end
|
|
912
759
|
|
|
760
|
+
#
|
|
761
|
+
# Allows locating elements by their title attribute.
|
|
762
|
+
#
|
|
763
|
+
# **Usage**
|
|
764
|
+
#
|
|
765
|
+
# Consider the following DOM structure.
|
|
766
|
+
#
|
|
767
|
+
# ```html
|
|
768
|
+
# <span title='Issues count'>25 issues</span>
|
|
769
|
+
# ```
|
|
770
|
+
#
|
|
771
|
+
# You can check the issues count after locating it by the title text:
|
|
772
|
+
#
|
|
773
|
+
# ```python sync
|
|
774
|
+
# expect(page.get_by_title("Issues count")).to_have_text("25 issues")
|
|
775
|
+
# ```
|
|
776
|
+
def get_by_title(text, exact: nil)
|
|
777
|
+
wrap_impl(@impl.get_by_title(unwrap_impl(text), exact: unwrap_impl(exact)))
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
#
|
|
913
781
|
# Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
|
|
914
|
-
# last redirect. If
|
|
915
|
-
#
|
|
782
|
+
# last redirect. If cannot go back, returns `null`.
|
|
783
|
+
#
|
|
916
784
|
# Navigate to the previous page in history.
|
|
917
785
|
def go_back(timeout: nil, waitUntil: nil)
|
|
918
|
-
|
|
786
|
+
wrap_impl(@impl.go_back(timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
|
|
919
787
|
end
|
|
920
788
|
|
|
789
|
+
#
|
|
921
790
|
# Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
|
|
922
|
-
# last redirect. If
|
|
923
|
-
#
|
|
791
|
+
# last redirect. If cannot go forward, returns `null`.
|
|
792
|
+
#
|
|
924
793
|
# Navigate to the next page in history.
|
|
925
794
|
def go_forward(timeout: nil, waitUntil: nil)
|
|
926
|
-
|
|
795
|
+
wrap_impl(@impl.go_forward(timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
|
|
927
796
|
end
|
|
928
797
|
|
|
929
|
-
#
|
|
930
|
-
#
|
|
931
|
-
#
|
|
932
|
-
#
|
|
798
|
+
#
|
|
799
|
+
# Request the page to perform garbage collection. Note that there is no guarantee that all unreachable objects will be collected.
|
|
800
|
+
#
|
|
801
|
+
# This is useful to help detect memory leaks. For example, if your page has a large object `'suspect'` that might be leaked, you can check that it does not leak by using a [`WeakRef`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef).
|
|
802
|
+
#
|
|
803
|
+
# ```python sync
|
|
804
|
+
# # 1. In your page, save a WeakRef for the "suspect".
|
|
805
|
+
# page.evaluate("globalThis.suspectWeakRef = new WeakRef(suspect)")
|
|
806
|
+
# # 2. Request garbage collection.
|
|
807
|
+
# page.request_gc()
|
|
808
|
+
# # 3. Check that weak ref does not deref to the original object.
|
|
809
|
+
# assert page.evaluate("!globalThis.suspectWeakRef.deref()")
|
|
810
|
+
# ```
|
|
811
|
+
def request_gc
|
|
812
|
+
raise NotImplementedError.new('request_gc is not implemented yet.')
|
|
813
|
+
end
|
|
814
|
+
|
|
815
|
+
#
|
|
816
|
+
# Returns the main resource response. In case of multiple redirects, the navigation will resolve with the first
|
|
817
|
+
# non-redirect response.
|
|
818
|
+
#
|
|
819
|
+
# The method will throw an error if:
|
|
933
820
|
# - there's an SSL error (e.g. in case of self-signed certificates).
|
|
934
821
|
# - target URL is invalid.
|
|
935
822
|
# - the `timeout` is exceeded during navigation.
|
|
936
823
|
# - the remote server does not respond or is unreachable.
|
|
937
824
|
# - the main resource failed to load.
|
|
938
|
-
#
|
|
939
|
-
#
|
|
825
|
+
#
|
|
826
|
+
# The method will not throw an error when any valid HTTP status code is returned by the remote server, including 404 "Not
|
|
940
827
|
# Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling
|
|
941
828
|
# [`method: Response.status`].
|
|
942
|
-
#
|
|
943
|
-
#
|
|
829
|
+
#
|
|
830
|
+
# **NOTE**: The method either throws an error or returns a main resource response. The only exceptions are navigation to
|
|
944
831
|
# `about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.
|
|
945
|
-
#
|
|
832
|
+
#
|
|
833
|
+
# **NOTE**: Headless mode doesn't support navigation to a PDF document. See the
|
|
946
834
|
# [upstream issue](https://bugs.chromium.org/p/chromium/issues/detail?id=761295).
|
|
947
|
-
#
|
|
948
|
-
# Shortcut for main frame's [`method: Frame.goto`]
|
|
949
835
|
def goto(url, referer: nil, timeout: nil, waitUntil: nil)
|
|
950
836
|
wrap_impl(@impl.goto(unwrap_impl(url), referer: unwrap_impl(referer), timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
|
|
951
837
|
end
|
|
952
838
|
|
|
839
|
+
#
|
|
953
840
|
# This method hovers over an element matching `selector` by performing the following steps:
|
|
954
|
-
# 1. Find an element
|
|
955
|
-
# 1. Wait for [actionability](
|
|
956
|
-
# element is detached during the checks, the whole action is retried.
|
|
841
|
+
# 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
|
842
|
+
# 1. Wait for [actionability](../actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
|
|
957
843
|
# 1. Scroll the element into view if needed.
|
|
958
844
|
# 1. Use [`property: Page.mouse`] to hover over the center of the element, or the specified `position`.
|
|
959
|
-
#
|
|
960
|
-
#
|
|
961
|
-
#
|
|
962
|
-
# Passing zero timeout disables this.
|
|
963
|
-
#
|
|
964
|
-
# Shortcut for main frame's [`method: Frame.hover`].
|
|
845
|
+
#
|
|
846
|
+
# When all steps combined have not finished during the specified `timeout`, this method throws a
|
|
847
|
+
# `TimeoutError`. Passing zero timeout disables this.
|
|
965
848
|
def hover(
|
|
966
849
|
selector,
|
|
967
850
|
force: nil,
|
|
968
851
|
modifiers: nil,
|
|
852
|
+
noWaitAfter: nil,
|
|
969
853
|
position: nil,
|
|
970
|
-
|
|
971
|
-
|
|
854
|
+
strict: nil,
|
|
855
|
+
timeout: nil,
|
|
856
|
+
trial: nil)
|
|
857
|
+
wrap_impl(@impl.hover(unwrap_impl(selector), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
|
|
972
858
|
end
|
|
973
859
|
|
|
860
|
+
#
|
|
974
861
|
# Returns `element.innerHTML`.
|
|
975
|
-
def inner_html(selector, timeout: nil)
|
|
976
|
-
|
|
862
|
+
def inner_html(selector, strict: nil, timeout: nil)
|
|
863
|
+
wrap_impl(@impl.inner_html(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
977
864
|
end
|
|
978
865
|
|
|
866
|
+
#
|
|
979
867
|
# Returns `element.innerText`.
|
|
980
|
-
def inner_text(selector, timeout: nil)
|
|
981
|
-
|
|
868
|
+
def inner_text(selector, strict: nil, timeout: nil)
|
|
869
|
+
wrap_impl(@impl.inner_text(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
982
870
|
end
|
|
983
871
|
|
|
872
|
+
#
|
|
873
|
+
# Returns `input.value` for the selected `<input>` or `<textarea>` or `<select>` element.
|
|
874
|
+
#
|
|
875
|
+
# Throws for non-input elements. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), returns the value of the control.
|
|
876
|
+
def input_value(selector, strict: nil, timeout: nil)
|
|
877
|
+
wrap_impl(@impl.input_value(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
878
|
+
end
|
|
879
|
+
|
|
880
|
+
#
|
|
984
881
|
# Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
|
|
985
|
-
def checked?(selector, timeout: nil)
|
|
986
|
-
|
|
882
|
+
def checked?(selector, strict: nil, timeout: nil)
|
|
883
|
+
wrap_impl(@impl.checked?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
987
884
|
end
|
|
988
885
|
|
|
886
|
+
#
|
|
989
887
|
# Indicates that the page has been closed.
|
|
990
888
|
def closed?
|
|
991
889
|
wrap_impl(@impl.closed?)
|
|
992
890
|
end
|
|
993
891
|
|
|
994
|
-
#
|
|
995
|
-
|
|
996
|
-
|
|
892
|
+
#
|
|
893
|
+
# Returns whether the element is disabled, the opposite of [enabled](../actionability.md#enabled).
|
|
894
|
+
def disabled?(selector, strict: nil, timeout: nil)
|
|
895
|
+
wrap_impl(@impl.disabled?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
896
|
+
end
|
|
897
|
+
|
|
898
|
+
#
|
|
899
|
+
# Returns whether the element is [editable](../actionability.md#editable).
|
|
900
|
+
def editable?(selector, strict: nil, timeout: nil)
|
|
901
|
+
wrap_impl(@impl.editable?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
902
|
+
end
|
|
903
|
+
|
|
904
|
+
#
|
|
905
|
+
# Returns whether the element is [enabled](../actionability.md#enabled).
|
|
906
|
+
def enabled?(selector, strict: nil, timeout: nil)
|
|
907
|
+
wrap_impl(@impl.enabled?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
908
|
+
end
|
|
909
|
+
|
|
910
|
+
#
|
|
911
|
+
# Returns whether the element is hidden, the opposite of [visible](../actionability.md#visible). `selector` that does not match any elements is considered hidden.
|
|
912
|
+
def hidden?(selector, strict: nil, timeout: nil)
|
|
913
|
+
wrap_impl(@impl.hidden?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
997
914
|
end
|
|
998
915
|
|
|
999
|
-
#
|
|
1000
|
-
|
|
1001
|
-
|
|
916
|
+
#
|
|
917
|
+
# Returns whether the element is [visible](../actionability.md#visible). `selector` that does not match any elements is considered not visible.
|
|
918
|
+
def visible?(selector, strict: nil, timeout: nil)
|
|
919
|
+
wrap_impl(@impl.visible?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
1002
920
|
end
|
|
1003
921
|
|
|
1004
|
-
#
|
|
1005
|
-
|
|
1006
|
-
|
|
922
|
+
#
|
|
923
|
+
# Returns up to (currently) 200 last console messages from this page. See [`event: Page.console`] for more details.
|
|
924
|
+
def console_messages
|
|
925
|
+
wrap_impl(@impl.console_messages)
|
|
1007
926
|
end
|
|
1008
927
|
|
|
1009
|
-
#
|
|
1010
|
-
|
|
1011
|
-
|
|
928
|
+
#
|
|
929
|
+
# Returns up to (currently) 200 last page errors from this page. See [`event: Page.pageError`] for more details.
|
|
930
|
+
def page_errors
|
|
931
|
+
wrap_impl(@impl.page_errors)
|
|
1012
932
|
end
|
|
1013
933
|
|
|
1014
|
-
#
|
|
1015
|
-
|
|
1016
|
-
|
|
934
|
+
#
|
|
935
|
+
# The method returns an element locator that can be used to perform actions on this page / frame.
|
|
936
|
+
# Locator is resolved to the element immediately before performing an action, so a series of actions on the same locator can in fact be performed on different DOM elements. That would happen if the DOM structure between those actions has changed.
|
|
937
|
+
#
|
|
938
|
+
# [Learn more about locators](../locators.md).
|
|
939
|
+
def locator(
|
|
940
|
+
selector,
|
|
941
|
+
has: nil,
|
|
942
|
+
hasNot: nil,
|
|
943
|
+
hasNotText: nil,
|
|
944
|
+
hasText: nil)
|
|
945
|
+
wrap_impl(@impl.locator(unwrap_impl(selector), has: unwrap_impl(has), hasNot: unwrap_impl(hasNot), hasNotText: unwrap_impl(hasNotText), hasText: unwrap_impl(hasText)))
|
|
1017
946
|
end
|
|
1018
947
|
|
|
948
|
+
#
|
|
1019
949
|
# The page's main frame. Page is guaranteed to have a main frame which persists during navigations.
|
|
1020
950
|
def main_frame
|
|
1021
951
|
wrap_impl(@impl.main_frame)
|
|
1022
952
|
end
|
|
1023
953
|
|
|
954
|
+
#
|
|
1024
955
|
# Returns the opener for popup pages and `null` for others. If the opener has been closed already the returns `null`.
|
|
1025
956
|
def opener
|
|
1026
957
|
wrap_impl(@impl.opener)
|
|
1027
958
|
end
|
|
1028
959
|
|
|
960
|
+
#
|
|
961
|
+
# Pauses script execution. Playwright will stop executing the script and wait for the user to either press the 'Resume'
|
|
962
|
+
# button in the page overlay or to call `playwright.resume()` in the DevTools console.
|
|
963
|
+
#
|
|
964
|
+
# User can inspect selectors or perform manual steps while paused. Resume will continue running the original script from
|
|
965
|
+
# the place it was paused.
|
|
966
|
+
#
|
|
967
|
+
# **NOTE**: This method requires Playwright to be started in a headed mode, with a falsy `headless` option.
|
|
968
|
+
def pause
|
|
969
|
+
wrap_impl(@impl.pause)
|
|
970
|
+
end
|
|
971
|
+
|
|
972
|
+
#
|
|
1029
973
|
# Returns the PDF buffer.
|
|
1030
|
-
#
|
|
1031
|
-
# > NOTE: Generating a pdf is currently only supported in Chromium headless.
|
|
1032
|
-
#
|
|
974
|
+
#
|
|
1033
975
|
# `page.pdf()` generates a pdf of the page with `print` css media. To generate a pdf with `screen` media, call
|
|
1034
976
|
# [`method: Page.emulateMedia`] before calling `page.pdf()`:
|
|
1035
|
-
#
|
|
1036
|
-
#
|
|
977
|
+
#
|
|
978
|
+
# **NOTE**: By default, `page.pdf()` generates a pdf with modified colors for printing. Use the
|
|
1037
979
|
# [`-webkit-print-color-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-print-color-adjust) property to
|
|
1038
980
|
# force rendering of exact colors.
|
|
1039
|
-
#
|
|
1040
981
|
#
|
|
1041
|
-
#
|
|
1042
|
-
#
|
|
1043
|
-
# await page.emulateMedia({media: 'screen'});
|
|
1044
|
-
# await page.pdf({path: 'page.pdf'});
|
|
1045
|
-
# ```
|
|
1046
|
-
#
|
|
1047
|
-
# ```python async
|
|
1048
|
-
# # generates a pdf with "screen" media type.
|
|
1049
|
-
# await page.emulate_media(media="screen")
|
|
1050
|
-
# await page.pdf(path="page.pdf")
|
|
1051
|
-
# ```
|
|
1052
|
-
#
|
|
982
|
+
# **Usage**
|
|
983
|
+
#
|
|
1053
984
|
# ```python sync
|
|
1054
985
|
# # generates a pdf with "screen" media type.
|
|
1055
986
|
# page.emulate_media(media="screen")
|
|
1056
987
|
# page.pdf(path="page.pdf")
|
|
1057
988
|
# ```
|
|
1058
|
-
#
|
|
1059
|
-
# The `width`, `height`, and `margin` options accept values labeled with units. Unlabeled
|
|
1060
|
-
#
|
|
989
|
+
#
|
|
990
|
+
# The `width`, `height`, and `margin` options accept values labeled with units. Unlabeled
|
|
991
|
+
# values are treated as pixels.
|
|
992
|
+
#
|
|
1061
993
|
# A few examples:
|
|
1062
994
|
# - `page.pdf({width: 100})` - prints with width set to 100 pixels
|
|
1063
995
|
# - `page.pdf({width: '100px'})` - prints with width set to 100 pixels
|
|
1064
996
|
# - `page.pdf({width: '10cm'})` - prints with width set to 10 centimeters.
|
|
1065
|
-
#
|
|
997
|
+
#
|
|
1066
998
|
# All possible units are:
|
|
1067
999
|
# - `px` - pixel
|
|
1068
1000
|
# - `in` - inch
|
|
1069
1001
|
# - `cm` - centimeter
|
|
1070
1002
|
# - `mm` - millimeter
|
|
1071
|
-
#
|
|
1003
|
+
#
|
|
1072
1004
|
# The `format` options are:
|
|
1073
1005
|
# - `Letter`: 8.5in x 11in
|
|
1074
1006
|
# - `Legal`: 8.5in x 14in
|
|
@@ -1081,9 +1013,9 @@ module Playwright
|
|
|
1081
1013
|
# - `A4`: 8.27in x 11.7in
|
|
1082
1014
|
# - `A5`: 5.83in x 8.27in
|
|
1083
1015
|
# - `A6`: 4.13in x 5.83in
|
|
1084
|
-
#
|
|
1085
|
-
#
|
|
1086
|
-
# are not evaluated. > 2. Page styles are not visible inside templates.
|
|
1016
|
+
#
|
|
1017
|
+
# **NOTE**: `headerTemplate` and `footerTemplate` markup have the following limitations: > 1. Script tags inside
|
|
1018
|
+
# templates are not evaluated. > 2. Page styles are not visible inside templates.
|
|
1087
1019
|
def pdf(
|
|
1088
1020
|
displayHeaderFooter: nil,
|
|
1089
1021
|
footerTemplate: nil,
|
|
@@ -1092,59 +1024,41 @@ module Playwright
|
|
|
1092
1024
|
height: nil,
|
|
1093
1025
|
landscape: nil,
|
|
1094
1026
|
margin: nil,
|
|
1027
|
+
outline: nil,
|
|
1095
1028
|
pageRanges: nil,
|
|
1096
1029
|
path: nil,
|
|
1097
1030
|
preferCSSPageSize: nil,
|
|
1098
1031
|
printBackground: nil,
|
|
1099
1032
|
scale: nil,
|
|
1033
|
+
tagged: nil,
|
|
1100
1034
|
width: nil)
|
|
1101
|
-
|
|
1035
|
+
wrap_impl(@impl.pdf(displayHeaderFooter: unwrap_impl(displayHeaderFooter), footerTemplate: unwrap_impl(footerTemplate), format: unwrap_impl(format), headerTemplate: unwrap_impl(headerTemplate), height: unwrap_impl(height), landscape: unwrap_impl(landscape), margin: unwrap_impl(margin), outline: unwrap_impl(outline), pageRanges: unwrap_impl(pageRanges), path: unwrap_impl(path), preferCSSPageSize: unwrap_impl(preferCSSPageSize), printBackground: unwrap_impl(printBackground), scale: unwrap_impl(scale), tagged: unwrap_impl(tagged), width: unwrap_impl(width)))
|
|
1102
1036
|
end
|
|
1103
1037
|
|
|
1038
|
+
#
|
|
1104
1039
|
# Focuses the element, and then uses [`method: Keyboard.down`] and [`method: Keyboard.up`].
|
|
1105
|
-
#
|
|
1106
|
-
# `key` can specify the intended
|
|
1107
|
-
# value or a single character to
|
|
1040
|
+
#
|
|
1041
|
+
# `key` can specify the intended
|
|
1042
|
+
# [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to
|
|
1043
|
+
# generate the text for. A superset of the `key` values can be found
|
|
1108
1044
|
# [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are:
|
|
1109
|
-
#
|
|
1045
|
+
#
|
|
1110
1046
|
# `F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`,
|
|
1111
1047
|
# `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
|
|
1112
|
-
#
|
|
1113
|
-
# Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
|
|
1114
|
-
#
|
|
1048
|
+
#
|
|
1049
|
+
# Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`, `ControlOrMeta`.
|
|
1050
|
+
# `ControlOrMeta` resolves to `Control` on Windows and Linux and to `Meta` on macOS.
|
|
1051
|
+
#
|
|
1115
1052
|
# Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
|
1116
|
-
#
|
|
1117
|
-
# If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different
|
|
1118
|
-
# texts.
|
|
1119
|
-
#
|
|
1120
|
-
# Shortcuts such as `key: "Control+o"` or `key: "Control+Shift+T"` are supported as well. When
|
|
1053
|
+
#
|
|
1054
|
+
# If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different
|
|
1055
|
+
# respective texts.
|
|
1056
|
+
#
|
|
1057
|
+
# Shortcuts such as `key: "Control+o"`, `key: "Control++` or `key: "Control+Shift+T"` are supported as well. When specified with the
|
|
1121
1058
|
# modifier, modifier is pressed and being held while the subsequent key is being pressed.
|
|
1122
|
-
#
|
|
1123
|
-
#
|
|
1124
|
-
#
|
|
1125
|
-
# const page = await browser.newPage();
|
|
1126
|
-
# await page.goto('https://keycode.info');
|
|
1127
|
-
# await page.press('body', 'A');
|
|
1128
|
-
# await page.screenshot({ path: 'A.png' });
|
|
1129
|
-
# await page.press('body', 'ArrowLeft');
|
|
1130
|
-
# await page.screenshot({ path: 'ArrowLeft.png' });
|
|
1131
|
-
# await page.press('body', 'Shift+O');
|
|
1132
|
-
# await page.screenshot({ path: 'O.png' });
|
|
1133
|
-
# await browser.close();
|
|
1134
|
-
# ```
|
|
1135
|
-
#
|
|
1136
|
-
# ```python async
|
|
1137
|
-
# page = await browser.new_page()
|
|
1138
|
-
# await page.goto("https://keycode.info")
|
|
1139
|
-
# await page.press("body", "A")
|
|
1140
|
-
# await page.screenshot(path="a.png")
|
|
1141
|
-
# await page.press("body", "ArrowLeft")
|
|
1142
|
-
# await page.screenshot(path="arrow_left.png")
|
|
1143
|
-
# await page.press("body", "Shift+O")
|
|
1144
|
-
# await page.screenshot(path="o.png")
|
|
1145
|
-
# await browser.close()
|
|
1146
|
-
# ```
|
|
1147
|
-
#
|
|
1059
|
+
#
|
|
1060
|
+
# **Usage**
|
|
1061
|
+
#
|
|
1148
1062
|
# ```python sync
|
|
1149
1063
|
# page = browser.new_page()
|
|
1150
1064
|
# page.goto("https://keycode.info")
|
|
@@ -1161,141 +1075,291 @@ module Playwright
|
|
|
1161
1075
|
key,
|
|
1162
1076
|
delay: nil,
|
|
1163
1077
|
noWaitAfter: nil,
|
|
1078
|
+
strict: nil,
|
|
1164
1079
|
timeout: nil)
|
|
1165
|
-
wrap_impl(@impl.press(unwrap_impl(selector), unwrap_impl(key), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
|
1080
|
+
wrap_impl(@impl.press(unwrap_impl(selector), unwrap_impl(key), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
#
|
|
1084
|
+
# The method finds an element matching the specified selector within the page. If no elements match the selector, the
|
|
1085
|
+
# return value resolves to `null`. To wait for an element on the page, use [`method: Locator.waitFor`].
|
|
1086
|
+
def query_selector(selector, strict: nil)
|
|
1087
|
+
wrap_impl(@impl.query_selector(unwrap_impl(selector), strict: unwrap_impl(strict)))
|
|
1088
|
+
end
|
|
1089
|
+
|
|
1090
|
+
#
|
|
1091
|
+
# The method finds all elements matching the specified selector within the page. If no elements match the selector, the
|
|
1092
|
+
# return value resolves to `[]`.
|
|
1093
|
+
def query_selector_all(selector)
|
|
1094
|
+
wrap_impl(@impl.query_selector_all(unwrap_impl(selector)))
|
|
1095
|
+
end
|
|
1096
|
+
|
|
1097
|
+
#
|
|
1098
|
+
# Returns up to (currently) 100 last network request from this page. See [`event: Page.request`] for more details.
|
|
1099
|
+
#
|
|
1100
|
+
# Returned requests should be accessed immediately, otherwise they might be collected to prevent unbounded memory growth as new requests come in. Once collected, retrieving most information about the request is impossible.
|
|
1101
|
+
#
|
|
1102
|
+
# Note that requests reported through the [`event: Page.request`] request are not collected, so there is a trade off between efficient memory usage with [`method: Page.requests`] and the amount of available information reported through [`event: Page.request`].
|
|
1103
|
+
def requests
|
|
1104
|
+
wrap_impl(@impl.requests)
|
|
1105
|
+
end
|
|
1106
|
+
|
|
1107
|
+
#
|
|
1108
|
+
# When testing a web page, sometimes unexpected overlays like a "Sign up" dialog appear and block actions you want to automate, e.g. clicking a button. These overlays don't always show up in the same way or at the same time, making them tricky to handle in automated tests.
|
|
1109
|
+
#
|
|
1110
|
+
# This method lets you set up a special function, called a handler, that activates when it detects that overlay is visible. The handler's job is to remove the overlay, allowing your test to continue as if the overlay wasn't there.
|
|
1111
|
+
#
|
|
1112
|
+
# Things to keep in mind:
|
|
1113
|
+
# - When an overlay is shown predictably, we recommend explicitly waiting for it in your test and dismissing it as a part of your normal test flow, instead of using [`method: Page.addLocatorHandler`].
|
|
1114
|
+
# - Playwright checks for the overlay every time before executing or retrying an action that requires an [actionability check](../actionability.md), or before performing an auto-waiting assertion check. When overlay is visible, Playwright calls the handler first, and then proceeds with the action/assertion. Note that the handler is only called when you perform an action/assertion - if the overlay becomes visible but you don't perform any actions, the handler will not be triggered.
|
|
1115
|
+
# - After executing the handler, Playwright will ensure that overlay that triggered the handler is not visible anymore. You can opt-out of this behavior with `noWaitAfter`.
|
|
1116
|
+
# - The execution time of the handler counts towards the timeout of the action/assertion that executed the handler. If your handler takes too long, it might cause timeouts.
|
|
1117
|
+
# - You can register multiple handlers. However, only a single handler will be running at a time. Make sure the actions within a handler don't depend on another handler.
|
|
1118
|
+
#
|
|
1119
|
+
# **NOTE**: Running the handler will alter your page state mid-test. For example it will change the currently focused element and move the mouse. Make sure that actions that run after the handler are self-contained and do not rely on the focus and mouse state being unchanged.
|
|
1120
|
+
#
|
|
1121
|
+
# For example, consider a test that calls [`method: Locator.focus`] followed by [`method: Keyboard.press`]. If your handler clicks a button between these two actions, the focused element most likely will be wrong, and key press will happen on the unexpected element. Use [`method: Locator.press`] instead to avoid this problem.
|
|
1122
|
+
#
|
|
1123
|
+
# Another example is a series of mouse actions, where [`method: Mouse.move`] is followed by [`method: Mouse.down`]. Again, when the handler runs between these two actions, the mouse position will be wrong during the mouse down. Prefer self-contained actions like [`method: Locator.click`] that do not rely on the state being unchanged by a handler.
|
|
1124
|
+
#
|
|
1125
|
+
# **Usage**
|
|
1126
|
+
#
|
|
1127
|
+
# An example that closes a "Sign up to the newsletter" dialog when it appears:
|
|
1128
|
+
#
|
|
1129
|
+
# ```python sync
|
|
1130
|
+
# # Setup the handler.
|
|
1131
|
+
# def handler():
|
|
1132
|
+
# page.get_by_role("button", name="No thanks").click()
|
|
1133
|
+
# page.add_locator_handler(page.get_by_text("Sign up to the newsletter"), handler)
|
|
1134
|
+
#
|
|
1135
|
+
# # Write the test as usual.
|
|
1136
|
+
# page.goto("https://example.com")
|
|
1137
|
+
# page.get_by_role("button", name="Start here").click()
|
|
1138
|
+
# ```
|
|
1139
|
+
#
|
|
1140
|
+
# An example that skips the "Confirm your security details" page when it is shown:
|
|
1141
|
+
#
|
|
1142
|
+
# ```python sync
|
|
1143
|
+
# # Setup the handler.
|
|
1144
|
+
# def handler():
|
|
1145
|
+
# page.get_by_role("button", name="Remind me later").click()
|
|
1146
|
+
# page.add_locator_handler(page.get_by_text("Confirm your security details"), handler)
|
|
1147
|
+
#
|
|
1148
|
+
# # Write the test as usual.
|
|
1149
|
+
# page.goto("https://example.com")
|
|
1150
|
+
# page.get_by_role("button", name="Start here").click()
|
|
1151
|
+
# ```
|
|
1152
|
+
#
|
|
1153
|
+
# An example with a custom callback on every actionability check. It uses a `<body>` locator that is always visible, so the handler is called before every actionability check. It is important to specify `noWaitAfter`, because the handler does not hide the `<body>` element.
|
|
1154
|
+
#
|
|
1155
|
+
# ```python sync
|
|
1156
|
+
# # Setup the handler.
|
|
1157
|
+
# def handler():
|
|
1158
|
+
# page.evaluate("window.removeObstructionsForTestIfNeeded()")
|
|
1159
|
+
# page.add_locator_handler(page.locator("body"), handler, no_wait_after=True)
|
|
1160
|
+
#
|
|
1161
|
+
# # Write the test as usual.
|
|
1162
|
+
# page.goto("https://example.com")
|
|
1163
|
+
# page.get_by_role("button", name="Start here").click()
|
|
1164
|
+
# ```
|
|
1165
|
+
#
|
|
1166
|
+
# Handler takes the original locator as an argument. You can also automatically remove the handler after a number of invocations by setting `times`:
|
|
1167
|
+
#
|
|
1168
|
+
# ```python sync
|
|
1169
|
+
# def handler(locator):
|
|
1170
|
+
# locator.click()
|
|
1171
|
+
# page.add_locator_handler(page.get_by_label("Close"), handler, times=1)
|
|
1172
|
+
# ```
|
|
1173
|
+
def add_locator_handler(locator, handler, noWaitAfter: nil, times: nil)
|
|
1174
|
+
raise NotImplementedError.new('add_locator_handler is not implemented yet.')
|
|
1166
1175
|
end
|
|
1167
1176
|
|
|
1177
|
+
#
|
|
1178
|
+
# Removes all locator handlers added by [`method: Page.addLocatorHandler`] for a specific locator.
|
|
1179
|
+
def remove_locator_handler(locator)
|
|
1180
|
+
raise NotImplementedError.new('remove_locator_handler is not implemented yet.')
|
|
1181
|
+
end
|
|
1182
|
+
|
|
1183
|
+
#
|
|
1184
|
+
# This method reloads the current page, in the same way as if the user had triggered a browser refresh.
|
|
1168
1185
|
# Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
|
|
1169
1186
|
# last redirect.
|
|
1170
1187
|
def reload(timeout: nil, waitUntil: nil)
|
|
1171
1188
|
wrap_impl(@impl.reload(timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
|
|
1172
1189
|
end
|
|
1173
1190
|
|
|
1191
|
+
#
|
|
1174
1192
|
# Routing provides the capability to modify network requests that are made by a page.
|
|
1175
|
-
#
|
|
1193
|
+
#
|
|
1176
1194
|
# Once routing is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted.
|
|
1177
|
-
#
|
|
1178
|
-
#
|
|
1179
|
-
#
|
|
1180
|
-
#
|
|
1181
|
-
#
|
|
1182
|
-
#
|
|
1183
|
-
#
|
|
1184
|
-
#
|
|
1185
|
-
#
|
|
1186
|
-
#
|
|
1187
|
-
#
|
|
1188
|
-
# ```
|
|
1189
|
-
#
|
|
1190
|
-
# ```python async
|
|
1191
|
-
# page = await browser.new_page()
|
|
1192
|
-
# await page.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())
|
|
1193
|
-
# await page.goto("https://example.com")
|
|
1194
|
-
# await browser.close()
|
|
1195
|
-
# ```
|
|
1196
|
-
#
|
|
1195
|
+
#
|
|
1196
|
+
# **NOTE**: The handler will only be called for the first url if the response is a redirect.
|
|
1197
|
+
#
|
|
1198
|
+
# **NOTE**: [`method: Page.route`] will not intercept requests intercepted by Service Worker. See [this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend disabling Service Workers when using request interception by setting `serviceWorkers` to `'block'`.
|
|
1199
|
+
#
|
|
1200
|
+
# **NOTE**: [`method: Page.route`] will not intercept the first request of a popup page. Use [`method: BrowserContext.route`] instead.
|
|
1201
|
+
#
|
|
1202
|
+
# **Usage**
|
|
1203
|
+
#
|
|
1204
|
+
# An example of a naive handler that aborts all image requests:
|
|
1205
|
+
#
|
|
1197
1206
|
# ```python sync
|
|
1198
1207
|
# page = browser.new_page()
|
|
1199
1208
|
# page.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())
|
|
1200
1209
|
# page.goto("https://example.com")
|
|
1201
1210
|
# browser.close()
|
|
1202
1211
|
# ```
|
|
1203
|
-
#
|
|
1212
|
+
#
|
|
1204
1213
|
# or the same snippet using a regex pattern instead:
|
|
1205
|
-
#
|
|
1206
1214
|
#
|
|
1207
|
-
# ```js
|
|
1208
|
-
# const page = await browser.newPage();
|
|
1209
|
-
# await page.route(/(\.png$)|(\.jpg$)/, route => route.abort());
|
|
1210
|
-
# await page.goto('https://example.com');
|
|
1211
|
-
# await browser.close();
|
|
1212
|
-
# ```
|
|
1213
|
-
#
|
|
1214
|
-
# ```python async
|
|
1215
|
-
# page = await browser.new_page()
|
|
1216
|
-
# await page.route(re.compile(r"(\.png$)|(\.jpg$)"), lambda route: route.abort())
|
|
1217
|
-
# await page.goto("https://example.com")
|
|
1218
|
-
# await browser.close()
|
|
1219
|
-
# ```
|
|
1220
|
-
#
|
|
1221
1215
|
# ```python sync
|
|
1222
1216
|
# page = browser.new_page()
|
|
1223
1217
|
# page.route(re.compile(r"(\.png$)|(\.jpg$)"), lambda route: route.abort())
|
|
1224
1218
|
# page.goto("https://example.com")
|
|
1225
1219
|
# browser.close()
|
|
1226
1220
|
# ```
|
|
1227
|
-
#
|
|
1221
|
+
#
|
|
1222
|
+
# It is possible to examine the request to decide the route action. For example, mocking all requests that contain some post data, and leaving all other requests as is:
|
|
1223
|
+
#
|
|
1224
|
+
# ```python sync
|
|
1225
|
+
# def handle_route(route: Route):
|
|
1226
|
+
# if ("my-string" in route.request.post_data):
|
|
1227
|
+
# route.fulfill(body="mocked-data")
|
|
1228
|
+
# else:
|
|
1229
|
+
# route.continue_()
|
|
1230
|
+
# page.route("/api/**", handle_route)
|
|
1231
|
+
# ```
|
|
1232
|
+
#
|
|
1228
1233
|
# Page routes take precedence over browser context routes (set up with [`method: BrowserContext.route`]) when request
|
|
1229
1234
|
# matches both handlers.
|
|
1230
|
-
#
|
|
1231
|
-
#
|
|
1232
|
-
|
|
1233
|
-
|
|
1235
|
+
#
|
|
1236
|
+
# To remove a route with its handler you can use [`method: Page.unroute`].
|
|
1237
|
+
#
|
|
1238
|
+
# **NOTE**: Enabling routing disables http cache.
|
|
1239
|
+
def route(url, handler, times: nil)
|
|
1240
|
+
wrap_impl(@impl.route(unwrap_impl(url), unwrap_impl(handler), times: unwrap_impl(times)))
|
|
1241
|
+
end
|
|
1242
|
+
|
|
1243
|
+
#
|
|
1244
|
+
# If specified the network requests that are made in the page will be served from the HAR file. Read more about [Replaying from HAR](../mock.md#replaying-from-har).
|
|
1245
|
+
#
|
|
1246
|
+
# Playwright will not serve requests intercepted by Service Worker from the HAR file. See [this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend disabling Service Workers when using request interception by setting `serviceWorkers` to `'block'`.
|
|
1247
|
+
def route_from_har(
|
|
1248
|
+
har,
|
|
1249
|
+
notFound: nil,
|
|
1250
|
+
update: nil,
|
|
1251
|
+
updateContent: nil,
|
|
1252
|
+
updateMode: nil,
|
|
1253
|
+
url: nil)
|
|
1254
|
+
wrap_impl(@impl.route_from_har(unwrap_impl(har), notFound: unwrap_impl(notFound), update: unwrap_impl(update), updateContent: unwrap_impl(updateContent), updateMode: unwrap_impl(updateMode), url: unwrap_impl(url)))
|
|
1255
|
+
end
|
|
1256
|
+
|
|
1257
|
+
#
|
|
1258
|
+
# This method allows to modify websocket connections that are made by the page.
|
|
1259
|
+
#
|
|
1260
|
+
# Note that only `WebSocket`s created after this method was called will be routed. It is recommended to call this method before navigating the page.
|
|
1261
|
+
#
|
|
1262
|
+
# **Usage**
|
|
1263
|
+
#
|
|
1264
|
+
# Below is an example of a simple mock that responds to a single message. See `WebSocketRoute` for more details and examples.
|
|
1265
|
+
#
|
|
1266
|
+
# ```python sync
|
|
1267
|
+
# def message_handler(ws: WebSocketRoute, message: Union[str, bytes]):
|
|
1268
|
+
# if message == "request":
|
|
1269
|
+
# ws.send("response")
|
|
1270
|
+
#
|
|
1271
|
+
# def handler(ws: WebSocketRoute):
|
|
1272
|
+
# ws.on_message(lambda message: message_handler(ws, message))
|
|
1273
|
+
#
|
|
1274
|
+
# page.route_web_socket("/ws", handler)
|
|
1275
|
+
# ```
|
|
1276
|
+
def route_web_socket(url, handler)
|
|
1277
|
+
raise NotImplementedError.new('route_web_socket is not implemented yet.')
|
|
1234
1278
|
end
|
|
1235
1279
|
|
|
1280
|
+
#
|
|
1236
1281
|
# Returns the buffer with the captured screenshot.
|
|
1237
|
-
#
|
|
1238
|
-
# > NOTE: Screenshots take at least 1/6 second on Chromium OS X and Chromium Windows. See https://crbug.com/741689 for
|
|
1239
|
-
# discussion.
|
|
1240
1282
|
def screenshot(
|
|
1283
|
+
animations: nil,
|
|
1284
|
+
caret: nil,
|
|
1241
1285
|
clip: nil,
|
|
1242
1286
|
fullPage: nil,
|
|
1287
|
+
mask: nil,
|
|
1288
|
+
maskColor: nil,
|
|
1243
1289
|
omitBackground: nil,
|
|
1244
1290
|
path: nil,
|
|
1245
1291
|
quality: nil,
|
|
1292
|
+
scale: nil,
|
|
1293
|
+
style: nil,
|
|
1246
1294
|
timeout: nil,
|
|
1247
1295
|
type: nil)
|
|
1248
|
-
wrap_impl(@impl.screenshot(clip: unwrap_impl(clip), fullPage: unwrap_impl(fullPage), omitBackground: unwrap_impl(omitBackground), path: unwrap_impl(path), quality: unwrap_impl(quality), timeout: unwrap_impl(timeout), type: unwrap_impl(type)))
|
|
1296
|
+
wrap_impl(@impl.screenshot(animations: unwrap_impl(animations), caret: unwrap_impl(caret), clip: unwrap_impl(clip), fullPage: unwrap_impl(fullPage), mask: unwrap_impl(mask), maskColor: unwrap_impl(maskColor), omitBackground: unwrap_impl(omitBackground), path: unwrap_impl(path), quality: unwrap_impl(quality), scale: unwrap_impl(scale), style: unwrap_impl(style), timeout: unwrap_impl(timeout), type: unwrap_impl(type)))
|
|
1249
1297
|
end
|
|
1250
1298
|
|
|
1299
|
+
#
|
|
1300
|
+
# This method waits for an element matching `selector`, waits for [actionability](../actionability.md) checks, waits until all specified options are present in the `<select>` element and selects these options.
|
|
1301
|
+
#
|
|
1302
|
+
# If the target element is not a `<select>` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be used instead.
|
|
1303
|
+
#
|
|
1251
1304
|
# Returns the array of option values that have been successfully selected.
|
|
1252
|
-
#
|
|
1253
|
-
# Triggers a `change` and `input` event once all the provided options have been selected.
|
|
1254
|
-
#
|
|
1255
|
-
#
|
|
1256
|
-
#
|
|
1257
|
-
#
|
|
1258
|
-
#
|
|
1259
|
-
# ```js
|
|
1260
|
-
# // single selection matching the value
|
|
1261
|
-
# page.selectOption('select#colors', 'blue');
|
|
1262
|
-
#
|
|
1263
|
-
# // single selection matching the label
|
|
1264
|
-
# page.selectOption('select#colors', { label: 'Blue' });
|
|
1265
|
-
#
|
|
1266
|
-
# // multiple selection
|
|
1267
|
-
# page.selectOption('select#colors', ['red', 'green', 'blue']);
|
|
1268
|
-
#
|
|
1269
|
-
# ```
|
|
1270
|
-
#
|
|
1271
|
-
# ```python async
|
|
1272
|
-
# # single selection matching the value
|
|
1273
|
-
# await page.select_option("select#colors", "blue")
|
|
1274
|
-
# # single selection matching the label
|
|
1275
|
-
# await page.select_option("select#colors", label="blue")
|
|
1276
|
-
# # multiple selection
|
|
1277
|
-
# await page.select_option("select#colors", value=["red", "green", "blue"])
|
|
1278
|
-
# ```
|
|
1279
|
-
#
|
|
1305
|
+
#
|
|
1306
|
+
# Triggers a `change` and `input` event once all the provided options have been selected.
|
|
1307
|
+
#
|
|
1308
|
+
# **Usage**
|
|
1309
|
+
#
|
|
1280
1310
|
# ```python sync
|
|
1281
|
-
# #
|
|
1311
|
+
# # Single selection matching the value or label
|
|
1282
1312
|
# page.select_option("select#colors", "blue")
|
|
1283
1313
|
# # single selection matching both the label
|
|
1284
1314
|
# page.select_option("select#colors", label="blue")
|
|
1285
1315
|
# # multiple selection
|
|
1286
1316
|
# page.select_option("select#colors", value=["red", "green", "blue"])
|
|
1287
1317
|
# ```
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1318
|
+
def select_option(
|
|
1319
|
+
selector,
|
|
1320
|
+
element: nil,
|
|
1321
|
+
index: nil,
|
|
1322
|
+
value: nil,
|
|
1323
|
+
label: nil,
|
|
1324
|
+
force: nil,
|
|
1325
|
+
noWaitAfter: nil,
|
|
1326
|
+
strict: nil,
|
|
1327
|
+
timeout: nil)
|
|
1328
|
+
wrap_impl(@impl.select_option(unwrap_impl(selector), element: unwrap_impl(element), index: unwrap_impl(index), value: unwrap_impl(value), label: unwrap_impl(label), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
1329
|
+
end
|
|
1330
|
+
|
|
1331
|
+
#
|
|
1332
|
+
# This method checks or unchecks an element matching `selector` by performing the following steps:
|
|
1333
|
+
# 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
|
1334
|
+
# 1. Ensure that matched element is a checkbox or a radio input. If not, this method throws.
|
|
1335
|
+
# 1. If the element already has the right checked state, this method returns immediately.
|
|
1336
|
+
# 1. Wait for [actionability](../actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
|
|
1337
|
+
# 1. Scroll the element into view if needed.
|
|
1338
|
+
# 1. Use [`property: Page.mouse`] to click in the center of the element.
|
|
1339
|
+
# 1. Ensure that the element is now checked or unchecked. If not, this method throws.
|
|
1340
|
+
#
|
|
1341
|
+
# When all steps combined have not finished during the specified `timeout`, this method throws a
|
|
1342
|
+
# `TimeoutError`. Passing zero timeout disables this.
|
|
1343
|
+
def set_checked(
|
|
1344
|
+
selector,
|
|
1345
|
+
checked,
|
|
1346
|
+
force: nil,
|
|
1347
|
+
noWaitAfter: nil,
|
|
1348
|
+
position: nil,
|
|
1349
|
+
strict: nil,
|
|
1350
|
+
timeout: nil,
|
|
1351
|
+
trial: nil)
|
|
1352
|
+
wrap_impl(@impl.set_checked(unwrap_impl(selector), unwrap_impl(checked), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
|
|
1292
1353
|
end
|
|
1293
1354
|
|
|
1355
|
+
#
|
|
1356
|
+
# This method internally calls [document.write()](https://developer.mozilla.org/en-US/docs/Web/API/Document/write), inheriting all its specific characteristics and behaviors.
|
|
1294
1357
|
def set_content(html, timeout: nil, waitUntil: nil)
|
|
1295
1358
|
wrap_impl(@impl.set_content(unwrap_impl(html), timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
|
|
1296
1359
|
end
|
|
1297
1360
|
alias_method :content=, :set_content
|
|
1298
1361
|
|
|
1362
|
+
#
|
|
1299
1363
|
# This setting will change the default maximum navigation time for the following methods and related shortcuts:
|
|
1300
1364
|
# - [`method: Page.goBack`]
|
|
1301
1365
|
# - [`method: Page.goForward`]
|
|
@@ -1303,61 +1367,58 @@ module Playwright
|
|
|
1303
1367
|
# - [`method: Page.reload`]
|
|
1304
1368
|
# - [`method: Page.setContent`]
|
|
1305
1369
|
# - [`method: Page.waitForNavigation`]
|
|
1306
|
-
#
|
|
1307
|
-
#
|
|
1370
|
+
# - [`method: Page.waitForURL`]
|
|
1371
|
+
#
|
|
1372
|
+
# **NOTE**: [`method: Page.setDefaultNavigationTimeout`] takes priority over [`method: Page.setDefaultTimeout`],
|
|
1308
1373
|
# [`method: BrowserContext.setDefaultTimeout`] and [`method: BrowserContext.setDefaultNavigationTimeout`].
|
|
1309
1374
|
def set_default_navigation_timeout(timeout)
|
|
1310
1375
|
wrap_impl(@impl.set_default_navigation_timeout(unwrap_impl(timeout)))
|
|
1311
1376
|
end
|
|
1312
1377
|
alias_method :default_navigation_timeout=, :set_default_navigation_timeout
|
|
1313
1378
|
|
|
1379
|
+
#
|
|
1314
1380
|
# This setting will change the default maximum time for all the methods accepting `timeout` option.
|
|
1315
|
-
#
|
|
1316
|
-
#
|
|
1381
|
+
#
|
|
1382
|
+
# **NOTE**: [`method: Page.setDefaultNavigationTimeout`] takes priority over [`method: Page.setDefaultTimeout`].
|
|
1317
1383
|
def set_default_timeout(timeout)
|
|
1318
1384
|
wrap_impl(@impl.set_default_timeout(unwrap_impl(timeout)))
|
|
1319
1385
|
end
|
|
1320
1386
|
alias_method :default_timeout=, :set_default_timeout
|
|
1321
1387
|
|
|
1388
|
+
#
|
|
1322
1389
|
# The extra HTTP headers will be sent with every request the page initiates.
|
|
1323
|
-
#
|
|
1324
|
-
#
|
|
1390
|
+
#
|
|
1391
|
+
# **NOTE**: [`method: Page.setExtraHTTPHeaders`] does not guarantee the order of headers in the outgoing requests.
|
|
1325
1392
|
def set_extra_http_headers(headers)
|
|
1326
|
-
|
|
1393
|
+
wrap_impl(@impl.set_extra_http_headers(unwrap_impl(headers)))
|
|
1327
1394
|
end
|
|
1328
1395
|
alias_method :extra_http_headers=, :set_extra_http_headers
|
|
1329
1396
|
|
|
1330
|
-
#
|
|
1331
|
-
# [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
|
|
1332
|
-
#
|
|
1397
|
+
#
|
|
1333
1398
|
# Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
|
|
1334
|
-
# are resolved relative to the
|
|
1335
|
-
|
|
1336
|
-
|
|
1399
|
+
# are resolved relative to the current working directory. For empty array, clears the selected files.
|
|
1400
|
+
# For inputs with a `[webkitdirectory]` attribute, only a single directory path is supported.
|
|
1401
|
+
#
|
|
1402
|
+
# This method expects `selector` to point to an
|
|
1403
|
+
# [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), targets the control instead.
|
|
1404
|
+
def set_input_files(
|
|
1405
|
+
selector,
|
|
1406
|
+
files,
|
|
1407
|
+
noWaitAfter: nil,
|
|
1408
|
+
strict: nil,
|
|
1409
|
+
timeout: nil)
|
|
1410
|
+
wrap_impl(@impl.set_input_files(unwrap_impl(selector), unwrap_impl(files), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
1337
1411
|
end
|
|
1338
1412
|
|
|
1413
|
+
#
|
|
1339
1414
|
# In the case of multiple pages in a single browser, each page can have its own viewport size. However,
|
|
1340
1415
|
# [`method: Browser.newContext`] allows to set viewport size (and more) for all pages in the context at once.
|
|
1341
|
-
#
|
|
1342
|
-
# `
|
|
1343
|
-
# viewport size before navigating to the page.
|
|
1344
|
-
#
|
|
1345
|
-
#
|
|
1346
|
-
#
|
|
1347
|
-
# const page = await browser.newPage();
|
|
1348
|
-
# await page.setViewportSize({
|
|
1349
|
-
# width: 640,
|
|
1350
|
-
# height: 480,
|
|
1351
|
-
# });
|
|
1352
|
-
# await page.goto('https://example.com');
|
|
1353
|
-
# ```
|
|
1354
|
-
#
|
|
1355
|
-
# ```python async
|
|
1356
|
-
# page = await browser.new_page()
|
|
1357
|
-
# await page.set_viewport_size({"width": 640, "height": 480})
|
|
1358
|
-
# await page.goto("https://example.com")
|
|
1359
|
-
# ```
|
|
1360
|
-
#
|
|
1416
|
+
#
|
|
1417
|
+
# [`method: Page.setViewportSize`] will resize the page. A lot of websites don't expect phones to change size, so you should set the
|
|
1418
|
+
# viewport size before navigating to the page. [`method: Page.setViewportSize`] will also reset `screen` size, use [`method: Browser.newContext`] with `screen` and `viewport` parameters if you need better control of these properties.
|
|
1419
|
+
#
|
|
1420
|
+
# **Usage**
|
|
1421
|
+
#
|
|
1361
1422
|
# ```python sync
|
|
1362
1423
|
# page = browser.new_page()
|
|
1363
1424
|
# page.set_viewport_size({"width": 640, "height": 480})
|
|
@@ -1368,409 +1429,309 @@ module Playwright
|
|
|
1368
1429
|
end
|
|
1369
1430
|
alias_method :viewport_size=, :set_viewport_size
|
|
1370
1431
|
|
|
1432
|
+
#
|
|
1371
1433
|
# This method taps an element matching `selector` by performing the following steps:
|
|
1372
|
-
# 1. Find an element
|
|
1373
|
-
# 1. Wait for [actionability](
|
|
1374
|
-
# element is detached during the checks, the whole action is retried.
|
|
1434
|
+
# 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
|
1435
|
+
# 1. Wait for [actionability](../actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
|
|
1375
1436
|
# 1. Scroll the element into view if needed.
|
|
1376
1437
|
# 1. Use [`property: Page.touchscreen`] to tap the center of the element, or the specified `position`.
|
|
1377
|
-
#
|
|
1378
|
-
#
|
|
1379
|
-
#
|
|
1380
|
-
#
|
|
1381
|
-
#
|
|
1382
|
-
# > NOTE: [`method: Page.tap`] requires that the `hasTouch` option of the browser context be set to true.
|
|
1383
|
-
#
|
|
1384
|
-
# Shortcut for main frame's [`method: Frame.tap`].
|
|
1438
|
+
#
|
|
1439
|
+
# When all steps combined have not finished during the specified `timeout`, this method throws a
|
|
1440
|
+
# `TimeoutError`. Passing zero timeout disables this.
|
|
1441
|
+
#
|
|
1442
|
+
# **NOTE**: [`method: Page.tap`] the method will throw if `hasTouch` option of the browser context is false.
|
|
1385
1443
|
def tap_point(
|
|
1386
1444
|
selector,
|
|
1387
1445
|
force: nil,
|
|
1388
1446
|
modifiers: nil,
|
|
1389
1447
|
noWaitAfter: nil,
|
|
1390
1448
|
position: nil,
|
|
1391
|
-
|
|
1392
|
-
|
|
1449
|
+
strict: nil,
|
|
1450
|
+
timeout: nil,
|
|
1451
|
+
trial: nil)
|
|
1452
|
+
wrap_impl(@impl.tap_point(unwrap_impl(selector), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
|
|
1393
1453
|
end
|
|
1394
1454
|
|
|
1455
|
+
#
|
|
1395
1456
|
# Returns `element.textContent`.
|
|
1396
|
-
def text_content(selector, timeout: nil)
|
|
1397
|
-
|
|
1457
|
+
def text_content(selector, strict: nil, timeout: nil)
|
|
1458
|
+
wrap_impl(@impl.text_content(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
1398
1459
|
end
|
|
1399
1460
|
|
|
1400
|
-
#
|
|
1461
|
+
#
|
|
1462
|
+
# Returns the page's title.
|
|
1401
1463
|
def title
|
|
1402
1464
|
wrap_impl(@impl.title)
|
|
1403
1465
|
end
|
|
1404
1466
|
|
|
1467
|
+
#
|
|
1405
1468
|
# Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. `page.type` can be used to send
|
|
1406
1469
|
# fine-grained keyboard events. To fill values in form fields, use [`method: Page.fill`].
|
|
1407
|
-
#
|
|
1470
|
+
#
|
|
1408
1471
|
# To press a special key, like `Control` or `ArrowDown`, use [`method: Keyboard.press`].
|
|
1409
|
-
#
|
|
1410
1472
|
#
|
|
1411
|
-
#
|
|
1412
|
-
#
|
|
1413
|
-
#
|
|
1414
|
-
# ```
|
|
1415
|
-
#
|
|
1416
|
-
# ```python async
|
|
1417
|
-
# await page.type("#mytextarea", "hello") # types instantly
|
|
1418
|
-
# await page.type("#mytextarea", "world", delay=100) # types slower, like a user
|
|
1419
|
-
# ```
|
|
1420
|
-
#
|
|
1421
|
-
# ```python sync
|
|
1422
|
-
# page.type("#mytextarea", "hello") # types instantly
|
|
1423
|
-
# page.type("#mytextarea", "world", delay=100) # types slower, like a user
|
|
1424
|
-
# ```
|
|
1425
|
-
#
|
|
1426
|
-
# Shortcut for main frame's [`method: Frame.type`].
|
|
1473
|
+
# **Usage**
|
|
1474
|
+
#
|
|
1475
|
+
# @deprecated In most cases, you should use [`method: Locator.fill`] instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [`method: Locator.pressSequentially`].
|
|
1427
1476
|
def type(
|
|
1428
1477
|
selector,
|
|
1429
1478
|
text,
|
|
1430
1479
|
delay: nil,
|
|
1431
1480
|
noWaitAfter: nil,
|
|
1481
|
+
strict: nil,
|
|
1432
1482
|
timeout: nil)
|
|
1433
|
-
wrap_impl(@impl.type(unwrap_impl(selector), unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
|
1483
|
+
wrap_impl(@impl.type(unwrap_impl(selector), unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
1434
1484
|
end
|
|
1435
1485
|
|
|
1486
|
+
#
|
|
1436
1487
|
# This method unchecks an element matching `selector` by performing the following steps:
|
|
1437
|
-
# 1. Find an element
|
|
1438
|
-
# 1. Ensure that matched element is a checkbox or a radio input. If not, this method
|
|
1439
|
-
#
|
|
1440
|
-
# 1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the
|
|
1441
|
-
# element is detached during the checks, the whole action is retried.
|
|
1488
|
+
# 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
|
1489
|
+
# 1. Ensure that matched element is a checkbox or a radio input. If not, this method throws. If the element is already unchecked, this method returns immediately.
|
|
1490
|
+
# 1. Wait for [actionability](../actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
|
|
1442
1491
|
# 1. Scroll the element into view if needed.
|
|
1443
1492
|
# 1. Use [`property: Page.mouse`] to click in the center of the element.
|
|
1444
|
-
# 1.
|
|
1445
|
-
#
|
|
1446
|
-
#
|
|
1447
|
-
#
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1493
|
+
# 1. Ensure that the element is now unchecked. If not, this method throws.
|
|
1494
|
+
#
|
|
1495
|
+
# When all steps combined have not finished during the specified `timeout`, this method throws a
|
|
1496
|
+
# `TimeoutError`. Passing zero timeout disables this.
|
|
1497
|
+
def uncheck(
|
|
1498
|
+
selector,
|
|
1499
|
+
force: nil,
|
|
1500
|
+
noWaitAfter: nil,
|
|
1501
|
+
position: nil,
|
|
1502
|
+
strict: nil,
|
|
1503
|
+
timeout: nil,
|
|
1504
|
+
trial: nil)
|
|
1505
|
+
wrap_impl(@impl.uncheck(unwrap_impl(selector), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
|
|
1453
1506
|
end
|
|
1454
1507
|
|
|
1455
|
-
#
|
|
1508
|
+
#
|
|
1509
|
+
# Removes all routes created with [`method: Page.route`] and [`method: Page.routeFromHAR`].
|
|
1510
|
+
def unroute_all(behavior: nil)
|
|
1511
|
+
wrap_impl(@impl.unroute_all(behavior: unwrap_impl(behavior)))
|
|
1512
|
+
end
|
|
1513
|
+
|
|
1514
|
+
#
|
|
1515
|
+
# Removes a route created with [`method: Page.route`]. When `handler` is not specified, removes all routes for
|
|
1516
|
+
# the `url`.
|
|
1456
1517
|
def unroute(url, handler: nil)
|
|
1457
|
-
|
|
1518
|
+
wrap_impl(@impl.unroute(unwrap_impl(url), handler: unwrap_impl(handler)))
|
|
1458
1519
|
end
|
|
1459
1520
|
|
|
1460
|
-
# Shortcut for main frame's [`method: Frame.url`].
|
|
1461
1521
|
def url
|
|
1462
1522
|
wrap_impl(@impl.url)
|
|
1463
1523
|
end
|
|
1464
1524
|
|
|
1525
|
+
#
|
|
1465
1526
|
# Video object associated with this page.
|
|
1466
1527
|
def video
|
|
1467
|
-
|
|
1528
|
+
wrap_impl(@impl.video)
|
|
1468
1529
|
end
|
|
1469
1530
|
|
|
1470
1531
|
def viewport_size
|
|
1471
1532
|
wrap_impl(@impl.viewport_size)
|
|
1472
1533
|
end
|
|
1473
1534
|
|
|
1535
|
+
#
|
|
1536
|
+
# Performs action and waits for a `ConsoleMessage` to be logged by in the page. If predicate is provided, it passes
|
|
1537
|
+
# `ConsoleMessage` value into the `predicate` function and waits for `predicate(message)` to return a truthy value.
|
|
1538
|
+
# Will throw an error if the page is closed before the [`event: Page.console`] event is fired.
|
|
1539
|
+
def expect_console_message(predicate: nil, timeout: nil, &block)
|
|
1540
|
+
wrap_impl(@impl.expect_console_message(predicate: unwrap_impl(predicate), timeout: unwrap_impl(timeout), &wrap_block_call(block)))
|
|
1541
|
+
end
|
|
1542
|
+
|
|
1543
|
+
#
|
|
1544
|
+
# Performs action and waits for a new `Download`. If predicate is provided, it passes
|
|
1545
|
+
# `Download` value into the `predicate` function and waits for `predicate(download)` to return a truthy value.
|
|
1546
|
+
# Will throw an error if the page is closed before the download event is fired.
|
|
1547
|
+
def expect_download(predicate: nil, timeout: nil, &block)
|
|
1548
|
+
wrap_impl(@impl.expect_download(predicate: unwrap_impl(predicate), timeout: unwrap_impl(timeout), &wrap_block_call(block)))
|
|
1549
|
+
end
|
|
1550
|
+
|
|
1551
|
+
#
|
|
1474
1552
|
# Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy
|
|
1475
1553
|
# value. Will throw an error if the page is closed before the event is fired. Returns the event data value.
|
|
1476
|
-
#
|
|
1477
1554
|
#
|
|
1478
|
-
#
|
|
1479
|
-
#
|
|
1480
|
-
# page.waitForEvent('framenavigated'),
|
|
1481
|
-
# page.click('button')
|
|
1482
|
-
# ]);
|
|
1483
|
-
# ```
|
|
1484
|
-
#
|
|
1485
|
-
# ```python async
|
|
1486
|
-
# async with page.expect_event("framenavigated") as event_info:
|
|
1487
|
-
# await page.click("button")
|
|
1488
|
-
# frame = await event_info.value
|
|
1489
|
-
# ```
|
|
1490
|
-
#
|
|
1555
|
+
# **Usage**
|
|
1556
|
+
#
|
|
1491
1557
|
# ```python sync
|
|
1492
1558
|
# with page.expect_event("framenavigated") as event_info:
|
|
1493
|
-
# page.
|
|
1559
|
+
# page.get_by_role("button")
|
|
1494
1560
|
# frame = event_info.value
|
|
1495
1561
|
# ```
|
|
1496
|
-
def expect_event(event,
|
|
1497
|
-
wrap_impl(@impl.expect_event(unwrap_impl(event),
|
|
1498
|
-
end
|
|
1499
|
-
|
|
1500
|
-
#
|
|
1501
|
-
#
|
|
1502
|
-
#
|
|
1503
|
-
#
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
#
|
|
1509
|
-
#
|
|
1510
|
-
#
|
|
1511
|
-
#
|
|
1512
|
-
#
|
|
1513
|
-
#
|
|
1514
|
-
#
|
|
1515
|
-
# })();
|
|
1516
|
-
# ```
|
|
1517
|
-
#
|
|
1518
|
-
# ```python async
|
|
1519
|
-
# import asyncio
|
|
1520
|
-
# from playwright.async_api import async_playwright
|
|
1521
|
-
#
|
|
1522
|
-
# async def run(playwright):
|
|
1523
|
-
# webkit = playwright.webkit
|
|
1524
|
-
# browser = await webkit.launch()
|
|
1525
|
-
# page = await browser.new_page()
|
|
1526
|
-
# await page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);", force_expr=True)
|
|
1527
|
-
# await page.wait_for_function("() => window.x > 0")
|
|
1528
|
-
# await browser.close()
|
|
1529
|
-
#
|
|
1530
|
-
# async def main():
|
|
1531
|
-
# async with async_playwright() as playwright:
|
|
1532
|
-
# await run(playwright)
|
|
1533
|
-
# asyncio.run(main())
|
|
1534
|
-
# ```
|
|
1535
|
-
#
|
|
1562
|
+
def expect_event(event, predicate: nil, timeout: nil, &block)
|
|
1563
|
+
wrap_impl(@impl.expect_event(unwrap_impl(event), predicate: unwrap_impl(predicate), timeout: unwrap_impl(timeout), &wrap_block_call(block)))
|
|
1564
|
+
end
|
|
1565
|
+
|
|
1566
|
+
#
|
|
1567
|
+
# Performs action and waits for a new `FileChooser` to be created. If predicate is provided, it passes
|
|
1568
|
+
# `FileChooser` value into the `predicate` function and waits for `predicate(fileChooser)` to return a truthy value.
|
|
1569
|
+
# Will throw an error if the page is closed before the file chooser is opened.
|
|
1570
|
+
def expect_file_chooser(predicate: nil, timeout: nil, &block)
|
|
1571
|
+
wrap_impl(@impl.expect_file_chooser(predicate: unwrap_impl(predicate), timeout: unwrap_impl(timeout), &wrap_block_call(block)))
|
|
1572
|
+
end
|
|
1573
|
+
|
|
1574
|
+
#
|
|
1575
|
+
# Returns when the `expression` returns a truthy value. It resolves to a JSHandle of the truthy value.
|
|
1576
|
+
#
|
|
1577
|
+
# **Usage**
|
|
1578
|
+
#
|
|
1579
|
+
# The [`method: Page.waitForFunction`] can be used to observe viewport size change:
|
|
1580
|
+
#
|
|
1536
1581
|
# ```python sync
|
|
1537
|
-
# from playwright.sync_api import sync_playwright
|
|
1538
|
-
#
|
|
1539
|
-
# def run(playwright):
|
|
1582
|
+
# from playwright.sync_api import sync_playwright, Playwright
|
|
1583
|
+
#
|
|
1584
|
+
# def run(playwright: Playwright):
|
|
1540
1585
|
# webkit = playwright.webkit
|
|
1541
1586
|
# browser = webkit.launch()
|
|
1542
1587
|
# page = browser.new_page()
|
|
1543
|
-
# page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);"
|
|
1588
|
+
# page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
|
|
1544
1589
|
# page.wait_for_function("() => window.x > 0")
|
|
1545
1590
|
# browser.close()
|
|
1546
|
-
#
|
|
1591
|
+
#
|
|
1547
1592
|
# with sync_playwright() as playwright:
|
|
1548
1593
|
# run(playwright)
|
|
1549
1594
|
# ```
|
|
1550
|
-
#
|
|
1595
|
+
#
|
|
1551
1596
|
# To pass an argument to the predicate of [`method: Page.waitForFunction`] function:
|
|
1552
|
-
#
|
|
1553
1597
|
#
|
|
1554
|
-
# ```js
|
|
1555
|
-
# const selector = '.foo';
|
|
1556
|
-
# await page.waitForFunction(selector => !!document.querySelector(selector), selector);
|
|
1557
|
-
# ```
|
|
1558
|
-
#
|
|
1559
|
-
# ```python async
|
|
1560
|
-
# selector = ".foo"
|
|
1561
|
-
# await page.wait_for_function("selector => !!document.querySelector(selector)", selector)
|
|
1562
|
-
# ```
|
|
1563
|
-
#
|
|
1564
1598
|
# ```python sync
|
|
1565
1599
|
# selector = ".foo"
|
|
1566
1600
|
# page.wait_for_function("selector => !!document.querySelector(selector)", selector)
|
|
1567
1601
|
# ```
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
def wait_for_function(pageFunction, arg: nil, polling: nil, timeout: nil)
|
|
1571
|
-
wrap_impl(@impl.wait_for_function(unwrap_impl(pageFunction), arg: unwrap_impl(arg), polling: unwrap_impl(polling), timeout: unwrap_impl(timeout)))
|
|
1602
|
+
def wait_for_function(expression, arg: nil, polling: nil, timeout: nil)
|
|
1603
|
+
wrap_impl(@impl.wait_for_function(unwrap_impl(expression), arg: unwrap_impl(arg), polling: unwrap_impl(polling), timeout: unwrap_impl(timeout)))
|
|
1572
1604
|
end
|
|
1573
1605
|
|
|
1606
|
+
#
|
|
1574
1607
|
# Returns when the required load state has been reached.
|
|
1575
|
-
#
|
|
1608
|
+
#
|
|
1576
1609
|
# This resolves when the page reaches a required load state, `load` by default. The navigation must have been committed
|
|
1577
1610
|
# when this method is called. If current document has already reached the required state, resolves immediately.
|
|
1578
|
-
#
|
|
1579
1611
|
#
|
|
1580
|
-
#
|
|
1581
|
-
#
|
|
1582
|
-
#
|
|
1583
|
-
#
|
|
1584
|
-
#
|
|
1585
|
-
# ```python async
|
|
1586
|
-
# await page.click("button") # click triggers navigation.
|
|
1587
|
-
# await page.wait_for_load_state() # the promise resolves after "load" event.
|
|
1588
|
-
# ```
|
|
1589
|
-
#
|
|
1612
|
+
# **NOTE**: Most of the time, this method is not needed because Playwright [auto-waits before every action](../actionability.md).
|
|
1613
|
+
#
|
|
1614
|
+
# **Usage**
|
|
1615
|
+
#
|
|
1590
1616
|
# ```python sync
|
|
1591
|
-
# page.
|
|
1617
|
+
# page.get_by_role("button").click() # click triggers navigation.
|
|
1592
1618
|
# page.wait_for_load_state() # the promise resolves after "load" event.
|
|
1593
1619
|
# ```
|
|
1594
|
-
#
|
|
1595
|
-
#
|
|
1596
|
-
# ```js
|
|
1597
|
-
# const [popup] = await Promise.all([
|
|
1598
|
-
# page.waitForEvent('popup'),
|
|
1599
|
-
# page.click('button'), // Click triggers a popup.
|
|
1600
|
-
# ])
|
|
1601
|
-
# await popup.waitForLoadState('domcontentloaded'); // The promise resolves after 'domcontentloaded' event.
|
|
1602
|
-
# console.log(await popup.title()); // Popup is ready to use.
|
|
1603
|
-
# ```
|
|
1604
|
-
#
|
|
1605
|
-
# ```python async
|
|
1606
|
-
# async with page.expect_popup() as page_info:
|
|
1607
|
-
# await page.click("button") # click triggers a popup.
|
|
1608
|
-
# popup = await page_info.value
|
|
1609
|
-
# # Following resolves after "domcontentloaded" event.
|
|
1610
|
-
# await popup.wait_for_load_state("domcontentloaded")
|
|
1611
|
-
# print(await popup.title()) # popup is ready to use.
|
|
1612
|
-
# ```
|
|
1613
|
-
#
|
|
1620
|
+
#
|
|
1614
1621
|
# ```python sync
|
|
1615
1622
|
# with page.expect_popup() as page_info:
|
|
1616
|
-
# page.
|
|
1623
|
+
# page.get_by_role("button").click() # click triggers a popup.
|
|
1617
1624
|
# popup = page_info.value
|
|
1618
|
-
#
|
|
1625
|
+
# # Wait for the "DOMContentLoaded" event.
|
|
1619
1626
|
# popup.wait_for_load_state("domcontentloaded")
|
|
1620
1627
|
# print(popup.title()) # popup is ready to use.
|
|
1621
1628
|
# ```
|
|
1622
|
-
#
|
|
1623
|
-
# Shortcut for main frame's [`method: Frame.waitForLoadState`].
|
|
1624
1629
|
def wait_for_load_state(state: nil, timeout: nil)
|
|
1625
1630
|
wrap_impl(@impl.wait_for_load_state(state: unwrap_impl(state), timeout: unwrap_impl(timeout)))
|
|
1626
1631
|
end
|
|
1627
1632
|
|
|
1628
|
-
#
|
|
1629
|
-
#
|
|
1630
|
-
#
|
|
1631
|
-
#
|
|
1633
|
+
#
|
|
1634
|
+
# Waits for the main frame navigation and returns the main resource response. In case of multiple redirects, the navigation
|
|
1635
|
+
# will resolve with the response of the last redirect. In case of navigation to a different anchor or navigation due to
|
|
1636
|
+
# History API usage, the navigation will resolve with `null`.
|
|
1637
|
+
#
|
|
1638
|
+
# **Usage**
|
|
1639
|
+
#
|
|
1632
1640
|
# This resolves when the page navigates to a new URL or reloads. It is useful for when you run code which will indirectly
|
|
1633
1641
|
# cause the page to navigate. e.g. The click target has an `onclick` handler that triggers navigation from a `setTimeout`.
|
|
1634
1642
|
# Consider this example:
|
|
1635
|
-
#
|
|
1636
1643
|
#
|
|
1637
|
-
# ```js
|
|
1638
|
-
# const [response] = await Promise.all([
|
|
1639
|
-
# page.waitForNavigation(), // The promise resolves after navigation has finished
|
|
1640
|
-
# page.click('a.delayed-navigation'), // Clicking the link will indirectly cause a navigation
|
|
1641
|
-
# ]);
|
|
1642
|
-
# ```
|
|
1643
|
-
#
|
|
1644
|
-
# ```python async
|
|
1645
|
-
# async with page.expect_navigation():
|
|
1646
|
-
# await page.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
|
|
1647
|
-
# # Resolves after navigation has finished
|
|
1648
|
-
# ```
|
|
1649
|
-
#
|
|
1650
1644
|
# ```python sync
|
|
1651
1645
|
# with page.expect_navigation():
|
|
1652
|
-
#
|
|
1646
|
+
# # This action triggers the navigation after a timeout.
|
|
1647
|
+
# page.get_by_text("Navigate after timeout").click()
|
|
1653
1648
|
# # Resolves after navigation has finished
|
|
1654
1649
|
# ```
|
|
1655
|
-
#
|
|
1656
|
-
#
|
|
1657
|
-
#
|
|
1658
|
-
#
|
|
1659
|
-
#
|
|
1650
|
+
#
|
|
1651
|
+
# **NOTE**: Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is considered
|
|
1652
|
+
# a navigation.
|
|
1653
|
+
#
|
|
1654
|
+
# @deprecated This method is inherently racy, please use [`method: Page.waitForURL`] instead.
|
|
1660
1655
|
def expect_navigation(timeout: nil, url: nil, waitUntil: nil, &block)
|
|
1661
1656
|
wrap_impl(@impl.expect_navigation(timeout: unwrap_impl(timeout), url: unwrap_impl(url), waitUntil: unwrap_impl(waitUntil), &wrap_block_call(block)))
|
|
1662
1657
|
end
|
|
1663
1658
|
|
|
1664
|
-
# Waits for the matching request and returns it.
|
|
1665
|
-
#
|
|
1666
1659
|
#
|
|
1667
|
-
#
|
|
1668
|
-
#
|
|
1669
|
-
#
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
#
|
|
1675
|
-
#
|
|
1676
|
-
#
|
|
1677
|
-
#
|
|
1678
|
-
#
|
|
1679
|
-
# await page.click('img')
|
|
1680
|
-
# second_request = await second.value
|
|
1681
|
-
# ```
|
|
1682
|
-
#
|
|
1660
|
+
# Performs action and waits for a popup `Page`. If predicate is provided, it passes
|
|
1661
|
+
# [Popup] value into the `predicate` function and waits for `predicate(page)` to return a truthy value.
|
|
1662
|
+
# Will throw an error if the page is closed before the popup event is fired.
|
|
1663
|
+
def expect_popup(predicate: nil, timeout: nil, &block)
|
|
1664
|
+
wrap_impl(@impl.expect_popup(predicate: unwrap_impl(predicate), timeout: unwrap_impl(timeout), &wrap_block_call(block)))
|
|
1665
|
+
end
|
|
1666
|
+
|
|
1667
|
+
#
|
|
1668
|
+
# Waits for the matching request and returns it. See [waiting for event](../events.md#waiting-for-event) for more details about events.
|
|
1669
|
+
#
|
|
1670
|
+
# **Usage**
|
|
1671
|
+
#
|
|
1683
1672
|
# ```python sync
|
|
1684
1673
|
# with page.expect_request("http://example.com/resource") as first:
|
|
1685
|
-
# page.click(
|
|
1674
|
+
# page.get_by_text("trigger request").click()
|
|
1686
1675
|
# first_request = first.value
|
|
1687
|
-
#
|
|
1676
|
+
#
|
|
1677
|
+
# # or with a lambda
|
|
1688
1678
|
# with page.expect_request(lambda request: request.url == "http://example.com" and request.method == "get") as second:
|
|
1689
|
-
# page.click(
|
|
1679
|
+
# page.get_by_text("trigger request").click()
|
|
1690
1680
|
# second_request = second.value
|
|
1691
1681
|
# ```
|
|
1692
|
-
|
|
1682
|
+
def expect_request(urlOrPredicate, timeout: nil, &block)
|
|
1683
|
+
wrap_impl(@impl.expect_request(unwrap_impl(urlOrPredicate), timeout: unwrap_impl(timeout), &wrap_block_call(block)))
|
|
1684
|
+
end
|
|
1685
|
+
|
|
1693
1686
|
#
|
|
1694
|
-
#
|
|
1695
|
-
#
|
|
1696
|
-
#
|
|
1697
|
-
def
|
|
1698
|
-
wrap_impl(@impl.
|
|
1687
|
+
# Performs action and waits for a `Request` to finish loading. If predicate is provided, it passes
|
|
1688
|
+
# `Request` value into the `predicate` function and waits for `predicate(request)` to return a truthy value.
|
|
1689
|
+
# Will throw an error if the page is closed before the [`event: Page.requestFinished`] event is fired.
|
|
1690
|
+
def expect_request_finished(predicate: nil, timeout: nil, &block)
|
|
1691
|
+
wrap_impl(@impl.expect_request_finished(predicate: unwrap_impl(predicate), timeout: unwrap_impl(timeout), &wrap_block_call(block)))
|
|
1699
1692
|
end
|
|
1700
1693
|
|
|
1701
|
-
# Returns the matched response.
|
|
1702
|
-
#
|
|
1703
1694
|
#
|
|
1704
|
-
#
|
|
1705
|
-
#
|
|
1706
|
-
#
|
|
1707
|
-
#
|
|
1708
|
-
# ```
|
|
1709
|
-
#
|
|
1710
|
-
# ```python async
|
|
1711
|
-
# first_response = await page.wait_for_response("https://example.com/resource")
|
|
1712
|
-
# final_response = await page.wait_for_response(lambda response: response.url == "https://example.com" and response.status === 200)
|
|
1713
|
-
# return final_response.ok
|
|
1714
|
-
# ```
|
|
1715
|
-
#
|
|
1695
|
+
# Returns the matched response. See [waiting for event](../events.md#waiting-for-event) for more details about events.
|
|
1696
|
+
#
|
|
1697
|
+
# **Usage**
|
|
1698
|
+
#
|
|
1716
1699
|
# ```python sync
|
|
1717
|
-
#
|
|
1718
|
-
#
|
|
1719
|
-
#
|
|
1700
|
+
# with page.expect_response("https://example.com/resource") as response_info:
|
|
1701
|
+
# page.get_by_text("trigger response").click()
|
|
1702
|
+
# response = response_info.value
|
|
1703
|
+
# return response.ok
|
|
1704
|
+
#
|
|
1705
|
+
# # or with a lambda
|
|
1706
|
+
# with page.expect_response(lambda response: response.url == "https://example.com" and response.status == 200 and response.request.method == "get") as response_info:
|
|
1707
|
+
# page.get_by_text("trigger response").click()
|
|
1708
|
+
# response = response_info.value
|
|
1709
|
+
# return response.ok
|
|
1720
1710
|
# ```
|
|
1721
|
-
def expect_response(urlOrPredicate, timeout: nil)
|
|
1722
|
-
wrap_impl(@impl.expect_response(unwrap_impl(urlOrPredicate), timeout: unwrap_impl(timeout)))
|
|
1711
|
+
def expect_response(urlOrPredicate, timeout: nil, &block)
|
|
1712
|
+
wrap_impl(@impl.expect_response(unwrap_impl(urlOrPredicate), timeout: unwrap_impl(timeout), &wrap_block_call(block)))
|
|
1723
1713
|
end
|
|
1724
1714
|
|
|
1715
|
+
#
|
|
1725
1716
|
# Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
|
|
1726
1717
|
# `detached`.
|
|
1727
|
-
#
|
|
1728
|
-
#
|
|
1729
|
-
#
|
|
1730
|
-
#
|
|
1731
|
-
#
|
|
1718
|
+
#
|
|
1719
|
+
# **NOTE**: Playwright automatically waits for element to be ready before performing an action. Using
|
|
1720
|
+
# `Locator` objects and web-first assertions makes the code wait-for-selector-free.
|
|
1721
|
+
#
|
|
1722
|
+
# Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become
|
|
1723
|
+
# visible/hidden). If at the moment of calling the method `selector` already satisfies the condition, the method
|
|
1724
|
+
# will return immediately. If the selector doesn't satisfy the condition for the `timeout` milliseconds, the
|
|
1725
|
+
# function will throw.
|
|
1726
|
+
#
|
|
1727
|
+
# **Usage**
|
|
1728
|
+
#
|
|
1732
1729
|
# This method works across navigations:
|
|
1733
|
-
#
|
|
1734
|
-
#
|
|
1735
|
-
# ```js
|
|
1736
|
-
# const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
|
|
1737
|
-
#
|
|
1738
|
-
# (async () => {
|
|
1739
|
-
# const browser = await chromium.launch();
|
|
1740
|
-
# const page = await browser.newPage();
|
|
1741
|
-
# for (let currentURL of ['https://google.com', 'https://bbc.com']) {
|
|
1742
|
-
# await page.goto(currentURL);
|
|
1743
|
-
# const element = await page.waitForSelector('img');
|
|
1744
|
-
# console.log('Loaded image: ' + await element.getAttribute('src'));
|
|
1745
|
-
# }
|
|
1746
|
-
# await browser.close();
|
|
1747
|
-
# })();
|
|
1748
|
-
# ```
|
|
1749
|
-
#
|
|
1750
|
-
# ```python async
|
|
1751
|
-
# import asyncio
|
|
1752
|
-
# from playwright.async_api import async_playwright
|
|
1753
|
-
#
|
|
1754
|
-
# async def run(playwright):
|
|
1755
|
-
# chromium = playwright.chromium
|
|
1756
|
-
# browser = await chromium.launch()
|
|
1757
|
-
# page = await browser.new_page()
|
|
1758
|
-
# for current_url in ["https://google.com", "https://bbc.com"]:
|
|
1759
|
-
# await page.goto(current_url, wait_until="domcontentloaded")
|
|
1760
|
-
# element = await page.wait_for_selector("img")
|
|
1761
|
-
# print("Loaded image: " + str(await element.get_attribute("src")))
|
|
1762
|
-
# await browser.close()
|
|
1763
|
-
#
|
|
1764
|
-
# async def main():
|
|
1765
|
-
# async with async_playwright() as playwright:
|
|
1766
|
-
# await run(playwright)
|
|
1767
|
-
# asyncio.run(main())
|
|
1768
|
-
# ```
|
|
1769
|
-
#
|
|
1730
|
+
#
|
|
1770
1731
|
# ```python sync
|
|
1771
|
-
# from playwright.sync_api import sync_playwright
|
|
1772
|
-
#
|
|
1773
|
-
# def run(playwright):
|
|
1732
|
+
# from playwright.sync_api import sync_playwright, Playwright
|
|
1733
|
+
#
|
|
1734
|
+
# def run(playwright: Playwright):
|
|
1774
1735
|
# chromium = playwright.chromium
|
|
1775
1736
|
# browser = chromium.launch()
|
|
1776
1737
|
# page = browser.new_page()
|
|
@@ -1779,51 +1740,101 @@ module Playwright
|
|
|
1779
1740
|
# element = page.wait_for_selector("img")
|
|
1780
1741
|
# print("Loaded image: " + str(element.get_attribute("src")))
|
|
1781
1742
|
# browser.close()
|
|
1782
|
-
#
|
|
1743
|
+
#
|
|
1783
1744
|
# with sync_playwright() as playwright:
|
|
1784
1745
|
# run(playwright)
|
|
1785
1746
|
# ```
|
|
1786
|
-
def wait_for_selector(selector, state: nil, timeout: nil)
|
|
1787
|
-
|
|
1747
|
+
def wait_for_selector(selector, state: nil, strict: nil, timeout: nil)
|
|
1748
|
+
wrap_impl(@impl.wait_for_selector(unwrap_impl(selector), state: unwrap_impl(state), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
|
1788
1749
|
end
|
|
1789
1750
|
|
|
1751
|
+
#
|
|
1790
1752
|
# Waits for the given `timeout` in milliseconds.
|
|
1791
|
-
#
|
|
1753
|
+
#
|
|
1792
1754
|
# Note that `page.waitForTimeout()` should only be used for debugging. Tests using the timer in production are going to be
|
|
1793
1755
|
# flaky. Use signals such as network events, selectors becoming visible and others instead.
|
|
1794
|
-
#
|
|
1795
1756
|
#
|
|
1796
|
-
#
|
|
1797
|
-
#
|
|
1798
|
-
# await page.waitForTimeout(1000);
|
|
1799
|
-
# ```
|
|
1800
|
-
#
|
|
1801
|
-
# ```python async
|
|
1802
|
-
# # wait for 1 second
|
|
1803
|
-
# await page.wait_for_timeout(1000)
|
|
1804
|
-
# ```
|
|
1805
|
-
#
|
|
1757
|
+
# **Usage**
|
|
1758
|
+
#
|
|
1806
1759
|
# ```python sync
|
|
1807
1760
|
# # wait for 1 second
|
|
1808
1761
|
# page.wait_for_timeout(1000)
|
|
1809
1762
|
# ```
|
|
1810
|
-
#
|
|
1811
|
-
# Shortcut for main frame's [`method: Frame.waitForTimeout`].
|
|
1812
1763
|
def wait_for_timeout(timeout)
|
|
1813
|
-
|
|
1764
|
+
wrap_impl(@impl.wait_for_timeout(unwrap_impl(timeout)))
|
|
1814
1765
|
end
|
|
1815
1766
|
|
|
1767
|
+
#
|
|
1768
|
+
# Waits for the main frame to navigate to the given URL.
|
|
1769
|
+
#
|
|
1770
|
+
# **Usage**
|
|
1771
|
+
#
|
|
1772
|
+
# ```python sync
|
|
1773
|
+
# page.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
|
|
1774
|
+
# page.wait_for_url("**/target.html")
|
|
1775
|
+
# ```
|
|
1776
|
+
def wait_for_url(url, timeout: nil, waitUntil: nil)
|
|
1777
|
+
wrap_impl(@impl.wait_for_url(unwrap_impl(url), timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
|
|
1778
|
+
end
|
|
1779
|
+
|
|
1780
|
+
#
|
|
1781
|
+
# Performs action and waits for a new `WebSocket`. If predicate is provided, it passes
|
|
1782
|
+
# `WebSocket` value into the `predicate` function and waits for `predicate(webSocket)` to return a truthy value.
|
|
1783
|
+
# Will throw an error if the page is closed before the WebSocket event is fired.
|
|
1784
|
+
def expect_websocket(predicate: nil, timeout: nil, &block)
|
|
1785
|
+
wrap_impl(@impl.expect_websocket(predicate: unwrap_impl(predicate), timeout: unwrap_impl(timeout), &wrap_block_call(block)))
|
|
1786
|
+
end
|
|
1787
|
+
|
|
1788
|
+
#
|
|
1789
|
+
# Performs action and waits for a new `Worker`. If predicate is provided, it passes
|
|
1790
|
+
# `Worker` value into the `predicate` function and waits for `predicate(worker)` to return a truthy value.
|
|
1791
|
+
# Will throw an error if the page is closed before the worker event is fired.
|
|
1792
|
+
def expect_worker(predicate: nil, timeout: nil, &block)
|
|
1793
|
+
wrap_impl(@impl.expect_worker(predicate: unwrap_impl(predicate), timeout: unwrap_impl(timeout), &wrap_block_call(block)))
|
|
1794
|
+
end
|
|
1795
|
+
|
|
1796
|
+
#
|
|
1816
1797
|
# This method returns all of the dedicated [WebWorkers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)
|
|
1817
1798
|
# associated with the page.
|
|
1818
|
-
#
|
|
1819
|
-
#
|
|
1799
|
+
#
|
|
1800
|
+
# **NOTE**: This does not contain ServiceWorkers
|
|
1820
1801
|
def workers
|
|
1821
|
-
|
|
1802
|
+
wrap_impl(@impl.workers)
|
|
1803
|
+
end
|
|
1804
|
+
|
|
1805
|
+
#
|
|
1806
|
+
# **NOTE**: In most cases, you should use [`method: Page.waitForEvent`].
|
|
1807
|
+
#
|
|
1808
|
+
# Waits for given `event` to fire. If predicate is provided, it passes
|
|
1809
|
+
# event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
|
|
1810
|
+
# Will throw an error if the page is closed before the `event` is fired.
|
|
1811
|
+
def wait_for_event(event, predicate: nil, timeout: nil)
|
|
1812
|
+
raise NotImplementedError.new('wait_for_event is not implemented yet.')
|
|
1813
|
+
end
|
|
1814
|
+
|
|
1815
|
+
# @nodoc
|
|
1816
|
+
def guid
|
|
1817
|
+
wrap_impl(@impl.guid)
|
|
1818
|
+
end
|
|
1819
|
+
|
|
1820
|
+
# @nodoc
|
|
1821
|
+
def snapshot_for_ai(timeout: nil, mode: nil, track: nil)
|
|
1822
|
+
wrap_impl(@impl.snapshot_for_ai(timeout: unwrap_impl(timeout), mode: unwrap_impl(mode), track: unwrap_impl(track)))
|
|
1823
|
+
end
|
|
1824
|
+
|
|
1825
|
+
# @nodoc
|
|
1826
|
+
def start_js_coverage(resetOnNavigation: nil, reportAnonymousScripts: nil)
|
|
1827
|
+
wrap_impl(@impl.start_js_coverage(resetOnNavigation: unwrap_impl(resetOnNavigation), reportAnonymousScripts: unwrap_impl(reportAnonymousScripts)))
|
|
1822
1828
|
end
|
|
1823
1829
|
|
|
1824
1830
|
# @nodoc
|
|
1825
|
-
def
|
|
1826
|
-
wrap_impl(@impl.
|
|
1831
|
+
def stop_js_coverage
|
|
1832
|
+
wrap_impl(@impl.stop_js_coverage)
|
|
1833
|
+
end
|
|
1834
|
+
|
|
1835
|
+
# @nodoc
|
|
1836
|
+
def start_css_coverage(resetOnNavigation: nil, reportAnonymousScripts: nil)
|
|
1837
|
+
wrap_impl(@impl.start_css_coverage(resetOnNavigation: unwrap_impl(resetOnNavigation), reportAnonymousScripts: unwrap_impl(reportAnonymousScripts)))
|
|
1827
1838
|
end
|
|
1828
1839
|
|
|
1829
1840
|
# @nodoc
|
|
@@ -1831,22 +1842,31 @@ module Playwright
|
|
|
1831
1842
|
wrap_impl(@impl.owned_context=(unwrap_impl(req)))
|
|
1832
1843
|
end
|
|
1833
1844
|
|
|
1845
|
+
# @nodoc
|
|
1846
|
+
def stop_css_coverage
|
|
1847
|
+
wrap_impl(@impl.stop_css_coverage)
|
|
1848
|
+
end
|
|
1849
|
+
|
|
1834
1850
|
# -- inherited from EventEmitter --
|
|
1835
1851
|
# @nodoc
|
|
1836
|
-
def
|
|
1837
|
-
|
|
1852
|
+
def once(event, callback)
|
|
1853
|
+
event_emitter_proxy.once(event, callback)
|
|
1838
1854
|
end
|
|
1839
1855
|
|
|
1840
1856
|
# -- inherited from EventEmitter --
|
|
1841
1857
|
# @nodoc
|
|
1842
|
-
def
|
|
1843
|
-
|
|
1858
|
+
def on(event, callback)
|
|
1859
|
+
event_emitter_proxy.on(event, callback)
|
|
1844
1860
|
end
|
|
1845
1861
|
|
|
1846
1862
|
# -- inherited from EventEmitter --
|
|
1847
1863
|
# @nodoc
|
|
1848
|
-
def
|
|
1849
|
-
|
|
1864
|
+
def off(event, callback)
|
|
1865
|
+
event_emitter_proxy.off(event, callback)
|
|
1866
|
+
end
|
|
1867
|
+
|
|
1868
|
+
private def event_emitter_proxy
|
|
1869
|
+
@event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
|
|
1850
1870
|
end
|
|
1851
1871
|
end
|
|
1852
1872
|
end
|