playwright-ruby-client 0.0.3 → 0.0.8
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/README.md +119 -12
- data/docs/api_coverage.md +354 -0
- data/lib/playwright.rb +8 -0
- data/lib/playwright/channel_owner.rb +16 -2
- data/lib/playwright/channel_owners/android.rb +10 -1
- data/lib/playwright/channel_owners/android_device.rb +163 -0
- data/lib/playwright/channel_owners/browser.rb +22 -29
- data/lib/playwright/channel_owners/browser_context.rb +43 -0
- data/lib/playwright/channel_owners/console_message.rb +21 -0
- data/lib/playwright/channel_owners/element_handle.rb +314 -0
- data/lib/playwright/channel_owners/frame.rb +466 -7
- data/lib/playwright/channel_owners/js_handle.rb +55 -0
- data/lib/playwright/channel_owners/page.rb +353 -5
- data/lib/playwright/channel_owners/request.rb +90 -0
- data/lib/playwright/channel_owners/webkit_browser.rb +1 -1
- data/lib/playwright/connection.rb +15 -14
- data/lib/playwright/errors.rb +1 -1
- data/lib/playwright/event_emitter.rb +13 -0
- data/lib/playwright/input_files.rb +42 -0
- data/lib/playwright/input_type.rb +19 -0
- data/lib/playwright/input_types/android_input.rb +19 -0
- data/lib/playwright/input_types/keyboard.rb +32 -0
- data/lib/playwright/input_types/mouse.rb +4 -0
- data/lib/playwright/input_types/touchscreen.rb +4 -0
- data/lib/playwright/javascript.rb +13 -0
- data/lib/playwright/javascript/expression.rb +67 -0
- data/lib/playwright/javascript/function.rb +67 -0
- data/lib/playwright/javascript/value_parser.rb +75 -0
- data/lib/playwright/javascript/value_serializer.rb +54 -0
- data/lib/playwright/playwright_api.rb +45 -25
- data/lib/playwright/select_option_values.rb +32 -0
- data/lib/playwright/timeout_settings.rb +19 -0
- data/lib/playwright/url_matcher.rb +19 -0
- data/lib/playwright/utils.rb +37 -0
- data/lib/playwright/version.rb +1 -1
- data/lib/playwright/wait_helper.rb +73 -0
- data/lib/playwright_api/accessibility.rb +60 -6
- data/lib/playwright_api/android.rb +33 -0
- data/lib/playwright_api/android_device.rb +78 -0
- data/lib/playwright_api/android_input.rb +25 -0
- data/lib/playwright_api/binding_call.rb +18 -0
- data/lib/playwright_api/browser.rb +136 -44
- data/lib/playwright_api/browser_context.rb +378 -51
- data/lib/playwright_api/browser_type.rb +137 -55
- data/lib/playwright_api/cdp_session.rb +32 -7
- data/lib/playwright_api/chromium_browser_context.rb +31 -0
- data/lib/playwright_api/console_message.rb +27 -7
- data/lib/playwright_api/dialog.rb +47 -3
- data/lib/playwright_api/download.rb +29 -5
- data/lib/playwright_api/element_handle.rb +429 -143
- data/lib/playwright_api/file_chooser.rb +13 -2
- data/lib/playwright_api/frame.rb +633 -179
- data/lib/playwright_api/js_handle.rb +97 -17
- data/lib/playwright_api/keyboard.rb +152 -24
- data/lib/playwright_api/mouse.rb +28 -3
- data/lib/playwright_api/page.rb +1183 -317
- data/lib/playwright_api/playwright.rb +174 -13
- data/lib/playwright_api/request.rb +115 -30
- data/lib/playwright_api/response.rb +22 -3
- data/lib/playwright_api/route.rb +63 -4
- data/lib/playwright_api/selectors.rb +29 -7
- data/lib/playwright_api/touchscreen.rb +2 -1
- data/lib/playwright_api/video.rb +11 -1
- data/lib/playwright_api/web_socket.rb +5 -5
- data/lib/playwright_api/worker.rb +29 -5
- data/playwright.gemspec +3 -0
- metadata +68 -2
@@ -1,11 +1,20 @@
|
|
1
1
|
module Playwright
|
2
|
-
# FileChooser objects are dispatched by the page in the
|
2
|
+
# `FileChooser` objects are dispatched by the page in the [`event: Page.filechooser`] event.
|
3
|
+
#
|
3
4
|
#
|
4
5
|
# ```js
|
5
6
|
# page.on('filechooser', async (fileChooser) => {
|
6
7
|
# await fileChooser.setFiles('/tmp/myfile.pdf');
|
7
8
|
# });
|
8
9
|
# ```
|
10
|
+
#
|
11
|
+
# ```python async
|
12
|
+
# page.on("filechooser", lambda file_chooser: file_chooser.set_files("/tmp/myfile.pdf"))
|
13
|
+
# ```
|
14
|
+
#
|
15
|
+
# ```python sync
|
16
|
+
# page.on("filechooser", lambda file_chooser: file_chooser.set_files("/tmp/myfile.pdf"))
|
17
|
+
# ```
|
9
18
|
class FileChooser < PlaywrightApi
|
10
19
|
|
11
20
|
# Returns input element associated with this file chooser.
|
@@ -23,9 +32,11 @@ module Playwright
|
|
23
32
|
raise NotImplementedError.new('page is not implemented yet.')
|
24
33
|
end
|
25
34
|
|
26
|
-
# Sets the value of the file input this chooser is associated with. If some of the `filePaths` are relative paths, then
|
35
|
+
# Sets the value of the file input this chooser is associated with. If some of the `filePaths` are relative paths, then
|
36
|
+
# they are resolved relative to the the current working directory. For empty array, clears the selected files.
|
27
37
|
def set_files(files, noWaitAfter: nil, timeout: nil)
|
28
38
|
raise NotImplementedError.new('set_files is not implemented yet.')
|
29
39
|
end
|
40
|
+
alias_method :files=, :set_files
|
30
41
|
end
|
31
42
|
end
|
data/lib/playwright_api/frame.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
module Playwright
|
2
|
-
# At every point of time, page exposes its current frame tree via the `
|
3
|
-
# Frame
|
2
|
+
# At every point of time, page exposes its current frame tree via the [`method: Page.mainFrame`] and
|
3
|
+
# [`method: Frame.childFrames`] methods.
|
4
4
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
5
|
+
# `Frame` object's lifecycle is controlled by three events, dispatched on the page object:
|
6
|
+
# - [`event: Page.frameattached`] - fired when the frame gets attached to the page. A Frame can be attached to the page
|
7
|
+
# only once.
|
8
|
+
# - [`event: Page.framenavigated`] - fired when the frame commits navigation to a different URL.
|
9
|
+
# - [`event: Page.framedetached`] - fired when the frame gets detached from the page. A Frame can be detached from the
|
10
|
+
# page only once.
|
8
11
|
#
|
9
12
|
# An example of dumping frame tree:
|
13
|
+
#
|
10
14
|
#
|
11
15
|
# ```js
|
12
16
|
# const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'.
|
@@ -26,164 +30,278 @@ module Playwright
|
|
26
30
|
# }
|
27
31
|
# })();
|
28
32
|
# ```
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
33
|
+
#
|
34
|
+
# ```python async
|
35
|
+
# import asyncio
|
36
|
+
# from playwright.async_api import async_playwright
|
37
|
+
#
|
38
|
+
# async def run(playwright):
|
39
|
+
# firefox = playwright.firefox
|
40
|
+
# browser = await firefox.launch()
|
41
|
+
# page = await browser.new_page()
|
42
|
+
# await page.goto("https://www.theverge.com")
|
43
|
+
# dump_frame_tree(page.main_frame, "")
|
44
|
+
# await browser.close()
|
45
|
+
#
|
46
|
+
# def dump_frame_tree(frame, indent):
|
47
|
+
# print(indent + frame.name + '@' + frame.url)
|
48
|
+
# for child in frame.child_frames:
|
49
|
+
# dump_frame_tree(child, indent + " ")
|
50
|
+
#
|
51
|
+
# async def main():
|
52
|
+
# async with async_playwright() as playwright:
|
53
|
+
# await run(playwright)
|
54
|
+
# asyncio.run(main())
|
55
|
+
# ```
|
56
|
+
#
|
57
|
+
# ```python sync
|
58
|
+
# from playwright.sync_api import sync_playwright
|
59
|
+
#
|
60
|
+
# def run(playwright):
|
61
|
+
# firefox = playwright.firefox
|
62
|
+
# browser = firefox.launch()
|
63
|
+
# page = browser.new_page()
|
64
|
+
# page.goto("https://www.theverge.com")
|
65
|
+
# dump_frame_tree(page.main_frame, "")
|
66
|
+
# browser.close()
|
67
|
+
#
|
68
|
+
# def dump_frame_tree(frame, indent):
|
69
|
+
# print(indent + frame.name + '@' + frame.url)
|
70
|
+
# for child in frame.child_frames:
|
71
|
+
# dump_frame_tree(child, indent + " ")
|
72
|
+
#
|
73
|
+
# with sync_playwright() as playwright:
|
74
|
+
# run(playwright)
|
35
75
|
# ```
|
36
76
|
class Frame < PlaywrightApi
|
37
77
|
|
38
78
|
# Returns the ElementHandle pointing to the frame element.
|
39
|
-
#
|
40
|
-
|
41
|
-
|
79
|
+
#
|
80
|
+
# The method finds an element matching the specified selector within the frame. See
|
81
|
+
# [Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
|
82
|
+
# returns `null`.
|
83
|
+
def query_selector(selector)
|
84
|
+
wrap_impl(@impl.query_selector(unwrap_impl(selector)))
|
42
85
|
end
|
43
86
|
|
44
87
|
# Returns the ElementHandles pointing to the frame elements.
|
45
|
-
#
|
46
|
-
|
47
|
-
|
88
|
+
#
|
89
|
+
# The method finds all elements matching the specified selector within the frame. See
|
90
|
+
# [Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
|
91
|
+
# returns empty array.
|
92
|
+
def query_selector_all(selector)
|
93
|
+
wrap_impl(@impl.query_selector_all(unwrap_impl(selector)))
|
48
94
|
end
|
49
95
|
|
50
96
|
# Returns the return value of `pageFunction`
|
51
|
-
#
|
52
|
-
#
|
97
|
+
#
|
98
|
+
# The method finds an element matching the specified selector within the frame and passes it as a first argument to
|
99
|
+
# `pageFunction`. See [Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements
|
100
|
+
# match the selector, the method throws an error.
|
101
|
+
#
|
102
|
+
# If `pageFunction` returns a [Promise], then `frame.$eval` would wait for the promise to resolve and return its value.
|
103
|
+
#
|
53
104
|
# Examples:
|
105
|
+
#
|
54
106
|
#
|
55
107
|
# ```js
|
56
108
|
# const searchValue = await frame.$eval('#search', el => el.value);
|
57
109
|
# const preloadHref = await frame.$eval('link[rel=preload]', el => el.href);
|
58
110
|
# const html = await frame.$eval('.main-container', (e, suffix) => e.outerHTML + suffix, 'hello');
|
59
111
|
# ```
|
60
|
-
|
61
|
-
|
112
|
+
#
|
113
|
+
# ```python async
|
114
|
+
# search_value = await frame.eval_on_selector("#search", "el => el.value")
|
115
|
+
# preload_href = await frame.eval_on_selector("link[rel=preload]", "el => el.href")
|
116
|
+
# html = await frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
|
117
|
+
# ```
|
118
|
+
#
|
119
|
+
# ```python sync
|
120
|
+
# search_value = frame.eval_on_selector("#search", "el => el.value")
|
121
|
+
# preload_href = frame.eval_on_selector("link[rel=preload]", "el => el.href")
|
122
|
+
# html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
|
123
|
+
# ```
|
124
|
+
def eval_on_selector(selector, pageFunction, arg: nil)
|
125
|
+
wrap_impl(@impl.eval_on_selector(unwrap_impl(selector), unwrap_impl(pageFunction), arg: unwrap_impl(arg)))
|
62
126
|
end
|
63
127
|
|
64
128
|
# Returns the return value of `pageFunction`
|
65
|
-
#
|
66
|
-
#
|
129
|
+
#
|
130
|
+
# The method finds all elements matching the specified selector within the frame and passes an array of matched elements
|
131
|
+
# as a first argument to `pageFunction`. See [Working with selectors](./selectors.md#working-with-selectors) for more
|
132
|
+
# details.
|
133
|
+
#
|
134
|
+
# If `pageFunction` returns a [Promise], then `frame.$$eval` would wait for the promise to resolve and return its value.
|
135
|
+
#
|
67
136
|
# Examples:
|
137
|
+
#
|
68
138
|
#
|
69
139
|
# ```js
|
70
140
|
# const divsCounts = await frame.$$eval('div', (divs, min) => divs.length >= min, 10);
|
71
141
|
# ```
|
72
|
-
|
73
|
-
|
142
|
+
#
|
143
|
+
# ```python async
|
144
|
+
# divs_counts = await frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
|
145
|
+
# ```
|
146
|
+
#
|
147
|
+
# ```python sync
|
148
|
+
# divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
|
149
|
+
# ```
|
150
|
+
def eval_on_selector_all(selector, pageFunction, arg: nil)
|
151
|
+
wrap_impl(@impl.eval_on_selector_all(unwrap_impl(selector), unwrap_impl(pageFunction), arg: unwrap_impl(arg)))
|
74
152
|
end
|
75
153
|
|
76
154
|
# Returns the added tag when the script's onload fires or when the script content was injected into frame.
|
155
|
+
#
|
77
156
|
# Adds a `<script>` tag into the page with the desired url or content.
|
78
|
-
def add_script_tag(
|
79
|
-
|
157
|
+
def add_script_tag(content: nil, path: nil, type: nil, url: nil)
|
158
|
+
wrap_impl(@impl.add_script_tag(content: unwrap_impl(content), path: unwrap_impl(path), type: unwrap_impl(type), url: unwrap_impl(url)))
|
80
159
|
end
|
81
160
|
|
82
161
|
# Returns the added tag when the stylesheet's onload fires or when the CSS content was injected into frame.
|
83
|
-
#
|
84
|
-
|
85
|
-
|
162
|
+
#
|
163
|
+
# Adds a `<link rel="stylesheet">` tag into the page with the desired url or a `<style type="text/css">` tag with the
|
164
|
+
# content.
|
165
|
+
def add_style_tag(content: nil, path: nil, url: nil)
|
166
|
+
wrap_impl(@impl.add_style_tag(content: unwrap_impl(content), path: unwrap_impl(path), url: unwrap_impl(url)))
|
86
167
|
end
|
87
168
|
|
88
169
|
# This method checks an element matching `selector` by performing the following steps:
|
170
|
+
# 1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
171
|
+
# 1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already
|
172
|
+
# checked, this method returns immediately.
|
173
|
+
# 1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the
|
174
|
+
# element is detached during the checks, the whole action is retried.
|
175
|
+
# 1. Scroll the element into view if needed.
|
176
|
+
# 1. Use [`property: Page.mouse`] to click in the center of the element.
|
177
|
+
# 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
178
|
+
# 1. Ensure that the element is now checked. If not, this method rejects.
|
89
179
|
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
# Wait for actionability checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
|
93
|
-
# Scroll the element into view if needed.
|
94
|
-
# Use page.mouse to click in the center of the element.
|
95
|
-
# Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
96
|
-
# Ensure that the element is now checked. If not, this method rejects.
|
97
|
-
#
|
98
|
-
# When all steps combined have not finished during the specified `timeout`, this method rejects with a TimeoutError. Passing zero timeout disables this.
|
180
|
+
# When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
|
181
|
+
# Passing zero timeout disables this.
|
99
182
|
def check(selector, force: nil, noWaitAfter: nil, timeout: nil)
|
100
|
-
|
183
|
+
wrap_impl(@impl.check(unwrap_impl(selector), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
101
184
|
end
|
102
185
|
|
103
186
|
def child_frames
|
104
|
-
|
187
|
+
wrap_impl(@impl.child_frames)
|
105
188
|
end
|
106
189
|
|
107
190
|
# This method clicks an element matching `selector` by performing the following steps:
|
191
|
+
# 1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
192
|
+
# 1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the
|
193
|
+
# element is detached during the checks, the whole action is retried.
|
194
|
+
# 1. Scroll the element into view if needed.
|
195
|
+
# 1. Use [`property: Page.mouse`] to click in the center of the element, or the specified `position`.
|
196
|
+
# 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
108
197
|
#
|
109
|
-
#
|
110
|
-
#
|
111
|
-
# Scroll the element into view if needed.
|
112
|
-
# Use page.mouse to click in the center of the element, or the specified `position`.
|
113
|
-
# Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
114
|
-
#
|
115
|
-
# When all steps combined have not finished during the specified `timeout`, this method rejects with a TimeoutError. Passing zero timeout disables this.
|
198
|
+
# When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
|
199
|
+
# Passing zero timeout disables this.
|
116
200
|
def click(
|
117
201
|
selector,
|
118
202
|
button: nil,
|
119
203
|
clickCount: nil,
|
120
204
|
delay: nil,
|
121
|
-
position: nil,
|
122
|
-
modifiers: nil,
|
123
205
|
force: nil,
|
206
|
+
modifiers: nil,
|
124
207
|
noWaitAfter: nil,
|
208
|
+
position: nil,
|
125
209
|
timeout: nil)
|
126
|
-
|
210
|
+
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), timeout: unwrap_impl(timeout)))
|
127
211
|
end
|
128
212
|
|
129
213
|
# Gets the full HTML contents of the frame, including the doctype.
|
130
214
|
def content
|
131
|
-
|
215
|
+
wrap_impl(@impl.content)
|
132
216
|
end
|
133
217
|
|
134
218
|
# This method double clicks an element matching `selector` by performing the following steps:
|
219
|
+
# 1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
220
|
+
# 1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the
|
221
|
+
# element is detached during the checks, the whole action is retried.
|
222
|
+
# 1. Scroll the element into view if needed.
|
223
|
+
# 1. Use [`property: Page.mouse`] to double click in the center of the element, or the specified `position`.
|
224
|
+
# 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. Note that if the
|
225
|
+
# first click of the `dblclick()` triggers a navigation event, this method will reject.
|
135
226
|
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
# Scroll the element into view if needed.
|
139
|
-
# Use page.mouse to double click in the center of the element, or the specified `position`.
|
140
|
-
# Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. Note that if the first click of the `dblclick()` triggers a navigation event, this method will reject.
|
227
|
+
# When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
|
228
|
+
# Passing zero timeout disables this.
|
141
229
|
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
# **NOTE** `frame.dblclick()` dispatches two `click` events and a single `dblclick` event.
|
230
|
+
# > NOTE: `frame.dblclick()` dispatches two `click` events and a single `dblclick` event.
|
145
231
|
def dblclick(
|
146
232
|
selector,
|
147
233
|
button: nil,
|
148
234
|
delay: nil,
|
149
|
-
position: nil,
|
150
|
-
modifiers: nil,
|
151
235
|
force: nil,
|
236
|
+
modifiers: nil,
|
152
237
|
noWaitAfter: nil,
|
238
|
+
position: nil,
|
153
239
|
timeout: nil)
|
154
|
-
|
240
|
+
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), timeout: unwrap_impl(timeout)))
|
155
241
|
end
|
156
242
|
|
157
|
-
# The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the elment, `click`
|
243
|
+
# The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the elment, `click`
|
244
|
+
# is dispatched. This is equivalend to calling
|
245
|
+
# [element.click()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click).
|
246
|
+
#
|
158
247
|
#
|
159
248
|
# ```js
|
160
249
|
# await frame.dispatchEvent('button#submit', 'click');
|
161
250
|
# ```
|
162
|
-
# Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default.
|
163
|
-
# Since `eventInit` is event-specific, please refer to the events documentation for the lists of initial properties:
|
164
251
|
#
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
#
|
170
|
-
#
|
171
|
-
#
|
252
|
+
# ```python async
|
253
|
+
# await frame.dispatch_event("button#submit", "click")
|
254
|
+
# ```
|
255
|
+
#
|
256
|
+
# ```python sync
|
257
|
+
# frame.dispatch_event("button#submit", "click")
|
258
|
+
# ```
|
259
|
+
#
|
260
|
+
# Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties
|
261
|
+
# and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default.
|
262
|
+
#
|
263
|
+
# Since `eventInit` is event-specific, please refer to the events documentation for the lists of initial properties:
|
264
|
+
# - [DragEvent](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/DragEvent)
|
265
|
+
# - [FocusEvent](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/FocusEvent)
|
266
|
+
# - [KeyboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent)
|
267
|
+
# - [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent)
|
268
|
+
# - [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/PointerEvent)
|
269
|
+
# - [TouchEvent](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/TouchEvent)
|
270
|
+
# - [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event/Event)
|
172
271
|
#
|
173
272
|
# You can also specify `JSHandle` as the property value if you want live objects to be passed into the event:
|
273
|
+
#
|
174
274
|
#
|
175
275
|
# ```js
|
176
276
|
# // Note you can only create DataTransfer in Chromium and Firefox
|
177
277
|
# const dataTransfer = await frame.evaluateHandle(() => new DataTransfer());
|
178
278
|
# await frame.dispatchEvent('#source', 'dragstart', { dataTransfer });
|
179
279
|
# ```
|
280
|
+
#
|
281
|
+
# ```python async
|
282
|
+
# # note you can only create data_transfer in chromium and firefox
|
283
|
+
# data_transfer = await frame.evaluate_handle("new DataTransfer()")
|
284
|
+
# await frame.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
|
285
|
+
# ```
|
286
|
+
#
|
287
|
+
# ```python sync
|
288
|
+
# # note you can only create data_transfer in chromium and firefox
|
289
|
+
# data_transfer = frame.evaluate_handle("new DataTransfer()")
|
290
|
+
# frame.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
|
291
|
+
# ```
|
180
292
|
def dispatch_event(selector, type, eventInit: nil, timeout: nil)
|
181
|
-
|
293
|
+
wrap_impl(@impl.dispatch_event(unwrap_impl(selector), unwrap_impl(type), eventInit: unwrap_impl(eventInit), timeout: unwrap_impl(timeout)))
|
182
294
|
end
|
183
295
|
|
184
296
|
# Returns the return value of `pageFunction`
|
185
|
-
#
|
186
|
-
# If the function passed to the `
|
297
|
+
#
|
298
|
+
# If the function passed to the [`method: Frame.evaluate`] returns a [Promise], then [`method: Frame.evaluate`] would wait
|
299
|
+
# for the promise to resolve and return its value.
|
300
|
+
#
|
301
|
+
# If the function passed to the [`method: Frame.evaluate`] returns a non-[Serializable] value,
|
302
|
+
# then[ method: `Frame.evaluate`] returns `undefined`. DevTools Protocol also supports transferring some additional values
|
303
|
+
# that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
|
304
|
+
#
|
187
305
|
#
|
188
306
|
# ```js
|
189
307
|
# const result = await frame.evaluate(([x, y]) => {
|
@@ -191,36 +309,102 @@ module Playwright
|
|
191
309
|
# }, [7, 8]);
|
192
310
|
# console.log(result); // prints "56"
|
193
311
|
# ```
|
312
|
+
#
|
313
|
+
# ```python async
|
314
|
+
# result = await frame.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
|
315
|
+
# print(result) # prints "56"
|
316
|
+
# ```
|
317
|
+
#
|
318
|
+
# ```python sync
|
319
|
+
# result = frame.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
|
320
|
+
# print(result) # prints "56"
|
321
|
+
# ```
|
322
|
+
#
|
194
323
|
# A string can also be passed in instead of a function.
|
324
|
+
#
|
195
325
|
#
|
196
326
|
# ```js
|
197
327
|
# console.log(await frame.evaluate('1 + 2')); // prints "3"
|
198
328
|
# ```
|
199
|
-
#
|
329
|
+
#
|
330
|
+
# ```python async
|
331
|
+
# print(await frame.evaluate("1 + 2")) # prints "3"
|
332
|
+
# x = 10
|
333
|
+
# print(await frame.evaluate(f"1 + {x}")) # prints "11"
|
334
|
+
# ```
|
335
|
+
#
|
336
|
+
# ```python sync
|
337
|
+
# print(frame.evaluate("1 + 2")) # prints "3"
|
338
|
+
# x = 10
|
339
|
+
# print(frame.evaluate(f"1 + {x}")) # prints "11"
|
340
|
+
# ```
|
341
|
+
#
|
342
|
+
# `ElementHandle` instances can be passed as an argument to the [`method: Frame.evaluate`]:
|
343
|
+
#
|
200
344
|
#
|
201
345
|
# ```js
|
202
346
|
# const bodyHandle = await frame.$('body');
|
203
347
|
# const html = await frame.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']);
|
204
348
|
# await bodyHandle.dispose();
|
205
349
|
# ```
|
350
|
+
#
|
351
|
+
# ```python async
|
352
|
+
# body_handle = await frame.query_selector("body")
|
353
|
+
# html = await frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
|
354
|
+
# await body_handle.dispose()
|
355
|
+
# ```
|
356
|
+
#
|
357
|
+
# ```python sync
|
358
|
+
# body_handle = frame.query_selector("body")
|
359
|
+
# html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
|
360
|
+
# body_handle.dispose()
|
361
|
+
# ```
|
206
362
|
def evaluate(pageFunction, arg: nil)
|
207
|
-
|
363
|
+
wrap_impl(@impl.evaluate(unwrap_impl(pageFunction), arg: unwrap_impl(arg)))
|
208
364
|
end
|
209
365
|
|
210
366
|
# Returns the return value of `pageFunction` as in-page object (JSHandle).
|
211
|
-
#
|
212
|
-
#
|
367
|
+
#
|
368
|
+
# The only difference between [`method: Frame.evaluate`] and [`method: Frame.evaluateHandle`] is
|
369
|
+
# that[ method: Fframe.evaluateHandle`] returns in-page object (JSHandle).
|
370
|
+
#
|
371
|
+
# If the function, passed to the [`method: Frame.evaluateHandle`], returns a [Promise],
|
372
|
+
# then[ method: Fframe.evaluateHandle`] would wait for the promise to resolve and return its value.
|
373
|
+
#
|
213
374
|
#
|
214
375
|
# ```js
|
215
376
|
# const aWindowHandle = await frame.evaluateHandle(() => Promise.resolve(window));
|
216
377
|
# aWindowHandle; // Handle for the window object.
|
217
378
|
# ```
|
379
|
+
#
|
380
|
+
# ```python async
|
381
|
+
# # FIXME
|
382
|
+
# a_window_handle = await frame.evaluate_handle("Promise.resolve(window)")
|
383
|
+
# a_window_handle # handle for the window object.
|
384
|
+
# ```
|
385
|
+
#
|
386
|
+
# ```python sync
|
387
|
+
# a_window_handle = frame.evaluate_handle("Promise.resolve(window)")
|
388
|
+
# a_window_handle # handle for the window object.
|
389
|
+
# ```
|
390
|
+
#
|
218
391
|
# A string can also be passed in instead of a function.
|
392
|
+
#
|
219
393
|
#
|
220
394
|
# ```js
|
221
395
|
# const aHandle = await frame.evaluateHandle('document'); // Handle for the 'document'.
|
222
396
|
# ```
|
223
|
-
#
|
397
|
+
#
|
398
|
+
# ```python async
|
399
|
+
# a_handle = await page.evaluate_handle("document") # handle for the "document"
|
400
|
+
# ```
|
401
|
+
#
|
402
|
+
# ```python sync
|
403
|
+
# a_handle = page.evaluate_handle("document") # handle for the "document"
|
404
|
+
# ```
|
405
|
+
#
|
406
|
+
# `JSHandle` instances can be passed as an argument to the [`method: Frame.evaluateHandle`]:
|
407
|
+
#
|
224
408
|
#
|
225
409
|
# ```js
|
226
410
|
# const aHandle = await frame.evaluateHandle(() => document.body);
|
@@ -228,124 +412,211 @@ module Playwright
|
|
228
412
|
# console.log(await resultHandle.jsonValue());
|
229
413
|
# await resultHandle.dispose();
|
230
414
|
# ```
|
415
|
+
#
|
416
|
+
# ```python async
|
417
|
+
# a_handle = await page.evaluate_handle("document.body")
|
418
|
+
# result_handle = await page.evaluate_handle("body => body.innerHTML", a_handle)
|
419
|
+
# print(await result_handle.json_value())
|
420
|
+
# await result_handle.dispose()
|
421
|
+
# ```
|
422
|
+
#
|
423
|
+
# ```python sync
|
424
|
+
# a_handle = page.evaluate_handle("document.body")
|
425
|
+
# result_handle = page.evaluate_handle("body => body.innerHTML", a_handle)
|
426
|
+
# print(result_handle.json_value())
|
427
|
+
# result_handle.dispose()
|
428
|
+
# ```
|
231
429
|
def evaluate_handle(pageFunction, arg: nil)
|
232
|
-
|
430
|
+
wrap_impl(@impl.evaluate_handle(unwrap_impl(pageFunction), arg: unwrap_impl(arg)))
|
233
431
|
end
|
234
432
|
|
235
|
-
# This method waits for an element matching `selector`, waits for actionability checks, focuses the
|
236
|
-
#
|
433
|
+
# This method waits for an element matching `selector`, waits for [actionability](./actionability.md) checks, focuses the
|
434
|
+
# element, fills it and triggers an `input` event after filling. If the element matching `selector` is not an `<input>`,
|
435
|
+
# `<textarea>` or `[contenteditable]` element, this method throws an error. Note that you can pass an empty string to
|
436
|
+
# clear the input field.
|
437
|
+
#
|
438
|
+
# To send fine-grained keyboard events, use [`method: Frame.type`].
|
237
439
|
def fill(selector, value, noWaitAfter: nil, timeout: nil)
|
238
|
-
|
440
|
+
wrap_impl(@impl.fill(unwrap_impl(selector), unwrap_impl(value), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
239
441
|
end
|
240
442
|
|
241
|
-
# This method fetches an element with `selector` and focuses it. If there's no element matching `selector`, the method
|
443
|
+
# This method fetches an element with `selector` and focuses it. If there's no element matching `selector`, the method
|
444
|
+
# waits until a matching element appears in the DOM.
|
242
445
|
def focus(selector, timeout: nil)
|
243
|
-
|
446
|
+
wrap_impl(@impl.focus(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
|
244
447
|
end
|
245
448
|
|
246
449
|
# Returns the `frame` or `iframe` element handle which corresponds to this frame.
|
247
|
-
#
|
450
|
+
#
|
451
|
+
# This is an inverse of [`method: ElementHandle.contentFrame`]. Note that returned handle actually belongs to the parent
|
452
|
+
# frame.
|
453
|
+
#
|
248
454
|
# This method throws an error if the frame has been detached before `frameElement()` returns.
|
455
|
+
#
|
249
456
|
#
|
250
457
|
# ```js
|
251
458
|
# const frameElement = await frame.frameElement();
|
252
459
|
# const contentFrame = await frameElement.contentFrame();
|
253
460
|
# console.log(frame === contentFrame); // -> true
|
254
461
|
# ```
|
462
|
+
#
|
463
|
+
# ```python async
|
464
|
+
# frame_element = await frame.frame_element()
|
465
|
+
# content_frame = await frame_element.content_frame()
|
466
|
+
# assert frame == content_frame
|
467
|
+
# ```
|
468
|
+
#
|
469
|
+
# ```python sync
|
470
|
+
# frame_element = frame.frame_element()
|
471
|
+
# content_frame = frame_element.content_frame()
|
472
|
+
# assert frame == content_frame
|
473
|
+
# ```
|
255
474
|
def frame_element
|
256
475
|
raise NotImplementedError.new('frame_element is not implemented yet.')
|
257
476
|
end
|
258
477
|
|
259
478
|
# Returns element attribute value.
|
260
479
|
def get_attribute(selector, name, timeout: nil)
|
261
|
-
|
480
|
+
wrap_impl(@impl.get_attribute(unwrap_impl(selector), unwrap_impl(name), timeout: unwrap_impl(timeout)))
|
262
481
|
end
|
263
482
|
|
264
|
-
# Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
|
265
|
-
#
|
483
|
+
# Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
|
484
|
+
# last redirect.
|
266
485
|
#
|
267
|
-
#
|
268
|
-
#
|
269
|
-
#
|
270
|
-
# the
|
271
|
-
# the
|
486
|
+
# `frame.goto` will throw an error if:
|
487
|
+
# - there's an SSL error (e.g. in case of self-signed certificates).
|
488
|
+
# - target URL is invalid.
|
489
|
+
# - the `timeout` is exceeded during navigation.
|
490
|
+
# - the remote server does not respond or is unreachable.
|
491
|
+
# - the main resource failed to load.
|
272
492
|
#
|
273
|
-
# `frame.goto` will not throw an error when any valid HTTP status code is returned by the remote server, including 404
|
493
|
+
# `frame.goto` will not throw an error when any valid HTTP status code is returned by the remote server, including 404
|
494
|
+
# "Not Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling
|
495
|
+
# [`method: Response.status`].
|
274
496
|
#
|
275
|
-
#
|
276
|
-
#
|
277
|
-
|
278
|
-
|
497
|
+
# > NOTE: `frame.goto` either throws an error or returns a main resource response. The only exceptions are navigation to
|
498
|
+
# `about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.
|
499
|
+
# > NOTE: Headless mode doesn't support navigation to a PDF document. See the
|
500
|
+
# [upstream issue](https://bugs.chromium.org/p/chromium/issues/detail?id=761295).
|
501
|
+
def goto(url, referer: nil, timeout: nil, waitUntil: nil)
|
502
|
+
wrap_impl(@impl.goto(unwrap_impl(url), referer: unwrap_impl(referer), timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
|
279
503
|
end
|
280
504
|
|
281
505
|
# This method hovers over an element matching `selector` by performing the following steps:
|
506
|
+
# 1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
507
|
+
# 1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the
|
508
|
+
# element is detached during the checks, the whole action is retried.
|
509
|
+
# 1. Scroll the element into view if needed.
|
510
|
+
# 1. Use [`property: Page.mouse`] to hover over the center of the element, or the specified `position`.
|
511
|
+
# 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
282
512
|
#
|
283
|
-
#
|
284
|
-
#
|
285
|
-
# Scroll the element into view if needed.
|
286
|
-
# Use page.mouse to hover over the center of the element, or the specified `position`.
|
287
|
-
# Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
288
|
-
#
|
289
|
-
# When all steps combined have not finished during the specified `timeout`, this method rejects with a TimeoutError. Passing zero timeout disables this.
|
513
|
+
# When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
|
514
|
+
# Passing zero timeout disables this.
|
290
515
|
def hover(
|
291
516
|
selector,
|
292
|
-
position: nil,
|
293
|
-
modifiers: nil,
|
294
517
|
force: nil,
|
518
|
+
modifiers: nil,
|
519
|
+
position: nil,
|
295
520
|
timeout: nil)
|
296
|
-
|
521
|
+
wrap_impl(@impl.hover(unwrap_impl(selector), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), position: unwrap_impl(position), timeout: unwrap_impl(timeout)))
|
297
522
|
end
|
298
523
|
|
299
524
|
# Returns `element.innerHTML`.
|
300
525
|
def inner_html(selector, timeout: nil)
|
301
|
-
|
526
|
+
wrap_impl(@impl.inner_html(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
|
302
527
|
end
|
303
528
|
|
304
529
|
# Returns `element.innerText`.
|
305
530
|
def inner_text(selector, timeout: nil)
|
306
|
-
|
531
|
+
wrap_impl(@impl.inner_text(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
|
532
|
+
end
|
533
|
+
|
534
|
+
# Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
|
535
|
+
def checked?(selector, timeout: nil)
|
536
|
+
wrap_impl(@impl.checked?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
|
307
537
|
end
|
308
538
|
|
309
539
|
# Returns `true` if the frame has been detached, or `false` otherwise.
|
310
540
|
def detached?
|
311
|
-
|
541
|
+
wrap_impl(@impl.detached?)
|
542
|
+
end
|
543
|
+
|
544
|
+
# Returns whether the element is disabled, the opposite of [enabled](./actionability.md#enabled).
|
545
|
+
def disabled?(selector, timeout: nil)
|
546
|
+
wrap_impl(@impl.disabled?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
|
547
|
+
end
|
548
|
+
|
549
|
+
# Returns whether the element is [editable](./actionability.md#editable).
|
550
|
+
def editable?(selector, timeout: nil)
|
551
|
+
wrap_impl(@impl.editable?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
|
552
|
+
end
|
553
|
+
|
554
|
+
# Returns whether the element is [enabled](./actionability.md#enabled).
|
555
|
+
def enabled?(selector, timeout: nil)
|
556
|
+
wrap_impl(@impl.enabled?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
|
557
|
+
end
|
558
|
+
|
559
|
+
# Returns whether the element is hidden, the opposite of [visible](./actionability.md#visible).
|
560
|
+
def hidden?(selector, timeout: nil)
|
561
|
+
wrap_impl(@impl.hidden?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
|
562
|
+
end
|
563
|
+
|
564
|
+
# Returns whether the element is [visible](./actionability.md#visible).
|
565
|
+
def visible?(selector, timeout: nil)
|
566
|
+
wrap_impl(@impl.visible?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
|
312
567
|
end
|
313
568
|
|
314
569
|
# Returns frame's name attribute as specified in the tag.
|
570
|
+
#
|
315
571
|
# If the name is empty, returns the id attribute instead.
|
316
572
|
#
|
317
|
-
#
|
573
|
+
# > NOTE: This value is calculated once when the frame is created, and will not update if the attribute is changed later.
|
318
574
|
def name
|
319
|
-
|
575
|
+
wrap_impl(@impl.name)
|
320
576
|
end
|
321
577
|
|
322
578
|
# Returns the page containing this frame.
|
323
579
|
def page
|
324
|
-
|
580
|
+
wrap_impl(@impl.page)
|
325
581
|
end
|
326
582
|
|
327
583
|
# Parent frame, if any. Detached frames and main frames return `null`.
|
328
584
|
def parent_frame
|
329
|
-
|
585
|
+
wrap_impl(@impl.parent_frame)
|
330
586
|
end
|
331
587
|
|
332
|
-
# `key` can specify the intended keyboardEvent.key
|
333
|
-
#
|
334
|
-
#
|
588
|
+
# `key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)
|
589
|
+
# value or a single character to generate the text for. A superset of the `key` values can be found
|
590
|
+
# [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are:
|
591
|
+
#
|
592
|
+
# `F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`,
|
593
|
+
# `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
|
594
|
+
#
|
595
|
+
# Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
|
596
|
+
#
|
335
597
|
# Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
336
|
-
#
|
337
|
-
#
|
598
|
+
#
|
599
|
+
# If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective
|
600
|
+
# texts.
|
601
|
+
#
|
602
|
+
# Shortcuts such as `key: "Control+o"` or `key: "Control+Shift+T"` are supported as well. When speficied with the
|
603
|
+
# modifier, modifier is pressed and being held while the subsequent key is being pressed.
|
338
604
|
def press(
|
339
605
|
selector,
|
340
606
|
key,
|
341
607
|
delay: nil,
|
342
608
|
noWaitAfter: nil,
|
343
609
|
timeout: nil)
|
344
|
-
|
610
|
+
wrap_impl(@impl.press(unwrap_impl(selector), unwrap_impl(key), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
345
611
|
end
|
346
612
|
|
347
613
|
# Returns the array of option values that have been successfully selected.
|
348
|
-
#
|
614
|
+
#
|
615
|
+
# Triggers a `change` and `input` event once all the provided options have been selected. If there's no `<select>` element
|
616
|
+
# matching `selector`, the method throws an error.
|
617
|
+
#
|
618
|
+
# Will wait until all specified options are present in the `<select>` element.
|
619
|
+
#
|
349
620
|
#
|
350
621
|
# ```js
|
351
622
|
# // single selection matching the value
|
@@ -357,89 +628,129 @@ module Playwright
|
|
357
628
|
# // multiple selection
|
358
629
|
# frame.selectOption('select#colors', 'red', 'green', 'blue');
|
359
630
|
# ```
|
631
|
+
#
|
632
|
+
# ```python async
|
633
|
+
# # single selection matching the value
|
634
|
+
# await frame.select_option("select#colors", "blue")
|
635
|
+
# # single selection matching the label
|
636
|
+
# await frame.select_option("select#colors", label="blue")
|
637
|
+
# # multiple selection
|
638
|
+
# await frame.select_option("select#colors", value=["red", "green", "blue"])
|
639
|
+
# ```
|
640
|
+
#
|
641
|
+
# ```python sync
|
642
|
+
# # single selection matching the value
|
643
|
+
# frame.select_option("select#colors", "blue")
|
644
|
+
# # single selection matching both the label
|
645
|
+
# frame.select_option("select#colors", label="blue")
|
646
|
+
# # multiple selection
|
647
|
+
# frame.select_option("select#colors", value=["red", "green", "blue"])
|
648
|
+
# ```
|
360
649
|
def select_option(selector, values, noWaitAfter: nil, timeout: nil)
|
361
|
-
|
650
|
+
wrap_impl(@impl.select_option(unwrap_impl(selector), unwrap_impl(values), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
362
651
|
end
|
363
652
|
|
364
653
|
def set_content(html, timeout: nil, waitUntil: nil)
|
365
|
-
|
654
|
+
wrap_impl(@impl.set_content(unwrap_impl(html), timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
|
366
655
|
end
|
656
|
+
alias_method :content=, :set_content
|
367
657
|
|
368
|
-
# This method expects `selector` to point to an
|
369
|
-
#
|
658
|
+
# This method expects `selector` to point to an
|
659
|
+
# [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
|
660
|
+
#
|
661
|
+
# Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
|
662
|
+
# are resolved relative to the the current working directory. For empty array, clears the selected files.
|
370
663
|
def set_input_files(selector, files, noWaitAfter: nil, timeout: nil)
|
371
|
-
|
664
|
+
wrap_impl(@impl.set_input_files(unwrap_impl(selector), unwrap_impl(files), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
372
665
|
end
|
373
666
|
|
374
667
|
# This method taps an element matching `selector` by performing the following steps:
|
668
|
+
# 1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
669
|
+
# 1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the
|
670
|
+
# element is detached during the checks, the whole action is retried.
|
671
|
+
# 1. Scroll the element into view if needed.
|
672
|
+
# 1. Use [`property: Page.touchscreen`] to tap the center of the element, or the specified `position`.
|
673
|
+
# 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
375
674
|
#
|
376
|
-
#
|
377
|
-
#
|
378
|
-
# Scroll the element into view if needed.
|
379
|
-
# Use page.touchscreen to tap the center of the element, or the specified `position`.
|
380
|
-
# Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
675
|
+
# When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
|
676
|
+
# Passing zero timeout disables this.
|
381
677
|
#
|
382
|
-
#
|
383
|
-
#
|
384
|
-
# **NOTE** `frame.tap()` requires that the `hasTouch` option of the browser context be set to true.
|
678
|
+
# > NOTE: `frame.tap()` requires that the `hasTouch` option of the browser context be set to true.
|
385
679
|
def tap_point(
|
386
680
|
selector,
|
387
|
-
|
681
|
+
force: nil,
|
388
682
|
modifiers: nil,
|
389
683
|
noWaitAfter: nil,
|
390
|
-
|
684
|
+
position: nil,
|
391
685
|
timeout: nil)
|
392
|
-
|
686
|
+
wrap_impl(@impl.tap_point(unwrap_impl(selector), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), timeout: unwrap_impl(timeout)))
|
393
687
|
end
|
394
688
|
|
395
689
|
# Returns `element.textContent`.
|
396
690
|
def text_content(selector, timeout: nil)
|
397
|
-
|
691
|
+
wrap_impl(@impl.text_content(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
|
398
692
|
end
|
399
693
|
|
400
694
|
# Returns the page title.
|
401
695
|
def title
|
402
|
-
|
696
|
+
wrap_impl(@impl.title)
|
403
697
|
end
|
404
698
|
|
405
|
-
# Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. `frame.type` can be used to
|
406
|
-
#
|
699
|
+
# Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. `frame.type` can be used to
|
700
|
+
# send fine-grained keyboard events. To fill values in form fields, use [`method: Frame.fill`].
|
701
|
+
#
|
702
|
+
# To press a special key, like `Control` or `ArrowDown`, use [`method: Keyboard.press`].
|
703
|
+
#
|
407
704
|
#
|
408
705
|
# ```js
|
409
706
|
# await frame.type('#mytextarea', 'Hello'); // Types instantly
|
410
707
|
# await frame.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
|
411
708
|
# ```
|
412
|
-
|
709
|
+
#
|
710
|
+
# ```python async
|
711
|
+
# await frame.type("#mytextarea", "hello") # types instantly
|
712
|
+
# await frame.type("#mytextarea", "world", delay=100) # types slower, like a user
|
713
|
+
# ```
|
714
|
+
#
|
715
|
+
# ```python sync
|
716
|
+
# frame.type("#mytextarea", "hello") # types instantly
|
717
|
+
# frame.type("#mytextarea", "world", delay=100) # types slower, like a user
|
718
|
+
# ```
|
719
|
+
def type(
|
413
720
|
selector,
|
414
721
|
text,
|
415
722
|
delay: nil,
|
416
723
|
noWaitAfter: nil,
|
417
724
|
timeout: nil)
|
418
|
-
|
725
|
+
wrap_impl(@impl.type(unwrap_impl(selector), unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
419
726
|
end
|
420
727
|
|
421
728
|
# This method checks an element matching `selector` by performing the following steps:
|
729
|
+
# 1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
730
|
+
# 1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already
|
731
|
+
# unchecked, this method returns immediately.
|
732
|
+
# 1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the
|
733
|
+
# element is detached during the checks, the whole action is retried.
|
734
|
+
# 1. Scroll the element into view if needed.
|
735
|
+
# 1. Use [`property: Page.mouse`] to click in the center of the element.
|
736
|
+
# 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
737
|
+
# 1. Ensure that the element is now unchecked. If not, this method rejects.
|
422
738
|
#
|
423
|
-
#
|
424
|
-
#
|
425
|
-
# Wait for actionability checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
|
426
|
-
# Scroll the element into view if needed.
|
427
|
-
# Use page.mouse to click in the center of the element.
|
428
|
-
# Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
429
|
-
# Ensure that the element is now unchecked. If not, this method rejects.
|
430
|
-
#
|
431
|
-
# When all steps combined have not finished during the specified `timeout`, this method rejects with a TimeoutError. Passing zero timeout disables this.
|
739
|
+
# When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
|
740
|
+
# Passing zero timeout disables this.
|
432
741
|
def uncheck(selector, force: nil, noWaitAfter: nil, timeout: nil)
|
433
|
-
|
742
|
+
wrap_impl(@impl.uncheck(unwrap_impl(selector), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
434
743
|
end
|
435
744
|
|
436
745
|
# Returns frame's url.
|
437
746
|
def url
|
438
|
-
|
747
|
+
wrap_impl(@impl.url)
|
439
748
|
end
|
440
749
|
|
441
750
|
# Returns when the `pageFunction` returns a truthy value, returns that value.
|
751
|
+
#
|
442
752
|
# The `waitForFunction` can be used to observe viewport size change:
|
753
|
+
#
|
443
754
|
#
|
444
755
|
# ```js
|
445
756
|
# const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'.
|
@@ -453,74 +764,217 @@ module Playwright
|
|
453
764
|
# await browser.close();
|
454
765
|
# })();
|
455
766
|
# ```
|
767
|
+
#
|
768
|
+
# ```python async
|
769
|
+
# import asyncio
|
770
|
+
# from playwright.async_api import async_playwright
|
771
|
+
#
|
772
|
+
# async def run(playwright):
|
773
|
+
# webkit = playwright.webkit
|
774
|
+
# browser = await webkit.launch()
|
775
|
+
# page = await browser.new_page()
|
776
|
+
# await page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);", force_expr=True)
|
777
|
+
# await page.main_frame.wait_for_function("() => window.x > 0")
|
778
|
+
# await browser.close()
|
779
|
+
#
|
780
|
+
# async def main():
|
781
|
+
# async with async_playwright() as playwright:
|
782
|
+
# await run(playwright)
|
783
|
+
# asyncio.run(main())
|
784
|
+
# ```
|
785
|
+
#
|
786
|
+
# ```python sync
|
787
|
+
# from playwright.sync_api import sync_playwright
|
788
|
+
#
|
789
|
+
# def run(playwright):
|
790
|
+
# webkit = playwright.webkit
|
791
|
+
# browser = webkit.launch()
|
792
|
+
# page = browser.new_page()
|
793
|
+
# page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);", force_expr=True)
|
794
|
+
# page.main_frame.wait_for_function("() => window.x > 0")
|
795
|
+
# browser.close()
|
796
|
+
#
|
797
|
+
# with sync_playwright() as playwright:
|
798
|
+
# run(playwright)
|
799
|
+
# ```
|
800
|
+
#
|
456
801
|
# To pass an argument to the predicate of `frame.waitForFunction` function:
|
802
|
+
#
|
457
803
|
#
|
458
804
|
# ```js
|
459
805
|
# const selector = '.foo';
|
460
806
|
# await frame.waitForFunction(selector => !!document.querySelector(selector), selector);
|
461
807
|
# ```
|
808
|
+
#
|
809
|
+
# ```python async
|
810
|
+
# selector = ".foo"
|
811
|
+
# await frame.wait_for_function("selector => !!document.querySelector(selector)", selector)
|
812
|
+
# ```
|
813
|
+
#
|
814
|
+
# ```python sync
|
815
|
+
# selector = ".foo"
|
816
|
+
# frame.wait_for_function("selector => !!document.querySelector(selector)", selector)
|
817
|
+
# ```
|
462
818
|
def wait_for_function(pageFunction, arg: nil, polling: nil, timeout: nil)
|
463
|
-
|
819
|
+
wrap_impl(@impl.wait_for_function(unwrap_impl(pageFunction), arg: unwrap_impl(arg), polling: unwrap_impl(polling), timeout: unwrap_impl(timeout)))
|
464
820
|
end
|
465
821
|
|
466
822
|
# Waits for the required load state to be reached.
|
467
|
-
#
|
823
|
+
#
|
824
|
+
# This returns when the frame reaches a required load state, `load` by default. The navigation must have been committed
|
825
|
+
# when this method is called. If current document has already reached the required state, resolves immediately.
|
826
|
+
#
|
468
827
|
#
|
469
828
|
# ```js
|
470
829
|
# await frame.click('button'); // Click triggers navigation.
|
471
830
|
# await frame.waitForLoadState(); // Waits for 'load' state by default.
|
472
831
|
# ```
|
832
|
+
#
|
833
|
+
# ```python async
|
834
|
+
# await frame.click("button") # click triggers navigation.
|
835
|
+
# await frame.wait_for_load_state() # the promise resolves after "load" event.
|
836
|
+
# ```
|
837
|
+
#
|
838
|
+
# ```python sync
|
839
|
+
# frame.click("button") # click triggers navigation.
|
840
|
+
# frame.wait_for_load_state() # the promise resolves after "load" event.
|
841
|
+
# ```
|
473
842
|
def wait_for_load_state(state: nil, timeout: nil)
|
474
|
-
|
843
|
+
wrap_impl(@impl.wait_for_load_state(state: unwrap_impl(state), timeout: unwrap_impl(timeout)))
|
475
844
|
end
|
476
845
|
|
477
|
-
#
|
478
|
-
#
|
846
|
+
# Waits for the frame navigation and returns the main resource response. In case of multiple redirects, the navigation
|
847
|
+
# will resolve with the response of the last redirect. In case of navigation to a different anchor or navigation due to
|
848
|
+
# History API usage, the navigation will resolve with `null`.
|
849
|
+
#
|
850
|
+
# This method waits for the frame to navigate to a new URL. It is useful for when you run code which will indirectly cause
|
851
|
+
# the frame to navigate. Consider this example:
|
852
|
+
#
|
479
853
|
#
|
480
854
|
# ```js
|
481
855
|
# const [response] = await Promise.all([
|
482
|
-
# frame.waitForNavigation(), //
|
483
|
-
# frame.click('a.
|
856
|
+
# frame.waitForNavigation(), // The promise resolves after navigation has finished
|
857
|
+
# frame.click('a.delayed-navigation'), // Clicking the link will indirectly cause a navigation
|
484
858
|
# ]);
|
485
859
|
# ```
|
486
|
-
#
|
487
|
-
|
488
|
-
|
860
|
+
#
|
861
|
+
# ```python async
|
862
|
+
# async with frame.expect_navigation():
|
863
|
+
# await frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
|
864
|
+
# # Resolves after navigation has finished
|
865
|
+
# ```
|
866
|
+
#
|
867
|
+
# ```python sync
|
868
|
+
# with frame.expect_navigation():
|
869
|
+
# frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
|
870
|
+
# # Resolves after navigation has finished
|
871
|
+
# ```
|
872
|
+
#
|
873
|
+
# > NOTE: Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is
|
874
|
+
# considered a navigation.
|
875
|
+
def expect_navigation(timeout: nil, url: nil, waitUntil: nil, &block)
|
876
|
+
wrap_impl(@impl.expect_navigation(timeout: unwrap_impl(timeout), url: unwrap_impl(url), waitUntil: unwrap_impl(waitUntil), &wrap_block_call(block)))
|
489
877
|
end
|
490
878
|
|
491
|
-
# Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
|
492
|
-
#
|
879
|
+
# Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
|
880
|
+
# `detached`.
|
881
|
+
#
|
882
|
+
# Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
|
883
|
+
# the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
|
884
|
+
# selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
|
885
|
+
#
|
493
886
|
# This method works across navigations:
|
887
|
+
#
|
494
888
|
#
|
495
889
|
# ```js
|
496
|
-
# const {
|
890
|
+
# const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
|
497
891
|
#
|
498
892
|
# (async () => {
|
499
|
-
# const browser = await
|
893
|
+
# const browser = await chromium.launch();
|
500
894
|
# const page = await browser.newPage();
|
501
|
-
# let currentURL
|
502
|
-
# page.mainFrame()
|
503
|
-
# .waitForSelector('img')
|
504
|
-
# .then(() => console.log('First URL with image: ' + currentURL));
|
505
|
-
# for (currentURL of ['https://example.com', 'https://google.com', 'https://bbc.com']) {
|
895
|
+
# for (let currentURL of ['https://google.com', 'https://bbc.com']) {
|
506
896
|
# await page.goto(currentURL);
|
897
|
+
# const element = await page.mainFrame().waitForSelector('img');
|
898
|
+
# console.log('Loaded image: ' + await element.getAttribute('src'));
|
507
899
|
# }
|
508
900
|
# await browser.close();
|
509
901
|
# })();
|
510
902
|
# ```
|
903
|
+
#
|
904
|
+
# ```python async
|
905
|
+
# import asyncio
|
906
|
+
# from playwright.async_api import async_playwright
|
907
|
+
#
|
908
|
+
# async def run(playwright):
|
909
|
+
# chromium = playwright.chromium
|
910
|
+
# browser = await chromium.launch()
|
911
|
+
# page = await browser.new_page()
|
912
|
+
# for current_url in ["https://google.com", "https://bbc.com"]:
|
913
|
+
# await page.goto(current_url, wait_until="domcontentloaded")
|
914
|
+
# element = await page.main_frame.wait_for_selector("img")
|
915
|
+
# print("Loaded image: " + str(await element.get_attribute("src")))
|
916
|
+
# await browser.close()
|
917
|
+
#
|
918
|
+
# async def main():
|
919
|
+
# async with async_playwright() as playwright:
|
920
|
+
# await run(playwright)
|
921
|
+
# asyncio.run(main())
|
922
|
+
# ```
|
923
|
+
#
|
924
|
+
# ```python sync
|
925
|
+
# from playwright.sync_api import sync_playwright
|
926
|
+
#
|
927
|
+
# def run(playwright):
|
928
|
+
# chromium = playwright.chromium
|
929
|
+
# browser = chromium.launch()
|
930
|
+
# page = browser.new_page()
|
931
|
+
# for current_url in ["https://google.com", "https://bbc.com"]:
|
932
|
+
# page.goto(current_url, wait_until="domcontentloaded")
|
933
|
+
# element = page.main_frame.wait_for_selector("img")
|
934
|
+
# print("Loaded image: " + str(element.get_attribute("src")))
|
935
|
+
# browser.close()
|
936
|
+
#
|
937
|
+
# with sync_playwright() as playwright:
|
938
|
+
# run(playwright)
|
939
|
+
# ```
|
511
940
|
def wait_for_selector(selector, state: nil, timeout: nil)
|
512
941
|
raise NotImplementedError.new('wait_for_selector is not implemented yet.')
|
513
942
|
end
|
514
943
|
|
515
944
|
# Waits for the given `timeout` in milliseconds.
|
516
|
-
#
|
945
|
+
#
|
946
|
+
# Note that `frame.waitForTimeout()` should only be used for debugging. Tests using the timer in production are going to
|
947
|
+
# be flaky. Use signals such as network events, selectors becoming visible and others instead.
|
517
948
|
def wait_for_timeout(timeout)
|
518
949
|
raise NotImplementedError.new('wait_for_timeout is not implemented yet.')
|
519
950
|
end
|
520
951
|
|
952
|
+
# @nodoc
|
953
|
+
def detached=(req)
|
954
|
+
wrap_impl(@impl.detached=(unwrap_impl(req)))
|
955
|
+
end
|
956
|
+
|
521
957
|
# @nodoc
|
522
958
|
def after_initialize
|
523
|
-
|
959
|
+
wrap_impl(@impl.after_initialize)
|
960
|
+
end
|
961
|
+
|
962
|
+
# -- inherited from EventEmitter --
|
963
|
+
# @nodoc
|
964
|
+
def on(event, callback)
|
965
|
+
wrap_impl(@impl.on(unwrap_impl(event), unwrap_impl(callback)))
|
966
|
+
end
|
967
|
+
|
968
|
+
# -- inherited from EventEmitter --
|
969
|
+
# @nodoc
|
970
|
+
def off(event, callback)
|
971
|
+
wrap_impl(@impl.off(unwrap_impl(event), unwrap_impl(callback)))
|
972
|
+
end
|
973
|
+
|
974
|
+
# -- inherited from EventEmitter --
|
975
|
+
# @nodoc
|
976
|
+
def once(event, callback)
|
977
|
+
wrap_impl(@impl.once(unwrap_impl(event), unwrap_impl(callback)))
|
524
978
|
end
|
525
979
|
end
|
526
980
|
end
|