playwright-ruby-client 1.14.beta2 → 1.15.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -14
- data/documentation/docs/api/accessibility.md +16 -17
- data/documentation/docs/api/browser.md +4 -0
- data/documentation/docs/api/browser_context.md +5 -1
- data/documentation/docs/api/browser_type.md +2 -0
- data/documentation/docs/api/element_handle.md +30 -5
- data/documentation/docs/api/experimental/android.md +15 -2
- data/documentation/docs/api/experimental/android_device.md +2 -0
- data/documentation/docs/api/frame.md +86 -104
- data/documentation/docs/api/locator.md +69 -40
- data/documentation/docs/api/mouse.md +3 -4
- data/documentation/docs/api/page.md +38 -7
- data/documentation/docs/api/request.md +42 -20
- data/documentation/docs/api/response.md +18 -1
- data/documentation/docs/api/selectors.md +29 -3
- data/documentation/docs/api/tracing.md +51 -16
- data/documentation/docs/api/worker.md +12 -11
- data/documentation/docs/article/getting_started.md +10 -1
- data/documentation/docs/article/guides/download_playwright_driver.md +9 -0
- data/documentation/docs/article/guides/inspector.md +1 -1
- data/documentation/docs/article/guides/playwright_on_alpine_linux.md +56 -3
- data/documentation/docs/article/guides/rails_integration.md +4 -2
- data/documentation/docs/article/guides/rails_integration_with_null_driver.md +86 -0
- data/documentation/docs/article/guides/recording_video.md +1 -1
- data/documentation/docs/article/guides/semi_automation.md +2 -2
- data/documentation/docs/article/guides/use_storage_state.md +78 -0
- data/documentation/docs/include/api_coverage.md +11 -0
- data/documentation/docusaurus.config.js +1 -0
- data/documentation/package.json +2 -2
- data/documentation/src/pages/index.js +0 -1
- data/documentation/static/img/playwright-ruby-client.png +0 -0
- data/documentation/yarn.lock +625 -549
- data/lib/playwright/channel.rb +36 -2
- data/lib/playwright/channel_owners/artifact.rb +6 -2
- data/lib/playwright/channel_owners/browser.rb +4 -0
- data/lib/playwright/channel_owners/browser_context.rb +21 -14
- data/lib/playwright/channel_owners/browser_type.rb +0 -1
- data/lib/playwright/channel_owners/element_handle.rb +10 -2
- data/lib/playwright/channel_owners/frame.rb +8 -0
- data/lib/playwright/channel_owners/page.rb +20 -4
- data/lib/playwright/channel_owners/playwright.rb +9 -0
- data/lib/playwright/channel_owners/request.rb +46 -25
- data/lib/playwright/channel_owners/response.rb +41 -5
- data/lib/playwright/connection.rb +8 -11
- data/lib/playwright/http_headers.rb +9 -4
- data/lib/playwright/locator_impl.rb +11 -3
- data/lib/playwright/{route_handler_entry.rb → route_handler.rb} +30 -2
- data/lib/playwright/tracing_impl.rb +18 -7
- data/lib/playwright/transport.rb +2 -0
- data/lib/playwright/utils.rb +8 -1
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright/web_socket_transport.rb +2 -0
- data/lib/playwright.rb +45 -5
- data/lib/playwright_api/android.rb +21 -8
- data/lib/playwright_api/android_device.rb +11 -9
- data/lib/playwright_api/browser.rb +12 -8
- data/lib/playwright_api/browser_context.rb +12 -8
- data/lib/playwright_api/browser_type.rb +9 -7
- 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/element_handle.rb +31 -8
- data/lib/playwright_api/frame.rb +35 -12
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/locator.rb +41 -2
- data/lib/playwright_api/page.rb +43 -15
- data/lib/playwright_api/playwright.rb +6 -6
- data/lib/playwright_api/request.rb +29 -7
- data/lib/playwright_api/response.rb +23 -7
- data/lib/playwright_api/route.rb +6 -6
- data/lib/playwright_api/selectors.rb +38 -7
- data/lib/playwright_api/tracing.rb +33 -4
- data/lib/playwright_api/web_socket.rb +6 -6
- data/lib/playwright_api/worker.rb +8 -8
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2247f39a5fa4881e45ad884606295d7003b3e42ca9db5436b223d921649e5553
|
4
|
+
data.tar.gz: f7f57d5044c66e300912578faa1d8114ee98f2eb1de736eac3da698e7851b9d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86b2003368d06755bfef64cebe40c716ef9d0156d6bd21f18fddc79cef07ffee5a48f562294c32b956dd664b5480326587736ee56334c76e80e8a8e2b89dfb72
|
7
|
+
data.tar.gz: 20697ed55fb7ce54856d04dc0f9568316d5941b0b103ce5c0138e680a28aeda1b7876a3cf4d358f006a2b5d7115a267ed8e7c689064bf54f65e6797848d69a2f
|
data/README.md
CHANGED
@@ -6,19 +6,13 @@
|
|
6
6
|
|
7
7
|
## Getting Started
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
```sh
|
12
|
-
npx playwright install
|
9
|
+
```
|
10
|
+
gem 'playwright-ruby-client'
|
13
11
|
```
|
14
12
|
|
15
|
-
and then
|
16
|
-
|
17
|
-
**Prefer npm install instead of npx?**
|
18
|
-
|
19
|
-
Actually `npx playwright` is a bit slow. We can also use `npm install` to setup.
|
13
|
+
and then 'bundle install'.
|
20
14
|
|
21
|
-
|
15
|
+
Since playwright-ruby-client doesn't include the playwright driver, **we have to install [playwright](https://github.com/microsoft/playwright) in advance**.
|
22
16
|
|
23
17
|
```
|
24
18
|
npm install playwright
|
@@ -29,14 +23,14 @@ And set `playwright_cli_executable_path: './node_modules/.bin/playwright'`
|
|
29
23
|
|
30
24
|
**Prefer playwrighting without Node.js?**
|
31
25
|
|
32
|
-
Instead of npm, you can also directly download playwright driver from playwright.azureedge.net/builds/. The URL can be easily detected from [here](https://github.com/microsoft/playwright-python/blob/
|
26
|
+
Instead of npm, you can also directly download playwright driver from playwright.azureedge.net/builds/. The URL can be easily detected from [here](https://github.com/microsoft/playwright-python/blob/cb5409934629adaabc0cff1891080de2052fa778/setup.py#L73-L77)
|
33
27
|
|
34
28
|
### Capture a site
|
35
29
|
|
36
30
|
```ruby
|
37
31
|
require 'playwright'
|
38
32
|
|
39
|
-
Playwright.create(playwright_cli_executable_path: '
|
33
|
+
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
|
40
34
|
playwright.chromium.launch(headless: false) do |browser|
|
41
35
|
page = browser.new_page
|
42
36
|
page.goto('https://github.com/YusukeIwaki')
|
@@ -52,7 +46,7 @@ end
|
|
52
46
|
```ruby
|
53
47
|
require 'playwright'
|
54
48
|
|
55
|
-
Playwright.create(playwright_cli_executable_path: '
|
49
|
+
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
|
56
50
|
playwright.chromium.launch(headless: false) do |browser|
|
57
51
|
page = browser.new_page
|
58
52
|
page.goto('https://github.com/')
|
@@ -94,7 +88,7 @@ $ bundle exec ruby main.rb
|
|
94
88
|
```ruby
|
95
89
|
require 'playwright'
|
96
90
|
|
97
|
-
Playwright.create(playwright_cli_executable_path: '
|
91
|
+
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
|
98
92
|
devices = playwright.android.devices
|
99
93
|
unless devices.empty?
|
100
94
|
device = devices.last
|
@@ -185,6 +179,8 @@ end
|
|
185
179
|
|
186
180
|
When `Playwright.connect_to_playwright_server` is used, playwright_cli_executable_path is not required.
|
187
181
|
|
182
|
+
For more detailed instraction, refer this article: https://playwright-ruby-client.vercel.app/docs/article/guides/playwright_on_alpine_linux
|
183
|
+
|
188
184
|
## License
|
189
185
|
|
190
186
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -32,27 +32,26 @@ Playwright will discard them as well for an easier to process tree, unless `inte
|
|
32
32
|
|
33
33
|
An example of dumping the entire accessibility tree:
|
34
34
|
|
35
|
-
```
|
36
|
-
snapshot = page.accessibility.snapshot
|
37
|
-
|
38
|
-
|
35
|
+
```ruby
|
36
|
+
snapshot = page.accessibility.snapshot
|
37
|
+
puts snapshot
|
39
38
|
```
|
40
39
|
|
41
40
|
An example of logging the focused node's name:
|
42
41
|
|
43
|
-
```
|
44
|
-
def find_focused_node(node)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
53
54
|
node = find_focused_node(snapshot)
|
54
|
-
|
55
|
-
print(node["name"])
|
56
|
-
|
55
|
+
puts node['name']
|
57
56
|
```
|
58
57
|
|
@@ -81,6 +81,7 @@ def new_context(
|
|
81
81
|
colorScheme: nil,
|
82
82
|
deviceScaleFactor: nil,
|
83
83
|
extraHTTPHeaders: nil,
|
84
|
+
forcedColors: nil,
|
84
85
|
geolocation: nil,
|
85
86
|
hasTouch: nil,
|
86
87
|
httpCredentials: nil,
|
@@ -99,6 +100,7 @@ def new_context(
|
|
99
100
|
reducedMotion: nil,
|
100
101
|
screen: nil,
|
101
102
|
storageState: nil,
|
103
|
+
strictSelectors: nil,
|
102
104
|
timezoneId: nil,
|
103
105
|
userAgent: nil,
|
104
106
|
viewport: nil,
|
@@ -130,6 +132,7 @@ def new_page(
|
|
130
132
|
colorScheme: nil,
|
131
133
|
deviceScaleFactor: nil,
|
132
134
|
extraHTTPHeaders: nil,
|
135
|
+
forcedColors: nil,
|
133
136
|
geolocation: nil,
|
134
137
|
hasTouch: nil,
|
135
138
|
httpCredentials: nil,
|
@@ -148,6 +151,7 @@ def new_page(
|
|
148
151
|
reducedMotion: nil,
|
149
152
|
screen: nil,
|
150
153
|
storageState: nil,
|
154
|
+
strictSelectors: nil,
|
151
155
|
timezoneId: nil,
|
152
156
|
userAgent: nil,
|
153
157
|
viewport: nil,
|
@@ -265,12 +265,16 @@ Returns all open pages in the context.
|
|
265
265
|
## route
|
266
266
|
|
267
267
|
```
|
268
|
-
def route(url, handler)
|
268
|
+
def route(url, handler, times: nil)
|
269
269
|
```
|
270
270
|
|
271
271
|
Routing provides the capability to modify network requests that are made by any page in the browser context. Once route
|
272
272
|
is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted.
|
273
273
|
|
274
|
+
> NOTE: [Page#route](./page#route) will not intercept requests intercepted by Service Worker. See
|
275
|
+
[this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend disabling Service Workers when using
|
276
|
+
request interception. Via `await context.addInitScript(() => delete window.navigator.serviceWorker);`
|
277
|
+
|
274
278
|
An example of a naive handler that aborts all image requests:
|
275
279
|
|
276
280
|
```ruby
|
@@ -114,6 +114,7 @@ def launch_persistent_context(
|
|
114
114
|
env: nil,
|
115
115
|
executablePath: nil,
|
116
116
|
extraHTTPHeaders: nil,
|
117
|
+
forcedColors: nil,
|
117
118
|
geolocation: nil,
|
118
119
|
handleSIGHUP: nil,
|
119
120
|
handleSIGINT: nil,
|
@@ -137,6 +138,7 @@ def launch_persistent_context(
|
|
137
138
|
reducedMotion: nil,
|
138
139
|
screen: nil,
|
139
140
|
slowMo: nil,
|
141
|
+
strictSelectors: nil,
|
140
142
|
timeout: nil,
|
141
143
|
timezoneId: nil,
|
142
144
|
tracesDir: nil,
|
@@ -510,6 +510,32 @@ def select_text(force: nil, timeout: nil)
|
|
510
510
|
This method waits for [actionability](https://playwright.dev/python/docs/actionability) checks, then focuses the element and selects all its text
|
511
511
|
content.
|
512
512
|
|
513
|
+
## set_checked
|
514
|
+
|
515
|
+
```
|
516
|
+
def set_checked(
|
517
|
+
checked,
|
518
|
+
force: nil,
|
519
|
+
noWaitAfter: nil,
|
520
|
+
position: nil,
|
521
|
+
timeout: nil,
|
522
|
+
trial: nil)
|
523
|
+
```
|
524
|
+
alias: `checked=`
|
525
|
+
|
526
|
+
This method checks or unchecks an element by performing the following steps:
|
527
|
+
1. Ensure that element is a checkbox or a radio input. If not, this method throws.
|
528
|
+
1. If the element already has the right checked state, this method returns immediately.
|
529
|
+
1. Wait for [actionability](https://playwright.dev/python/docs/actionability) checks on the matched element, unless `force` option is set. If the
|
530
|
+
element is detached during the checks, the whole action is retried.
|
531
|
+
1. Scroll the element into view if needed.
|
532
|
+
1. Use [Page#mouse](./page#mouse) to click in the center of the element.
|
533
|
+
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
534
|
+
1. Ensure that the element is now checked or unchecked. If not, this method throws.
|
535
|
+
|
536
|
+
When all steps combined have not finished during the specified `timeout`, this method throws a `TimeoutError`. Passing
|
537
|
+
zero timeout disables this.
|
538
|
+
|
513
539
|
## set_input_files
|
514
540
|
|
515
541
|
```
|
@@ -630,7 +656,7 @@ If the element does not satisfy the condition for the `timeout` milliseconds, th
|
|
630
656
|
## wait_for_selector
|
631
657
|
|
632
658
|
```
|
633
|
-
def wait_for_selector(selector, state: nil, timeout: nil)
|
659
|
+
def wait_for_selector(selector, state: nil, strict: nil, timeout: nil)
|
634
660
|
```
|
635
661
|
|
636
662
|
Returns element specified by selector when it satisfies `state` option. Returns `null` if waiting for `hidden` or
|
@@ -641,12 +667,11 @@ become visible/hidden). If at the moment of calling the method `selector` alread
|
|
641
667
|
will return immediately. If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will
|
642
668
|
throw.
|
643
669
|
|
644
|
-
```
|
645
|
-
page.
|
670
|
+
```ruby
|
671
|
+
page.content = "<div><span></span></div>"
|
646
672
|
div = page.query_selector("div")
|
647
673
|
# waiting for the "span" selector relative to the div.
|
648
|
-
span = div.wait_for_selector("span", state
|
649
|
-
|
674
|
+
span = div.wait_for_selector("span", state: "attached")
|
650
675
|
```
|
651
676
|
|
652
677
|
> NOTE: This method does not work across navigations, use [Page#wait_for_selector](./page#wait_for_selector) instead.
|
@@ -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
|
|
@@ -34,6 +34,7 @@ def launch_browser(
|
|
34
34
|
command: nil,
|
35
35
|
deviceScaleFactor: nil,
|
36
36
|
extraHTTPHeaders: nil,
|
37
|
+
forcedColors: nil,
|
37
38
|
geolocation: nil,
|
38
39
|
hasTouch: nil,
|
39
40
|
httpCredentials: nil,
|
@@ -50,6 +51,7 @@ def launch_browser(
|
|
50
51
|
record_video_size: nil,
|
51
52
|
reducedMotion: nil,
|
52
53
|
screen: nil,
|
54
|
+
strictSelectors: nil,
|
53
55
|
timezoneId: nil,
|
54
56
|
userAgent: nil,
|
55
57
|
viewport: nil,
|
@@ -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
|
|
@@ -176,9 +167,8 @@ The snippet below dispatches the `click` event on the element. Regardless of the
|
|
176
167
|
`click` is dispatched. This is equivalent to calling
|
177
168
|
[element.click()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click).
|
178
169
|
|
179
|
-
```
|
170
|
+
```ruby
|
180
171
|
frame.dispatch_event("button#submit", "click")
|
181
|
-
|
182
172
|
```
|
183
173
|
|
184
174
|
Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties
|
@@ -195,11 +185,10 @@ Since `eventInit` is event-specific, please refer to the events documentation fo
|
|
195
185
|
|
196
186
|
You can also specify [JSHandle](./js_handle) as the property value if you want live objects to be passed into the event:
|
197
187
|
|
198
|
-
```
|
188
|
+
```ruby
|
199
189
|
# note you can only create data_transfer in chromium and firefox
|
200
190
|
data_transfer = frame.evaluate_handle("new DataTransfer()")
|
201
|
-
frame.dispatch_event("#source", "dragstart", {
|
202
|
-
|
191
|
+
frame.dispatch_event("#source", "dragstart", eventInit: { dataTransfer: data_transfer })
|
203
192
|
```
|
204
193
|
|
205
194
|
|
@@ -238,11 +227,10 @@ return its value.
|
|
238
227
|
|
239
228
|
Examples:
|
240
229
|
|
241
|
-
```
|
230
|
+
```ruby
|
242
231
|
search_value = frame.eval_on_selector("#search", "el => el.value")
|
243
232
|
preload_href = frame.eval_on_selector("link[rel=preload]", "el => el.href")
|
244
|
-
html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
|
245
|
-
|
233
|
+
html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", arg: "hello")
|
246
234
|
```
|
247
235
|
|
248
236
|
|
@@ -263,9 +251,8 @@ return its value.
|
|
263
251
|
|
264
252
|
Examples:
|
265
253
|
|
266
|
-
```
|
267
|
-
divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
|
268
|
-
|
254
|
+
```ruby
|
255
|
+
divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", arg: 10)
|
269
256
|
```
|
270
257
|
|
271
258
|
|
@@ -285,28 +272,25 @@ If the function passed to the [Frame#evaluate](./frame#evaluate) returns a non-[
|
|
285
272
|
[Frame#evaluate](./frame#evaluate) returns `undefined`. Playwright also supports transferring some additional values that are
|
286
273
|
not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`.
|
287
274
|
|
288
|
-
```
|
289
|
-
result = frame.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
|
290
|
-
|
291
|
-
|
275
|
+
```ruby
|
276
|
+
result = frame.evaluate("([x, y]) => Promise.resolve(x * y)", arg: [7, 8])
|
277
|
+
puts result # => "56"
|
292
278
|
```
|
293
279
|
|
294
280
|
A string can also be passed in instead of a function.
|
295
281
|
|
296
|
-
```
|
297
|
-
|
282
|
+
```ruby
|
283
|
+
puts frame.evaluate("1 + 2") # => 3
|
298
284
|
x = 10
|
299
|
-
|
300
|
-
|
285
|
+
puts frame.evaluate("1 + #{x}") # => "11"
|
301
286
|
```
|
302
287
|
|
303
288
|
[ElementHandle](./element_handle) instances can be passed as an argument to the [Frame#evaluate](./frame#evaluate):
|
304
289
|
|
305
|
-
```
|
290
|
+
```ruby
|
306
291
|
body_handle = frame.query_selector("body")
|
307
|
-
html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
|
308
|
-
body_handle.dispose
|
309
|
-
|
292
|
+
html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", arg: [body_handle, "hello"])
|
293
|
+
body_handle.dispose
|
310
294
|
```
|
311
295
|
|
312
296
|
|
@@ -325,10 +309,9 @@ The only difference between [Frame#evaluate](./frame#evaluate) and [Frame#evalua
|
|
325
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
|
326
310
|
[Frame#evaluate_handle](./frame#evaluate_handle) would wait for the promise to resolve and return its value.
|
327
311
|
|
328
|
-
```
|
312
|
+
```ruby
|
329
313
|
a_window_handle = frame.evaluate_handle("Promise.resolve(window)")
|
330
314
|
a_window_handle # handle for the window object.
|
331
|
-
|
332
315
|
```
|
333
316
|
|
334
317
|
A string can also be passed in instead of a function.
|
@@ -393,11 +376,10 @@ frame.
|
|
393
376
|
|
394
377
|
This method throws an error if the frame has been detached before `frameElement()` returns.
|
395
378
|
|
396
|
-
```
|
397
|
-
frame_element = frame.frame_element
|
398
|
-
content_frame = frame_element.content_frame
|
399
|
-
|
400
|
-
|
379
|
+
```ruby
|
380
|
+
frame_element = frame.frame_element
|
381
|
+
content_frame = frame_element.content_frame
|
382
|
+
puts frame == content_frame # => true
|
401
383
|
```
|
402
384
|
|
403
385
|
|
@@ -419,18 +401,18 @@ def goto(url, referer: nil, timeout: nil, waitUntil: nil)
|
|
419
401
|
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
|
420
402
|
last redirect.
|
421
403
|
|
422
|
-
|
404
|
+
The method will throw an error if:
|
423
405
|
- there's an SSL error (e.g. in case of self-signed certificates).
|
424
406
|
- target URL is invalid.
|
425
407
|
- the `timeout` is exceeded during navigation.
|
426
408
|
- the remote server does not respond or is unreachable.
|
427
409
|
- the main resource failed to load.
|
428
410
|
|
429
|
-
|
430
|
-
|
411
|
+
The method will not throw an error when any valid HTTP status code is returned by the remote server, including 404 "Not
|
412
|
+
Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling
|
431
413
|
[Response#status](./response#status).
|
432
414
|
|
433
|
-
> NOTE:
|
415
|
+
> NOTE: The method either throws an error or returns a main resource response. The only exceptions are navigation to
|
434
416
|
`about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.
|
435
417
|
> NOTE: Headless mode doesn't support navigation to a PDF document. See the
|
436
418
|
[upstream issue](https://bugs.chromium.org/p/chromium/issues/detail?id=761295).
|
@@ -551,8 +533,6 @@ The method returns an element locator that can be used to perform actions in the
|
|
551
533
|
element immediately before performing an action, so a series of actions on the same locator can in fact be performed on
|
552
534
|
different DOM elements. That would happen if the DOM structure between those actions has changed.
|
553
535
|
|
554
|
-
Note that locator always implies visibility, so it will always be locating visible elements.
|
555
|
-
|
556
536
|
## name
|
557
537
|
|
558
538
|
```
|
@@ -658,17 +638,44 @@ Returns the array of option values that have been successfully selected.
|
|
658
638
|
|
659
639
|
Triggers a `change` and `input` event once all the provided options have been selected.
|
660
640
|
|
661
|
-
```
|
641
|
+
```ruby
|
662
642
|
# single selection matching the value
|
663
|
-
frame.select_option("select#colors", "blue")
|
643
|
+
frame.select_option("select#colors", value: "blue")
|
664
644
|
# single selection matching both the label
|
665
|
-
frame.select_option("select#colors", label
|
645
|
+
frame.select_option("select#colors", label: "blue")
|
666
646
|
# multiple selection
|
667
|
-
frame.select_option("select#colors", value
|
647
|
+
frame.select_option("select#colors", value: ["red", "green", "blue"])
|
648
|
+
```
|
649
|
+
|
650
|
+
|
651
|
+
|
652
|
+
## set_checked
|
668
653
|
|
669
654
|
```
|
655
|
+
def set_checked(
|
656
|
+
selector,
|
657
|
+
checked,
|
658
|
+
force: nil,
|
659
|
+
noWaitAfter: nil,
|
660
|
+
position: nil,
|
661
|
+
strict: nil,
|
662
|
+
timeout: nil,
|
663
|
+
trial: nil)
|
664
|
+
```
|
670
665
|
|
666
|
+
This method checks or unchecks an element matching `selector` by performing the following steps:
|
667
|
+
1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
668
|
+
1. Ensure that matched element is a checkbox or a radio input. If not, this method throws.
|
669
|
+
1. If the element already has the right checked state, this method returns immediately.
|
670
|
+
1. Wait for [actionability](https://playwright.dev/python/docs/actionability) checks on the matched element, unless `force` option is set. If the
|
671
|
+
element is detached during the checks, the whole action is retried.
|
672
|
+
1. Scroll the element into view if needed.
|
673
|
+
1. Use [Page#mouse](./page#mouse) to click in the center of the element.
|
674
|
+
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
675
|
+
1. Ensure that the element is now checked or unchecked. If not, this method throws.
|
671
676
|
|
677
|
+
When all steps combined have not finished during the specified `timeout`, this method throws a `TimeoutError`. Passing
|
678
|
+
zero timeout disables this.
|
672
679
|
|
673
680
|
## set_content
|
674
681
|
|
@@ -756,10 +763,9 @@ send fine-grained keyboard events. To fill values in form fields, use [Frame#fil
|
|
756
763
|
|
757
764
|
To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./keyboard#press).
|
758
765
|
|
759
|
-
```
|
766
|
+
```ruby
|
760
767
|
frame.type("#mytextarea", "hello") # types instantly
|
761
|
-
frame.type("#mytextarea", "world", delay
|
762
|
-
|
768
|
+
frame.type("#mytextarea", "world", delay: 100) # types slower, like a user
|
763
769
|
```
|
764
770
|
|
765
771
|
|
@@ -809,28 +815,16 @@ Returns when the `expression` returns a truthy value, returns that value.
|
|
809
815
|
|
810
816
|
The [Frame#wait_for_function](./frame#wait_for_function) can be used to observe viewport size change:
|
811
817
|
|
812
|
-
```
|
813
|
-
|
814
|
-
|
815
|
-
def run(playwright):
|
816
|
-
webkit = playwright.webkit
|
817
|
-
browser = webkit.launch()
|
818
|
-
page = browser.new_page()
|
819
|
-
page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
|
820
|
-
page.main_frame.wait_for_function("() => window.x > 0")
|
821
|
-
browser.close()
|
822
|
-
|
823
|
-
with sync_playwright() as playwright:
|
824
|
-
run(playwright)
|
825
|
-
|
818
|
+
```ruby
|
819
|
+
frame.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
|
820
|
+
frame.wait_for_function("() => window.x > 0")
|
826
821
|
```
|
827
822
|
|
828
823
|
To pass an argument to the predicate of `frame.waitForFunction` function:
|
829
824
|
|
830
|
-
```
|
825
|
+
```ruby
|
831
826
|
selector = ".foo"
|
832
|
-
frame.wait_for_function("selector => !!document.querySelector(selector)", selector)
|
833
|
-
|
827
|
+
frame.wait_for_function("selector => !!document.querySelector(selector)", arg: selector)
|
834
828
|
```
|
835
829
|
|
836
830
|
|
@@ -846,10 +840,9 @@ Waits for the required load state to be reached.
|
|
846
840
|
This returns when the frame reaches a required load state, `load` by default. The navigation must have been committed
|
847
841
|
when this method is called. If current document has already reached the required state, resolves immediately.
|
848
842
|
|
849
|
-
```
|
843
|
+
```ruby
|
850
844
|
frame.click("button") # click triggers navigation.
|
851
|
-
frame.wait_for_load_state
|
852
|
-
|
845
|
+
frame.wait_for_load_state # the promise resolves after "load" event.
|
853
846
|
```
|
854
847
|
|
855
848
|
|
@@ -867,11 +860,10 @@ History API usage, the navigation will resolve with `null`.
|
|
867
860
|
This method waits for the frame to navigate to a new URL. It is useful for when you run code which will indirectly cause
|
868
861
|
the frame to navigate. Consider this example:
|
869
862
|
|
870
|
-
```
|
871
|
-
|
872
|
-
|
873
|
-
# Resolves after navigation has finished
|
874
|
-
|
863
|
+
```ruby
|
864
|
+
frame.expect_navigation do
|
865
|
+
frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
|
866
|
+
end # Resolves after navigation has finished
|
875
867
|
```
|
876
868
|
|
877
869
|
> NOTE: Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is
|
@@ -892,22 +884,13 @@ selector doesn't satisfy the condition for the `timeout` milliseconds, the funct
|
|
892
884
|
|
893
885
|
This method works across navigations:
|
894
886
|
|
895
|
-
```
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
for current_url in ["https://google.com", "https://bbc.com"]:
|
903
|
-
page.goto(current_url, wait_until="domcontentloaded")
|
904
|
-
element = page.main_frame.wait_for_selector("img")
|
905
|
-
print("Loaded image: " + str(element.get_attribute("src")))
|
906
|
-
browser.close()
|
907
|
-
|
908
|
-
with sync_playwright() as playwright:
|
909
|
-
run(playwright)
|
910
|
-
|
887
|
+
```ruby
|
888
|
+
%w[https://google.com https://bbc.com].each do |current_url|
|
889
|
+
page.goto(current_url, waitUntil: "domcontentloaded")
|
890
|
+
frame = page.main_frame
|
891
|
+
element = frame.wait_for_selector("img")
|
892
|
+
puts "Loaded image: #{element["src"]}"
|
893
|
+
end
|
911
894
|
```
|
912
895
|
|
913
896
|
|
@@ -931,10 +914,9 @@ def wait_for_url(url, timeout: nil, waitUntil: nil)
|
|
931
914
|
|
932
915
|
Waits for the frame to navigate to the given URL.
|
933
916
|
|
934
|
-
```
|
917
|
+
```ruby
|
935
918
|
frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
|
936
919
|
frame.wait_for_url("**/target.html")
|
937
|
-
|
938
920
|
```
|
939
921
|
|
940
922
|
|