playwright-ruby-client 0.8.1 → 1.14.beta3
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/documentation/docs/api/accessibility.md +51 -1
- data/documentation/docs/api/browser_context.md +28 -0
- data/documentation/docs/api/download.md +97 -0
- data/documentation/docs/api/element_handle.md +28 -3
- data/documentation/docs/api/experimental/android.md +15 -2
- data/documentation/docs/api/frame.md +116 -114
- data/documentation/docs/api/locator.md +650 -0
- data/documentation/docs/api/mouse.md +3 -4
- data/documentation/docs/api/page.md +109 -19
- data/documentation/docs/api/request.md +15 -19
- data/documentation/docs/api/touchscreen.md +8 -0
- data/documentation/docs/api/tracing.md +13 -12
- data/documentation/docs/api/worker.md +37 -0
- data/documentation/docs/article/guides/inspector.md +31 -0
- data/documentation/docs/article/guides/playwright_on_alpine_linux.md +1 -1
- data/documentation/docs/article/guides/semi_automation.md +1 -1
- data/documentation/docs/include/api_coverage.md +70 -14
- data/lib/playwright.rb +0 -1
- data/lib/playwright/accessibility_impl.rb +50 -0
- data/lib/playwright/channel_owners/browser_context.rb +70 -0
- data/lib/playwright/channel_owners/frame.rb +79 -33
- data/lib/playwright/channel_owners/page.rb +133 -42
- data/lib/playwright/channel_owners/request.rb +8 -8
- data/lib/playwright/channel_owners/worker.rb +23 -0
- data/lib/playwright/{download.rb → download_impl.rb} +1 -1
- data/lib/playwright/javascript/expression.rb +5 -4
- data/lib/playwright/locator_impl.rb +314 -0
- data/lib/playwright/timeout_settings.rb +4 -4
- data/lib/playwright/touchscreen_impl.rb +7 -0
- data/lib/playwright/tracing_impl.rb +9 -8
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright_api/accessibility.rb +1 -1
- data/lib/playwright_api/android.rb +21 -8
- data/lib/playwright_api/android_device.rb +6 -6
- data/lib/playwright_api/browser.rb +6 -6
- data/lib/playwright_api/browser_context.rb +16 -11
- data/lib/playwright_api/browser_type.rb +6 -6
- data/lib/playwright_api/cdp_session.rb +6 -6
- data/lib/playwright_api/console_message.rb +6 -6
- data/lib/playwright_api/dialog.rb +6 -6
- data/lib/playwright_api/download.rb +70 -0
- data/lib/playwright_api/element_handle.rb +34 -20
- data/lib/playwright_api/frame.rb +85 -53
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/locator.rb +509 -0
- data/lib/playwright_api/page.rb +91 -57
- data/lib/playwright_api/playwright.rb +6 -6
- data/lib/playwright_api/request.rb +6 -6
- data/lib/playwright_api/response.rb +6 -6
- data/lib/playwright_api/route.rb +6 -6
- data/lib/playwright_api/selectors.rb +6 -6
- data/lib/playwright_api/touchscreen.rb +1 -1
- data/lib/playwright_api/web_socket.rb +6 -6
- data/lib/playwright_api/worker.rb +16 -6
- metadata +13 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88c8fbe4451b00ed8eba172f656e0171fb2580d555eefb4d2aa0cc1a13f86fc4
|
4
|
+
data.tar.gz: 3d307147cc4a23356d561f9528ef95343984bf4623ad77ebb6e479ce4f4f9462
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 647702705f820c268e5b858a1cd587b0e8f32f16415df2fd7b91505a221cadc20400fc9f2db188964fe4759f4734c8b30bc15c265434d2ac2b78e0683228c192
|
7
|
+
data.tar.gz: b4af0552e547d28be8c9390441bb7131d61fcea36fb5d3d293fd6985d6b47d3925e1c3bf27aa5f4e59243fc03ad751355acc20cb4e63b6e7489c47abb55b1864
|
@@ -4,4 +4,54 @@ sidebar_position: 10
|
|
4
4
|
|
5
5
|
# Accessibility
|
6
6
|
|
7
|
-
|
7
|
+
The Accessibility class provides methods for inspecting Chromium's accessibility tree. The accessibility tree is used by
|
8
|
+
assistive technology such as [screen readers](https://en.wikipedia.org/wiki/Screen_reader) or
|
9
|
+
[switches](https://en.wikipedia.org/wiki/Switch_access).
|
10
|
+
|
11
|
+
Accessibility is a very platform-specific thing. On different platforms, there are different screen readers that might
|
12
|
+
have wildly different output.
|
13
|
+
|
14
|
+
Rendering engines of Chromium, Firefox and WebKit have a concept of "accessibility tree", which is then translated into
|
15
|
+
different platform-specific APIs. Accessibility namespace gives access to this Accessibility Tree.
|
16
|
+
|
17
|
+
Most of the accessibility tree gets filtered out when converting from internal browser AX Tree to Platform-specific
|
18
|
+
AX-Tree or by assistive technologies themselves. By default, Playwright tries to approximate this filtering, exposing
|
19
|
+
only the "interesting" nodes of the tree.
|
20
|
+
|
21
|
+
## snapshot
|
22
|
+
|
23
|
+
```
|
24
|
+
def snapshot(interestingOnly: nil, root: nil)
|
25
|
+
```
|
26
|
+
|
27
|
+
Captures the current state of the accessibility tree. The returned object represents the root accessible node of the
|
28
|
+
page.
|
29
|
+
|
30
|
+
> NOTE: The Chromium accessibility tree contains nodes that go unused on most platforms and by most screen readers.
|
31
|
+
Playwright will discard them as well for an easier to process tree, unless `interestingOnly` is set to `false`.
|
32
|
+
|
33
|
+
An example of dumping the entire accessibility tree:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
snapshot = page.accessibility.snapshot
|
37
|
+
puts snapshot
|
38
|
+
```
|
39
|
+
|
40
|
+
An example of logging the focused node's name:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
def find_focused_node(node)
|
44
|
+
if node['focused']
|
45
|
+
node
|
46
|
+
else
|
47
|
+
node['children']&.find do |child|
|
48
|
+
find_focused_node(child)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
snapshot = page.accessibility.snapshot
|
54
|
+
node = find_focused_node(snapshot)
|
55
|
+
puts node['name']
|
56
|
+
```
|
57
|
+
|
@@ -67,6 +67,16 @@ browser_context.add_init_script(path: "preload.js")
|
|
67
67
|
> NOTE: The order of evaluation of multiple scripts installed via [BrowserContext#add_init_script](./browser_context#add_init_script) and
|
68
68
|
[Page#add_init_script](./page#add_init_script) is not defined.
|
69
69
|
|
70
|
+
## background_pages
|
71
|
+
|
72
|
+
```
|
73
|
+
def background_pages
|
74
|
+
```
|
75
|
+
|
76
|
+
> NOTE: Background pages are only supported on Chromium-based browsers.
|
77
|
+
|
78
|
+
All existing background pages in the context.
|
79
|
+
|
70
80
|
## browser
|
71
81
|
|
72
82
|
```
|
@@ -301,6 +311,16 @@ To remove a route with its handler you can use [BrowserContext#unroute](./browse
|
|
301
311
|
|
302
312
|
> NOTE: Enabling routing disables http cache.
|
303
313
|
|
314
|
+
## service_workers
|
315
|
+
|
316
|
+
```
|
317
|
+
def service_workers
|
318
|
+
```
|
319
|
+
|
320
|
+
> NOTE: Service workers are only supported on Chromium-based browsers.
|
321
|
+
|
322
|
+
All existing service workers in the context.
|
323
|
+
|
304
324
|
## set_default_navigation_timeout
|
305
325
|
|
306
326
|
```
|
@@ -369,6 +389,14 @@ alias: `offline=`
|
|
369
389
|
|
370
390
|
|
371
391
|
|
392
|
+
## storage_state
|
393
|
+
|
394
|
+
```
|
395
|
+
def storage_state(path: nil)
|
396
|
+
```
|
397
|
+
|
398
|
+
Returns storage state for this browser context, contains current cookies and local storage snapshot.
|
399
|
+
|
372
400
|
## unroute
|
373
401
|
|
374
402
|
```
|
@@ -0,0 +1,97 @@
|
|
1
|
+
---
|
2
|
+
sidebar_position: 10
|
3
|
+
---
|
4
|
+
|
5
|
+
# Download
|
6
|
+
|
7
|
+
[Download](./download) objects are dispatched by page via the [`event: Page.download`] event.
|
8
|
+
|
9
|
+
All the downloaded files belonging to the browser context are deleted when the browser context is closed.
|
10
|
+
|
11
|
+
Download event is emitted once the download starts. Download path becomes available once download completes:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
download = page.expect_download do
|
15
|
+
page.click('a')
|
16
|
+
end
|
17
|
+
|
18
|
+
# wait for download to complete
|
19
|
+
path = download.path
|
20
|
+
```
|
21
|
+
|
22
|
+
> NOTE: Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the
|
23
|
+
downloaded content. If `acceptDownloads` is not set, download events are emitted, but the actual download is not
|
24
|
+
performed and user has no access to the downloaded files.
|
25
|
+
|
26
|
+
## cancel
|
27
|
+
|
28
|
+
```
|
29
|
+
def cancel
|
30
|
+
```
|
31
|
+
|
32
|
+
Cancels a download. Will not fail if the download is already finished or canceled. Upon successful cancellations,
|
33
|
+
`download.failure()` would resolve to `'canceled'`.
|
34
|
+
|
35
|
+
## delete
|
36
|
+
|
37
|
+
```
|
38
|
+
def delete
|
39
|
+
```
|
40
|
+
|
41
|
+
Deletes the downloaded file. Will wait for the download to finish if necessary.
|
42
|
+
|
43
|
+
## failure
|
44
|
+
|
45
|
+
```
|
46
|
+
def failure
|
47
|
+
```
|
48
|
+
|
49
|
+
Returns download error if any. Will wait for the download to finish if necessary.
|
50
|
+
|
51
|
+
## page
|
52
|
+
|
53
|
+
```
|
54
|
+
def page
|
55
|
+
```
|
56
|
+
|
57
|
+
Get the page that the download belongs to.
|
58
|
+
|
59
|
+
## path
|
60
|
+
|
61
|
+
```
|
62
|
+
def path
|
63
|
+
```
|
64
|
+
|
65
|
+
Returns path to the downloaded file in case of successful download. The method will wait for the download to finish if
|
66
|
+
necessary. The method throws when connected remotely.
|
67
|
+
|
68
|
+
Note that the download's file name is a random GUID, use [Download#suggested_filename](./download#suggested_filename) to get suggested file
|
69
|
+
name.
|
70
|
+
|
71
|
+
## save_as
|
72
|
+
|
73
|
+
```
|
74
|
+
def save_as(path)
|
75
|
+
```
|
76
|
+
|
77
|
+
Copy the download to a user-specified path. It is safe to call this method while the download is still in progress. Will
|
78
|
+
wait for the download to finish if necessary.
|
79
|
+
|
80
|
+
## suggested_filename
|
81
|
+
|
82
|
+
```
|
83
|
+
def suggested_filename
|
84
|
+
```
|
85
|
+
|
86
|
+
Returns suggested filename for this download. It is typically computed by the browser from the
|
87
|
+
[`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) response header
|
88
|
+
or the `download` attribute. See the spec on [whatwg](https://html.spec.whatwg.org/#downloading-resources). Different
|
89
|
+
browsers can use different logic for computing it.
|
90
|
+
|
91
|
+
## url
|
92
|
+
|
93
|
+
```
|
94
|
+
def url
|
95
|
+
```
|
96
|
+
|
97
|
+
Returns downloaded url.
|
@@ -10,10 +10,8 @@ ElementHandle represents an in-page DOM element. ElementHandles can be created w
|
|
10
10
|
method.
|
11
11
|
|
12
12
|
```ruby
|
13
|
-
page.goto("https://example.com")
|
14
13
|
href_element = page.query_selector("a")
|
15
14
|
href_element.click
|
16
|
-
# ...
|
17
15
|
```
|
18
16
|
|
19
17
|
ElementHandle prevents DOM element from garbage collection unless the handle is disposed with
|
@@ -22,6 +20,33 @@ ElementHandle prevents DOM element from garbage collection unless the handle is
|
|
22
20
|
ElementHandle instances can be used as an argument in [Page#eval_on_selector](./page#eval_on_selector) and [Page#evaluate](./page#evaluate)
|
23
21
|
methods.
|
24
22
|
|
23
|
+
> NOTE: In most cases, you would want to use the [Locator](./locator) object instead. You should only use [ElementHandle](./element_handle) if you
|
24
|
+
want to retain a handle to a particular DOM Node that you intend to pass into [Page#evaluate](./page#evaluate) as an argument.
|
25
|
+
|
26
|
+
The difference between the [Locator](./locator) and ElementHandle is that the ElementHandle points to a particular element, while
|
27
|
+
[Locator](./locator) captures the logic of how to retrieve an element.
|
28
|
+
|
29
|
+
In the example below, handle points to a particular DOM element on page. If that element changes text or is used by
|
30
|
+
React to render an entirely different component, handle is still pointing to that very DOM element. This can lead to
|
31
|
+
unexpected behaviors.
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
handle = page.query_selector("text=Submit")
|
35
|
+
handle.hover
|
36
|
+
handle.click
|
37
|
+
```
|
38
|
+
|
39
|
+
With the locator, every time the `element` is used, up-to-date DOM element is located in the page using the selector. So
|
40
|
+
in the snippet below, underlying DOM element is going to be located twice.
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
locator = page.locator("text=Submit")
|
44
|
+
locator.hover
|
45
|
+
locator.click
|
46
|
+
```
|
47
|
+
|
48
|
+
|
49
|
+
|
25
50
|
## bounding_box
|
26
51
|
|
27
52
|
```
|
@@ -306,7 +331,7 @@ Returns the `element.innerText`.
|
|
306
331
|
def input_value(timeout: nil)
|
307
332
|
```
|
308
333
|
|
309
|
-
Returns `input.value` for `<input>` or `<textarea>` element. Throws for non-input elements.
|
334
|
+
Returns `input.value` for `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
|
310
335
|
|
311
336
|
## checked?
|
312
337
|
|
@@ -4,8 +4,21 @@ sidebar_position: 10
|
|
4
4
|
|
5
5
|
# Android
|
6
6
|
|
7
|
-
Playwright has **experimental** support for Android automation.
|
8
|
-
|
7
|
+
Playwright has **experimental** support for Android automation. This includes Chrome for Android and Android WebView.
|
8
|
+
|
9
|
+
*Requirements*
|
10
|
+
- Android device or AVD Emulator.
|
11
|
+
- [ADB daemon](https://developer.android.com/studio/command-line/adb) running and authenticated with your device.
|
12
|
+
Typically running `adb devices` is all you need to do.
|
13
|
+
- [`Chrome 87`](https://play.google.com/store/apps/details?id=com.android.chrome) or newer installed on the device
|
14
|
+
- "Enable command line on non-rooted devices" enabled in `chrome://flags`.
|
15
|
+
|
16
|
+
*Known limitations*
|
17
|
+
- Raw USB operation is not yet supported, so you need ADB.
|
18
|
+
- Device needs to be awake to produce screenshots. Enabling "Stay awake" developer mode will help.
|
19
|
+
- We didn't run all the tests against the device, so not everything works.
|
20
|
+
|
21
|
+
*How to run*
|
9
22
|
|
10
23
|
An example of the Android automation script would be:
|
11
24
|
|
@@ -16,25 +16,16 @@ At every point of time, page exposes its current frame tree via the [Page#main_f
|
|
16
16
|
|
17
17
|
An example of dumping frame tree:
|
18
18
|
|
19
|
-
```
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
page.goto("https://www.theverge.com")
|
27
|
-
dump_frame_tree(page.main_frame, "")
|
28
|
-
browser.close()
|
29
|
-
|
30
|
-
def dump_frame_tree(frame, indent):
|
31
|
-
print(indent + frame.name + '@' + frame.url)
|
32
|
-
for child in frame.child_frames:
|
33
|
-
dump_frame_tree(child, indent + " ")
|
34
|
-
|
35
|
-
with sync_playwright() as playwright:
|
36
|
-
run(playwright)
|
19
|
+
```ruby
|
20
|
+
def dump_frame_tree(frame, indent = 0)
|
21
|
+
puts "#{' ' * indent}#{frame.name}@#{frame.url}"
|
22
|
+
frame.child_frames.each do |child|
|
23
|
+
dump_frame_tree(child, indent + 2)
|
24
|
+
end
|
25
|
+
end
|
37
26
|
|
27
|
+
page.goto("https://www.theverge.com")
|
28
|
+
dump_frame_tree(page.main_frame)
|
38
29
|
```
|
39
30
|
|
40
31
|
|
@@ -68,6 +59,7 @@ def check(
|
|
68
59
|
force: nil,
|
69
60
|
noWaitAfter: nil,
|
70
61
|
position: nil,
|
62
|
+
strict: nil,
|
71
63
|
timeout: nil,
|
72
64
|
trial: nil)
|
73
65
|
```
|
@@ -106,6 +98,7 @@ def click(
|
|
106
98
|
modifiers: nil,
|
107
99
|
noWaitAfter: nil,
|
108
100
|
position: nil,
|
101
|
+
strict: nil,
|
109
102
|
timeout: nil,
|
110
103
|
trial: nil)
|
111
104
|
```
|
@@ -140,6 +133,7 @@ def dblclick(
|
|
140
133
|
modifiers: nil,
|
141
134
|
noWaitAfter: nil,
|
142
135
|
position: nil,
|
136
|
+
strict: nil,
|
143
137
|
timeout: nil,
|
144
138
|
trial: nil)
|
145
139
|
```
|
@@ -161,16 +155,20 @@ zero timeout disables this.
|
|
161
155
|
## dispatch_event
|
162
156
|
|
163
157
|
```
|
164
|
-
def dispatch_event(
|
158
|
+
def dispatch_event(
|
159
|
+
selector,
|
160
|
+
type,
|
161
|
+
eventInit: nil,
|
162
|
+
strict: nil,
|
163
|
+
timeout: nil)
|
165
164
|
```
|
166
165
|
|
167
166
|
The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the element,
|
168
167
|
`click` is dispatched. This is equivalent to calling
|
169
168
|
[element.click()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click).
|
170
169
|
|
171
|
-
```
|
170
|
+
```ruby
|
172
171
|
frame.dispatch_event("button#submit", "click")
|
173
|
-
|
174
172
|
```
|
175
173
|
|
176
174
|
Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties
|
@@ -187,11 +185,10 @@ Since `eventInit` is event-specific, please refer to the events documentation fo
|
|
187
185
|
|
188
186
|
You can also specify [JSHandle](./js_handle) as the property value if you want live objects to be passed into the event:
|
189
187
|
|
190
|
-
```
|
188
|
+
```ruby
|
191
189
|
# note you can only create data_transfer in chromium and firefox
|
192
190
|
data_transfer = frame.evaluate_handle("new DataTransfer()")
|
193
|
-
frame.dispatch_event("#source", "dragstart", {
|
194
|
-
|
191
|
+
frame.dispatch_event("#source", "dragstart", eventInit: { dataTransfer: data_transfer })
|
195
192
|
```
|
196
193
|
|
197
194
|
|
@@ -204,6 +201,9 @@ def drag_and_drop(
|
|
204
201
|
target,
|
205
202
|
force: nil,
|
206
203
|
noWaitAfter: nil,
|
204
|
+
sourcePosition: nil,
|
205
|
+
strict: nil,
|
206
|
+
targetPosition: nil,
|
207
207
|
timeout: nil,
|
208
208
|
trial: nil)
|
209
209
|
```
|
@@ -213,7 +213,7 @@ def drag_and_drop(
|
|
213
213
|
## eval_on_selector
|
214
214
|
|
215
215
|
```
|
216
|
-
def eval_on_selector(selector, expression, arg: nil)
|
216
|
+
def eval_on_selector(selector, expression, arg: nil, strict: nil)
|
217
217
|
```
|
218
218
|
|
219
219
|
Returns the return value of `expression`.
|
@@ -227,11 +227,10 @@ return its value.
|
|
227
227
|
|
228
228
|
Examples:
|
229
229
|
|
230
|
-
```
|
230
|
+
```ruby
|
231
231
|
search_value = frame.eval_on_selector("#search", "el => el.value")
|
232
232
|
preload_href = frame.eval_on_selector("link[rel=preload]", "el => el.href")
|
233
|
-
html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
|
234
|
-
|
233
|
+
html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", arg: "hello")
|
235
234
|
```
|
236
235
|
|
237
236
|
|
@@ -252,9 +251,8 @@ return its value.
|
|
252
251
|
|
253
252
|
Examples:
|
254
253
|
|
255
|
-
```
|
256
|
-
divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
|
257
|
-
|
254
|
+
```ruby
|
255
|
+
divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", arg: 10)
|
258
256
|
```
|
259
257
|
|
260
258
|
|
@@ -274,28 +272,25 @@ If the function passed to the [Frame#evaluate](./frame#evaluate) returns a non-[
|
|
274
272
|
[Frame#evaluate](./frame#evaluate) returns `undefined`. Playwright also supports transferring some additional values that are
|
275
273
|
not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`.
|
276
274
|
|
277
|
-
```
|
278
|
-
result = frame.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
|
279
|
-
|
280
|
-
|
275
|
+
```ruby
|
276
|
+
result = frame.evaluate("([x, y]) => Promise.resolve(x * y)", arg: [7, 8])
|
277
|
+
puts result # => "56"
|
281
278
|
```
|
282
279
|
|
283
280
|
A string can also be passed in instead of a function.
|
284
281
|
|
285
|
-
```
|
286
|
-
|
282
|
+
```ruby
|
283
|
+
puts frame.evaluate("1 + 2") # => 3
|
287
284
|
x = 10
|
288
|
-
|
289
|
-
|
285
|
+
puts frame.evaluate("1 + #{x}") # => "11"
|
290
286
|
```
|
291
287
|
|
292
288
|
[ElementHandle](./element_handle) instances can be passed as an argument to the [Frame#evaluate](./frame#evaluate):
|
293
289
|
|
294
|
-
```
|
290
|
+
```ruby
|
295
291
|
body_handle = frame.query_selector("body")
|
296
|
-
html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
|
297
|
-
body_handle.dispose
|
298
|
-
|
292
|
+
html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", arg: [body_handle, "hello"])
|
293
|
+
body_handle.dispose
|
299
294
|
```
|
300
295
|
|
301
296
|
|
@@ -314,10 +309,9 @@ The only difference between [Frame#evaluate](./frame#evaluate) and [Frame#evalua
|
|
314
309
|
If the function, passed to the [Frame#evaluate_handle](./frame#evaluate_handle), returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), then
|
315
310
|
[Frame#evaluate_handle](./frame#evaluate_handle) would wait for the promise to resolve and return its value.
|
316
311
|
|
317
|
-
```
|
312
|
+
```ruby
|
318
313
|
a_window_handle = frame.evaluate_handle("Promise.resolve(window)")
|
319
314
|
a_window_handle # handle for the window object.
|
320
|
-
|
321
315
|
```
|
322
316
|
|
323
317
|
A string can also be passed in instead of a function.
|
@@ -345,6 +339,7 @@ def fill(
|
|
345
339
|
value,
|
346
340
|
force: nil,
|
347
341
|
noWaitAfter: nil,
|
342
|
+
strict: nil,
|
348
343
|
timeout: nil)
|
349
344
|
```
|
350
345
|
|
@@ -362,7 +357,7 @@ To send fine-grained keyboard events, use [Frame#type](./frame#type).
|
|
362
357
|
## focus
|
363
358
|
|
364
359
|
```
|
365
|
-
def focus(selector, timeout: nil)
|
360
|
+
def focus(selector, strict: nil, timeout: nil)
|
366
361
|
```
|
367
362
|
|
368
363
|
This method fetches an element with `selector` and focuses it. If there's no element matching `selector`, the method
|
@@ -381,11 +376,10 @@ frame.
|
|
381
376
|
|
382
377
|
This method throws an error if the frame has been detached before `frameElement()` returns.
|
383
378
|
|
384
|
-
```
|
385
|
-
frame_element = frame.frame_element
|
386
|
-
content_frame = frame_element.content_frame
|
387
|
-
|
388
|
-
|
379
|
+
```ruby
|
380
|
+
frame_element = frame.frame_element
|
381
|
+
content_frame = frame_element.content_frame
|
382
|
+
puts frame == content_frame # => true
|
389
383
|
```
|
390
384
|
|
391
385
|
|
@@ -393,7 +387,7 @@ assert frame == content_frame
|
|
393
387
|
## get_attribute
|
394
388
|
|
395
389
|
```
|
396
|
-
def get_attribute(selector, name, timeout: nil)
|
390
|
+
def get_attribute(selector, name, strict: nil, timeout: nil)
|
397
391
|
```
|
398
392
|
|
399
393
|
Returns element attribute value.
|
@@ -431,6 +425,7 @@ def hover(
|
|
431
425
|
force: nil,
|
432
426
|
modifiers: nil,
|
433
427
|
position: nil,
|
428
|
+
strict: nil,
|
434
429
|
timeout: nil,
|
435
430
|
trial: nil)
|
436
431
|
```
|
@@ -449,7 +444,7 @@ zero timeout disables this.
|
|
449
444
|
## inner_html
|
450
445
|
|
451
446
|
```
|
452
|
-
def inner_html(selector, timeout: nil)
|
447
|
+
def inner_html(selector, strict: nil, timeout: nil)
|
453
448
|
```
|
454
449
|
|
455
450
|
Returns `element.innerHTML`.
|
@@ -457,7 +452,7 @@ Returns `element.innerHTML`.
|
|
457
452
|
## inner_text
|
458
453
|
|
459
454
|
```
|
460
|
-
def inner_text(selector, timeout: nil)
|
455
|
+
def inner_text(selector, strict: nil, timeout: nil)
|
461
456
|
```
|
462
457
|
|
463
458
|
Returns `element.innerText`.
|
@@ -465,15 +460,15 @@ Returns `element.innerText`.
|
|
465
460
|
## input_value
|
466
461
|
|
467
462
|
```
|
468
|
-
def input_value(selector, timeout: nil)
|
463
|
+
def input_value(selector, strict: nil, timeout: nil)
|
469
464
|
```
|
470
465
|
|
471
|
-
Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
|
466
|
+
Returns `input.value` for the selected `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
|
472
467
|
|
473
468
|
## checked?
|
474
469
|
|
475
470
|
```
|
476
|
-
def checked?(selector, timeout: nil)
|
471
|
+
def checked?(selector, strict: nil, timeout: nil)
|
477
472
|
```
|
478
473
|
|
479
474
|
Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
|
@@ -489,7 +484,7 @@ Returns `true` if the frame has been detached, or `false` otherwise.
|
|
489
484
|
## disabled?
|
490
485
|
|
491
486
|
```
|
492
|
-
def disabled?(selector, timeout: nil)
|
487
|
+
def disabled?(selector, strict: nil, timeout: nil)
|
493
488
|
```
|
494
489
|
|
495
490
|
Returns whether the element is disabled, the opposite of [enabled](https://playwright.dev/python/docs/actionability).
|
@@ -497,7 +492,7 @@ Returns whether the element is disabled, the opposite of [enabled](https://playw
|
|
497
492
|
## editable?
|
498
493
|
|
499
494
|
```
|
500
|
-
def editable?(selector, timeout: nil)
|
495
|
+
def editable?(selector, strict: nil, timeout: nil)
|
501
496
|
```
|
502
497
|
|
503
498
|
Returns whether the element is [editable](https://playwright.dev/python/docs/actionability).
|
@@ -505,7 +500,7 @@ Returns whether the element is [editable](https://playwright.dev/python/docs/act
|
|
505
500
|
## enabled?
|
506
501
|
|
507
502
|
```
|
508
|
-
def enabled?(selector, timeout: nil)
|
503
|
+
def enabled?(selector, strict: nil, timeout: nil)
|
509
504
|
```
|
510
505
|
|
511
506
|
Returns whether the element is [enabled](https://playwright.dev/python/docs/actionability).
|
@@ -513,7 +508,7 @@ Returns whether the element is [enabled](https://playwright.dev/python/docs/acti
|
|
513
508
|
## hidden?
|
514
509
|
|
515
510
|
```
|
516
|
-
def hidden?(selector, timeout: nil)
|
511
|
+
def hidden?(selector, strict: nil, timeout: nil)
|
517
512
|
```
|
518
513
|
|
519
514
|
Returns whether the element is hidden, the opposite of [visible](https://playwright.dev/python/docs/actionability). `selector` that does not
|
@@ -522,12 +517,24 @@ match any elements is considered hidden.
|
|
522
517
|
## visible?
|
523
518
|
|
524
519
|
```
|
525
|
-
def visible?(selector, timeout: nil)
|
520
|
+
def visible?(selector, strict: nil, timeout: nil)
|
526
521
|
```
|
527
522
|
|
528
523
|
Returns whether the element is [visible](https://playwright.dev/python/docs/actionability). `selector` that does not match any elements is
|
529
524
|
considered not visible.
|
530
525
|
|
526
|
+
## locator
|
527
|
+
|
528
|
+
```
|
529
|
+
def locator(selector)
|
530
|
+
```
|
531
|
+
|
532
|
+
The method returns an element locator that can be used to perform actions in the frame. Locator is resolved to the
|
533
|
+
element immediately before performing an action, so a series of actions on the same locator can in fact be performed on
|
534
|
+
different DOM elements. That would happen if the DOM structure between those actions has changed.
|
535
|
+
|
536
|
+
Note that locator always implies visibility, so it will always be locating visible elements.
|
537
|
+
|
531
538
|
## name
|
532
539
|
|
533
540
|
```
|
@@ -564,6 +571,7 @@ def press(
|
|
564
571
|
key,
|
565
572
|
delay: nil,
|
566
573
|
noWaitAfter: nil,
|
574
|
+
strict: nil,
|
567
575
|
timeout: nil)
|
568
576
|
```
|
569
577
|
|
@@ -587,7 +595,7 @@ modifier, modifier is pressed and being held while the subsequent key is being p
|
|
587
595
|
## query_selector
|
588
596
|
|
589
597
|
```
|
590
|
-
def query_selector(selector)
|
598
|
+
def query_selector(selector, strict: nil)
|
591
599
|
```
|
592
600
|
|
593
601
|
Returns the ElementHandle pointing to the frame element.
|
@@ -617,6 +625,7 @@ def select_option(
|
|
617
625
|
label: nil,
|
618
626
|
force: nil,
|
619
627
|
noWaitAfter: nil,
|
628
|
+
strict: nil,
|
620
629
|
timeout: nil)
|
621
630
|
```
|
622
631
|
|
@@ -631,14 +640,13 @@ Returns the array of option values that have been successfully selected.
|
|
631
640
|
|
632
641
|
Triggers a `change` and `input` event once all the provided options have been selected.
|
633
642
|
|
634
|
-
```
|
643
|
+
```ruby
|
635
644
|
# single selection matching the value
|
636
|
-
frame.select_option("select#colors", "blue")
|
645
|
+
frame.select_option("select#colors", value: "blue")
|
637
646
|
# single selection matching both the label
|
638
|
-
frame.select_option("select#colors", label
|
647
|
+
frame.select_option("select#colors", label: "blue")
|
639
648
|
# multiple selection
|
640
|
-
frame.select_option("select#colors", value
|
641
|
-
|
649
|
+
frame.select_option("select#colors", value: ["red", "green", "blue"])
|
642
650
|
```
|
643
651
|
|
644
652
|
|
@@ -655,7 +663,12 @@ alias: `content=`
|
|
655
663
|
## set_input_files
|
656
664
|
|
657
665
|
```
|
658
|
-
def set_input_files(
|
666
|
+
def set_input_files(
|
667
|
+
selector,
|
668
|
+
files,
|
669
|
+
noWaitAfter: nil,
|
670
|
+
strict: nil,
|
671
|
+
timeout: nil)
|
659
672
|
```
|
660
673
|
|
661
674
|
This method expects `selector` to point to an
|
@@ -673,6 +686,7 @@ def tap_point(
|
|
673
686
|
modifiers: nil,
|
674
687
|
noWaitAfter: nil,
|
675
688
|
position: nil,
|
689
|
+
strict: nil,
|
676
690
|
timeout: nil,
|
677
691
|
trial: nil)
|
678
692
|
```
|
@@ -693,7 +707,7 @@ zero timeout disables this.
|
|
693
707
|
## text_content
|
694
708
|
|
695
709
|
```
|
696
|
-
def text_content(selector, timeout: nil)
|
710
|
+
def text_content(selector, strict: nil, timeout: nil)
|
697
711
|
```
|
698
712
|
|
699
713
|
Returns `element.textContent`.
|
@@ -714,6 +728,7 @@ def type(
|
|
714
728
|
text,
|
715
729
|
delay: nil,
|
716
730
|
noWaitAfter: nil,
|
731
|
+
strict: nil,
|
717
732
|
timeout: nil)
|
718
733
|
```
|
719
734
|
|
@@ -722,10 +737,9 @@ send fine-grained keyboard events. To fill values in form fields, use [Frame#fil
|
|
722
737
|
|
723
738
|
To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./keyboard#press).
|
724
739
|
|
725
|
-
```
|
740
|
+
```ruby
|
726
741
|
frame.type("#mytextarea", "hello") # types instantly
|
727
|
-
frame.type("#mytextarea", "world", delay
|
728
|
-
|
742
|
+
frame.type("#mytextarea", "world", delay: 100) # types slower, like a user
|
729
743
|
```
|
730
744
|
|
731
745
|
|
@@ -738,6 +752,7 @@ def uncheck(
|
|
738
752
|
force: nil,
|
739
753
|
noWaitAfter: nil,
|
740
754
|
position: nil,
|
755
|
+
strict: nil,
|
741
756
|
timeout: nil,
|
742
757
|
trial: nil)
|
743
758
|
```
|
@@ -774,28 +789,16 @@ Returns when the `expression` returns a truthy value, returns that value.
|
|
774
789
|
|
775
790
|
The [Frame#wait_for_function](./frame#wait_for_function) can be used to observe viewport size change:
|
776
791
|
|
777
|
-
```
|
778
|
-
|
779
|
-
|
780
|
-
def run(playwright):
|
781
|
-
webkit = playwright.webkit
|
782
|
-
browser = webkit.launch()
|
783
|
-
page = browser.new_page()
|
784
|
-
page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
|
785
|
-
page.main_frame.wait_for_function("() => window.x > 0")
|
786
|
-
browser.close()
|
787
|
-
|
788
|
-
with sync_playwright() as playwright:
|
789
|
-
run(playwright)
|
790
|
-
|
792
|
+
```ruby
|
793
|
+
frame.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
|
794
|
+
frame.wait_for_function("() => window.x > 0")
|
791
795
|
```
|
792
796
|
|
793
797
|
To pass an argument to the predicate of `frame.waitForFunction` function:
|
794
798
|
|
795
|
-
```
|
799
|
+
```ruby
|
796
800
|
selector = ".foo"
|
797
|
-
frame.wait_for_function("selector => !!document.querySelector(selector)", selector)
|
798
|
-
|
801
|
+
frame.wait_for_function("selector => !!document.querySelector(selector)", arg: selector)
|
799
802
|
```
|
800
803
|
|
801
804
|
|
@@ -811,10 +814,9 @@ Waits for the required load state to be reached.
|
|
811
814
|
This returns when the frame reaches a required load state, `load` by default. The navigation must have been committed
|
812
815
|
when this method is called. If current document has already reached the required state, resolves immediately.
|
813
816
|
|
814
|
-
```
|
817
|
+
```ruby
|
815
818
|
frame.click("button") # click triggers navigation.
|
816
|
-
frame.wait_for_load_state
|
817
|
-
|
819
|
+
frame.wait_for_load_state # the promise resolves after "load" event.
|
818
820
|
```
|
819
821
|
|
820
822
|
|
@@ -832,11 +834,10 @@ History API usage, the navigation will resolve with `null`.
|
|
832
834
|
This method waits for the frame to navigate to a new URL. It is useful for when you run code which will indirectly cause
|
833
835
|
the frame to navigate. Consider this example:
|
834
836
|
|
835
|
-
```
|
836
|
-
|
837
|
-
|
838
|
-
# Resolves after navigation has finished
|
839
|
-
|
837
|
+
```ruby
|
838
|
+
frame.expect_navigation do
|
839
|
+
frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
|
840
|
+
end # Resolves after navigation has finished
|
840
841
|
```
|
841
842
|
|
842
843
|
> NOTE: Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is
|
@@ -845,7 +846,7 @@ considered a navigation.
|
|
845
846
|
## wait_for_selector
|
846
847
|
|
847
848
|
```
|
848
|
-
def wait_for_selector(selector, state: nil, timeout: nil)
|
849
|
+
def wait_for_selector(selector, state: nil, strict: nil, timeout: nil)
|
849
850
|
```
|
850
851
|
|
851
852
|
Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
|
@@ -857,25 +858,27 @@ selector doesn't satisfy the condition for the `timeout` milliseconds, the funct
|
|
857
858
|
|
858
859
|
This method works across navigations:
|
859
860
|
|
860
|
-
```
|
861
|
-
|
861
|
+
```ruby
|
862
|
+
%w[https://google.com https://bbc.com].each do |current_url|
|
863
|
+
page.goto(current_url, waitUntil: "domcontentloaded")
|
864
|
+
frame = page.main_frame
|
865
|
+
element = frame.wait_for_selector("img")
|
866
|
+
puts "Loaded image: #{element["src"]}"
|
867
|
+
end
|
868
|
+
```
|
869
|
+
|
862
870
|
|
863
|
-
def run(playwright):
|
864
|
-
chromium = playwright.chromium
|
865
|
-
browser = chromium.launch()
|
866
|
-
page = browser.new_page()
|
867
|
-
for current_url in ["https://google.com", "https://bbc.com"]:
|
868
|
-
page.goto(current_url, wait_until="domcontentloaded")
|
869
|
-
element = page.main_frame.wait_for_selector("img")
|
870
|
-
print("Loaded image: " + str(element.get_attribute("src")))
|
871
|
-
browser.close()
|
872
871
|
|
873
|
-
|
874
|
-
run(playwright)
|
872
|
+
## wait_for_timeout
|
875
873
|
|
874
|
+
```
|
875
|
+
def wait_for_timeout(timeout)
|
876
876
|
```
|
877
877
|
|
878
|
+
Waits for the given `timeout` in milliseconds.
|
878
879
|
|
880
|
+
Note that `frame.waitForTimeout()` should only be used for debugging. Tests using the timer in production are going to
|
881
|
+
be flaky. Use signals such as network events, selectors becoming visible and others instead.
|
879
882
|
|
880
883
|
## wait_for_url
|
881
884
|
|
@@ -885,10 +888,9 @@ def wait_for_url(url, timeout: nil, waitUntil: nil)
|
|
885
888
|
|
886
889
|
Waits for the frame to navigate to the given URL.
|
887
890
|
|
888
|
-
```
|
891
|
+
```ruby
|
889
892
|
frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
|
890
893
|
frame.wait_for_url("**/target.html")
|
891
|
-
|
892
894
|
```
|
893
895
|
|
894
896
|
|