playwright-ruby-client 0.6.6 → 0.8.1
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 +26 -0
- data/documentation/docs/api/browser.md +18 -2
- data/documentation/docs/api/browser_context.md +10 -0
- data/documentation/docs/api/browser_type.md +1 -0
- data/documentation/docs/api/cdp_session.md +41 -1
- data/documentation/docs/api/element_handle.md +11 -2
- data/documentation/docs/api/experimental/android_device.md +1 -0
- data/documentation/docs/api/frame.md +29 -1
- data/documentation/docs/api/keyboard.md +11 -20
- data/documentation/docs/api/page.md +48 -2
- data/documentation/docs/api/response.md +16 -0
- data/documentation/docs/api/web_socket.md +37 -0
- data/documentation/docs/article/guides/launch_browser.md +2 -0
- data/documentation/docs/article/guides/playwright_on_alpine_linux.md +91 -0
- data/documentation/docs/article/guides/rails_integration.md +1 -1
- data/documentation/docs/article/guides/semi_automation.md +71 -0
- data/documentation/docs/include/api_coverage.md +18 -11
- data/lib/playwright.rb +36 -3
- data/lib/playwright/channel_owners/artifact.rb +4 -0
- data/lib/playwright/channel_owners/browser.rb +5 -0
- data/lib/playwright/channel_owners/browser_context.rb +12 -3
- data/lib/playwright/channel_owners/cdp_session.rb +19 -0
- data/lib/playwright/channel_owners/element_handle.rb +11 -4
- data/lib/playwright/channel_owners/frame.rb +36 -4
- data/lib/playwright/channel_owners/page.rb +45 -16
- data/lib/playwright/channel_owners/response.rb +9 -1
- data/lib/playwright/channel_owners/web_socket.rb +83 -0
- data/lib/playwright/connection.rb +2 -4
- data/lib/playwright/download.rb +4 -0
- data/lib/playwright/route_handler_entry.rb +3 -2
- data/lib/playwright/transport.rb +0 -1
- data/lib/playwright/url_matcher.rb +12 -2
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright/web_socket_client.rb +164 -0
- data/lib/playwright/web_socket_transport.rb +104 -0
- data/lib/playwright_api/android.rb +6 -6
- data/lib/playwright_api/android_device.rb +10 -9
- data/lib/playwright_api/browser.rb +17 -11
- data/lib/playwright_api/browser_context.rb +7 -7
- data/lib/playwright_api/browser_type.rb +8 -7
- data/lib/playwright_api/cdp_session.rb +30 -8
- data/lib/playwright_api/console_message.rb +6 -6
- data/lib/playwright_api/dialog.rb +6 -6
- data/lib/playwright_api/element_handle.rb +17 -11
- data/lib/playwright_api/frame.rb +30 -9
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/page.rb +39 -18
- data/lib/playwright_api/playwright.rb +6 -6
- data/lib/playwright_api/request.rb +6 -6
- data/lib/playwright_api/response.rb +15 -10
- data/lib/playwright_api/route.rb +6 -6
- data/lib/playwright_api/selectors.rb +6 -6
- data/lib/playwright_api/web_socket.rb +12 -12
- data/lib/playwright_api/worker.rb +6 -6
- data/playwright.gemspec +2 -1
- metadata +37 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e631604c0af31dc184fd1bfe6953be910d4f19be8613e8a2a11c83a3d5e9049
|
4
|
+
data.tar.gz: b320853082ae065cc09195f09e35f9a5bf18edc3105c729c9bd4a4daeb804948
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ea608b469db2082b899c3b4c10cbfea703f222a79fb255a0d07d03eb46eacbd0274cb98c1c32a9241f120f5059bdb20fbc82a65a072c05e616bdbd4b76586aa
|
7
|
+
data.tar.gz: 50ea41552e79e96add337084c9a38961bae124dfcaf04c9fe3ab61ceb2cd5e8738f0ae6fffdb6e04157416593f351bc7177e03e0da75cf51a80e929e1bce3f42
|
data/README.md
CHANGED
@@ -159,6 +159,32 @@ end
|
|
159
159
|
|
160
160
|
```
|
161
161
|
|
162
|
+
### Communicate with Playwright server
|
163
|
+
|
164
|
+
If your environment doesn't accept installing browser or creating browser process, consider separating Ruby client and Playwright server.
|
165
|
+
|
166
|
+

|
167
|
+
|
168
|
+
For launching Playwright server, just execute:
|
169
|
+
|
170
|
+
```
|
171
|
+
npx playwright install && npx playwright run-server 8080
|
172
|
+
```
|
173
|
+
|
174
|
+
and we can connect to the server with the code like this:
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
Playwright.connect_to_playwright_server('ws://127.0.0.1:8080') do |playwright|
|
178
|
+
playwright.chromium.launch do |browser|
|
179
|
+
page = browser.new_page
|
180
|
+
page.goto('https://github.com/YusukeIwaki')
|
181
|
+
page.screenshot(path: './YusukeIwaki.png')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
When `Playwright.connect_to_playwright_server` is used, playwright_cli_executable_path is not required.
|
187
|
+
|
162
188
|
## License
|
163
189
|
|
164
190
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -61,11 +61,22 @@ def connected?
|
|
61
61
|
|
62
62
|
Indicates that the browser is connected.
|
63
63
|
|
64
|
+
## new_browser_cdp_session
|
65
|
+
|
66
|
+
```
|
67
|
+
def new_browser_cdp_session
|
68
|
+
```
|
69
|
+
|
70
|
+
> NOTE: CDP Sessions are only supported on Chromium-based browsers.
|
71
|
+
|
72
|
+
Returns the newly created browser session.
|
73
|
+
|
64
74
|
## new_context
|
65
75
|
|
66
76
|
```
|
67
77
|
def new_context(
|
68
78
|
acceptDownloads: nil,
|
79
|
+
baseURL: nil,
|
69
80
|
bypassCSP: nil,
|
70
81
|
colorScheme: nil,
|
71
82
|
deviceScaleFactor: nil,
|
@@ -114,6 +125,7 @@ end
|
|
114
125
|
```
|
115
126
|
def new_page(
|
116
127
|
acceptDownloads: nil,
|
128
|
+
baseURL: nil,
|
117
129
|
bypassCSP: nil,
|
118
130
|
colorScheme: nil,
|
119
131
|
deviceScaleFactor: nil,
|
@@ -154,7 +166,9 @@ testing frameworks should explicitly create [Browser#new_context](./browser#new_
|
|
154
166
|
def start_tracing(page: nil, categories: nil, path: nil, screenshots: nil)
|
155
167
|
```
|
156
168
|
|
157
|
-
> NOTE:
|
169
|
+
> NOTE: This API controls [Chromium Tracing](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool)
|
170
|
+
which is a low-level chromium-specific debugging tool. API to control [Playwright Tracing](https://playwright.dev/python/docs/trace-viewer) could be
|
171
|
+
found [here](./tracing).
|
158
172
|
|
159
173
|
You can use [Browser#start_tracing](./browser#start_tracing) and [Browser#stop_tracing](./browser#stop_tracing) to create a trace file that can be
|
160
174
|
opened in Chrome DevTools performance panel.
|
@@ -175,7 +189,9 @@ end
|
|
175
189
|
def stop_tracing
|
176
190
|
```
|
177
191
|
|
178
|
-
> NOTE:
|
192
|
+
> NOTE: This API controls [Chromium Tracing](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool)
|
193
|
+
which is a low-level chromium-specific debugging tool. API to control [Playwright Tracing](https://playwright.dev/python/docs/trace-viewer) could be
|
194
|
+
found [here](./tracing).
|
179
195
|
|
180
196
|
Returns the buffer with trace data.
|
181
197
|
|
@@ -226,6 +226,16 @@ def grant_permissions(permissions, origin: nil)
|
|
226
226
|
Grants specified permissions to the browser context. Only grants corresponding permissions to the given origin if
|
227
227
|
specified.
|
228
228
|
|
229
|
+
## new_cdp_session
|
230
|
+
|
231
|
+
```
|
232
|
+
def new_cdp_session(page)
|
233
|
+
```
|
234
|
+
|
235
|
+
> NOTE: CDP sessions are only supported on Chromium-based browsers.
|
236
|
+
|
237
|
+
Returns the newly created session.
|
238
|
+
|
229
239
|
## new_page
|
230
240
|
|
231
241
|
```
|
@@ -4,4 +4,44 @@ sidebar_position: 10
|
|
4
4
|
|
5
5
|
# CDPSession
|
6
6
|
|
7
|
-
|
7
|
+
- extends: [EventEmitter]
|
8
|
+
|
9
|
+
The [CDPSession](./cdp_session) instances are used to talk raw Chrome Devtools Protocol:
|
10
|
+
- protocol methods can be called with `session.send_message` method.
|
11
|
+
- protocol events can be subscribed to with `session.on` method.
|
12
|
+
|
13
|
+
Useful links:
|
14
|
+
- Documentation on DevTools Protocol can be found here:
|
15
|
+
[DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/).
|
16
|
+
- Getting Started with DevTools Protocol:
|
17
|
+
https://github.com/aslushnikov/getting-started-with-cdp/blob/master/README.md
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
client = page.context.new_cdp_session(page)
|
21
|
+
client.send_message('Animation.enable')
|
22
|
+
client.on('Animation.animationCreated', -> (_) { puts 'Animation Created' })
|
23
|
+
response = client.send_message('Animation.getPlaybackRate')
|
24
|
+
puts "Playback rate is #{response['playbackRate']}"
|
25
|
+
client.send_message(
|
26
|
+
'Animation.setPlaybackRate',
|
27
|
+
params: { playbackRate: response['playbackRate'] / 2.0 },
|
28
|
+
)
|
29
|
+
```
|
30
|
+
|
31
|
+
|
32
|
+
## detach
|
33
|
+
|
34
|
+
```
|
35
|
+
def detach
|
36
|
+
```
|
37
|
+
|
38
|
+
Detaches the CDPSession from the target. Once detached, the CDPSession object won't emit any events and can't be used to
|
39
|
+
send messages.
|
40
|
+
|
41
|
+
## send_message
|
42
|
+
|
43
|
+
```
|
44
|
+
def send_message(method, params: nil)
|
45
|
+
```
|
46
|
+
|
47
|
+
|
@@ -232,7 +232,7 @@ feed_handle.eval_on_selector_all(".tweet", "nodes => nodes.map(n => n.innerText)
|
|
232
232
|
## fill
|
233
233
|
|
234
234
|
```
|
235
|
-
def fill(value, noWaitAfter: nil, timeout: nil)
|
235
|
+
def fill(value, force: nil, noWaitAfter: nil, timeout: nil)
|
236
236
|
```
|
237
237
|
|
238
238
|
This method waits for [actionability](https://playwright.dev/python/docs/actionability) checks, focuses the element, fills it and triggers an `input`
|
@@ -300,6 +300,14 @@ def inner_text
|
|
300
300
|
|
301
301
|
Returns the `element.innerText`.
|
302
302
|
|
303
|
+
## input_value
|
304
|
+
|
305
|
+
```
|
306
|
+
def input_value(timeout: nil)
|
307
|
+
```
|
308
|
+
|
309
|
+
Returns `input.value` for `<input>` or `<textarea>` element. Throws for non-input elements.
|
310
|
+
|
303
311
|
## checked?
|
304
312
|
|
305
313
|
```
|
@@ -436,6 +444,7 @@ def select_option(
|
|
436
444
|
index: nil,
|
437
445
|
value: nil,
|
438
446
|
label: nil,
|
447
|
+
force: nil,
|
439
448
|
noWaitAfter: nil,
|
440
449
|
timeout: nil)
|
441
450
|
```
|
@@ -470,7 +479,7 @@ element_handle.select_option(value: "blue", index: 2, label: "red")
|
|
470
479
|
## select_text
|
471
480
|
|
472
481
|
```
|
473
|
-
def select_text(timeout: nil)
|
482
|
+
def select_text(force: nil, timeout: nil)
|
474
483
|
```
|
475
484
|
|
476
485
|
This method waits for [actionability](https://playwright.dev/python/docs/actionability) checks, then focuses the element and selects all its text
|
@@ -196,6 +196,20 @@ frame.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
|
|
196
196
|
|
197
197
|
|
198
198
|
|
199
|
+
## drag_and_drop
|
200
|
+
|
201
|
+
```
|
202
|
+
def drag_and_drop(
|
203
|
+
source,
|
204
|
+
target,
|
205
|
+
force: nil,
|
206
|
+
noWaitAfter: nil,
|
207
|
+
timeout: nil,
|
208
|
+
trial: nil)
|
209
|
+
```
|
210
|
+
|
211
|
+
|
212
|
+
|
199
213
|
## eval_on_selector
|
200
214
|
|
201
215
|
```
|
@@ -326,7 +340,12 @@ result_handle.dispose
|
|
326
340
|
## fill
|
327
341
|
|
328
342
|
```
|
329
|
-
def fill(
|
343
|
+
def fill(
|
344
|
+
selector,
|
345
|
+
value,
|
346
|
+
force: nil,
|
347
|
+
noWaitAfter: nil,
|
348
|
+
timeout: nil)
|
330
349
|
```
|
331
350
|
|
332
351
|
This method waits for an element matching `selector`, waits for [actionability](https://playwright.dev/python/docs/actionability) checks, focuses the
|
@@ -443,6 +462,14 @@ def inner_text(selector, timeout: nil)
|
|
443
462
|
|
444
463
|
Returns `element.innerText`.
|
445
464
|
|
465
|
+
## input_value
|
466
|
+
|
467
|
+
```
|
468
|
+
def input_value(selector, timeout: nil)
|
469
|
+
```
|
470
|
+
|
471
|
+
Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
|
472
|
+
|
446
473
|
## checked?
|
447
474
|
|
448
475
|
```
|
@@ -588,6 +615,7 @@ def select_option(
|
|
588
615
|
index: nil,
|
589
616
|
value: nil,
|
590
617
|
label: nil,
|
618
|
+
force: nil,
|
591
619
|
noWaitAfter: nil,
|
592
620
|
timeout: nil)
|
593
621
|
```
|
@@ -12,35 +12,31 @@ to manually fire events as if they were generated from a real keyboard.
|
|
12
12
|
|
13
13
|
An example of holding down `Shift` in order to select and delete some text:
|
14
14
|
|
15
|
-
```
|
15
|
+
```ruby
|
16
16
|
page.keyboard.type("Hello World!")
|
17
17
|
page.keyboard.press("ArrowLeft")
|
18
18
|
page.keyboard.down("Shift")
|
19
|
-
|
20
|
-
page.keyboard.press("ArrowLeft")
|
19
|
+
6.times { page.keyboard.press("ArrowLeft") }
|
21
20
|
page.keyboard.up("Shift")
|
22
21
|
page.keyboard.press("Backspace")
|
23
22
|
# result text will end up saying "Hello!"
|
24
|
-
|
25
23
|
```
|
26
24
|
|
27
25
|
An example of pressing uppercase `A`
|
28
26
|
|
29
|
-
```
|
27
|
+
```ruby
|
30
28
|
page.keyboard.press("Shift+KeyA")
|
31
29
|
# or
|
32
30
|
page.keyboard.press("Shift+A")
|
33
|
-
|
34
31
|
```
|
35
32
|
|
36
33
|
An example to trigger select-all with the keyboard
|
37
34
|
|
38
|
-
```
|
35
|
+
```ruby
|
39
36
|
# on windows and linux
|
40
37
|
page.keyboard.press("Control+A")
|
41
38
|
# on mac_os
|
42
39
|
page.keyboard.press("Meta+A")
|
43
|
-
|
44
40
|
```
|
45
41
|
|
46
42
|
|
@@ -84,9 +80,8 @@ def insert_text(text)
|
|
84
80
|
|
85
81
|
Dispatches only `input` event, does not emit the `keydown`, `keyup` or `keypress` events.
|
86
82
|
|
87
|
-
```
|
83
|
+
```ruby
|
88
84
|
page.keyboard.insert_text("嗨")
|
89
|
-
|
90
85
|
```
|
91
86
|
|
92
87
|
> NOTE: Modifier keys DO NOT effect `keyboard.insertText`. Holding down `Shift` will not type the text in upper case.
|
@@ -114,17 +109,14 @@ texts.
|
|
114
109
|
Shortcuts such as `key: "Control+o"` or `key: "Control+Shift+T"` are supported as well. When specified with the
|
115
110
|
modifier, modifier is pressed and being held while the subsequent key is being pressed.
|
116
111
|
|
117
|
-
```
|
118
|
-
page = browser.new_page()
|
112
|
+
```ruby
|
119
113
|
page.goto("https://keycode.info")
|
120
114
|
page.keyboard.press("a")
|
121
|
-
page.screenshot(path
|
115
|
+
page.screenshot(path: "a.png")
|
122
116
|
page.keyboard.press("ArrowLeft")
|
123
|
-
page.screenshot(path
|
117
|
+
page.screenshot(path: "arrow_left.png")
|
124
118
|
page.keyboard.press("Shift+O")
|
125
|
-
page.screenshot(path
|
126
|
-
browser.close()
|
127
|
-
|
119
|
+
page.screenshot(path: "o.png")
|
128
120
|
```
|
129
121
|
|
130
122
|
Shortcut for [Keyboard#down](./keyboard#down) and [Keyboard#up](./keyboard#up).
|
@@ -139,10 +131,9 @@ Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in t
|
|
139
131
|
|
140
132
|
To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./keyboard#press).
|
141
133
|
|
142
|
-
```
|
134
|
+
```ruby
|
143
135
|
page.keyboard.type("Hello") # types instantly
|
144
|
-
page.keyboard.type("World", delay
|
145
|
-
|
136
|
+
page.keyboard.type("World", delay: 100) # types slower, like a user
|
146
137
|
```
|
147
138
|
|
148
139
|
> NOTE: Modifier keys DO NOT effect `keyboard.type`. Holding down `Shift` will not type the text in upper case.
|
@@ -253,6 +253,20 @@ page.dispatch_event("#source", "dragstart", eventInit: { dataTransfer: data_tran
|
|
253
253
|
|
254
254
|
|
255
255
|
|
256
|
+
## drag_and_drop
|
257
|
+
|
258
|
+
```
|
259
|
+
def drag_and_drop(
|
260
|
+
source,
|
261
|
+
target,
|
262
|
+
force: nil,
|
263
|
+
noWaitAfter: nil,
|
264
|
+
timeout: nil,
|
265
|
+
trial: nil)
|
266
|
+
```
|
267
|
+
|
268
|
+
|
269
|
+
|
256
270
|
## emulate_media
|
257
271
|
|
258
272
|
```
|
@@ -499,7 +513,12 @@ page.click("button")
|
|
499
513
|
## fill
|
500
514
|
|
501
515
|
```
|
502
|
-
def fill(
|
516
|
+
def fill(
|
517
|
+
selector,
|
518
|
+
value,
|
519
|
+
force: nil,
|
520
|
+
noWaitAfter: nil,
|
521
|
+
timeout: nil)
|
503
522
|
```
|
504
523
|
|
505
524
|
This method waits for an element matching `selector`, waits for [actionability](https://playwright.dev/python/docs/actionability) checks, focuses the
|
@@ -650,6 +669,14 @@ def inner_text(selector, timeout: nil)
|
|
650
669
|
|
651
670
|
Returns `element.innerText`.
|
652
671
|
|
672
|
+
## input_value
|
673
|
+
|
674
|
+
```
|
675
|
+
def input_value(selector, timeout: nil)
|
676
|
+
```
|
677
|
+
|
678
|
+
Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
|
679
|
+
|
653
680
|
## checked?
|
654
681
|
|
655
682
|
```
|
@@ -934,6 +961,7 @@ def select_option(
|
|
934
961
|
index: nil,
|
935
962
|
value: nil,
|
936
963
|
label: nil,
|
964
|
+
force: nil,
|
937
965
|
noWaitAfter: nil,
|
938
966
|
timeout: nil)
|
939
967
|
```
|
@@ -1306,7 +1334,7 @@ Performs action and waits for a popup [Page](./page). If predicate is provided,
|
|
1306
1334
|
def expect_request(urlOrPredicate, timeout: nil, &block)
|
1307
1335
|
```
|
1308
1336
|
|
1309
|
-
Waits for the matching request and returns it.
|
1337
|
+
Waits for the matching request and returns it. See [waiting for event](https://playwright.dev/python/docs/events) for more details
|
1310
1338
|
about events.
|
1311
1339
|
|
1312
1340
|
```ruby
|
@@ -1328,6 +1356,16 @@ puts request.headers
|
|
1328
1356
|
|
1329
1357
|
|
1330
1358
|
|
1359
|
+
## expect_request_finished
|
1360
|
+
|
1361
|
+
```
|
1362
|
+
def expect_request_finished(predicate: nil, timeout: nil, &block)
|
1363
|
+
```
|
1364
|
+
|
1365
|
+
Performs action and waits for a [Request](./request) to finish loading. If predicate is provided, it passes [Request](./request) value into
|
1366
|
+
the `predicate` function and waits for `predicate(request)` to return a truthy value. Will throw an error if the page is
|
1367
|
+
closed before the [`event: Page.requestFinished`] event is fired.
|
1368
|
+
|
1331
1369
|
## expect_response
|
1332
1370
|
|
1333
1371
|
```
|
@@ -1393,6 +1431,14 @@ page.wait_for_url("**/target.html")
|
|
1393
1431
|
|
1394
1432
|
Shortcut for main frame's [Frame#wait_for_url](./frame#wait_for_url).
|
1395
1433
|
|
1434
|
+
## expect_websocket
|
1435
|
+
|
1436
|
+
```
|
1437
|
+
def expect_websocket(predicate: nil, timeout: nil, &block)
|
1438
|
+
```
|
1439
|
+
|
1440
|
+
Performs action and waits for a new [WebSocket](./web_socket). If predicate is provided, it passes [WebSocket](./web_socket) value into the `predicate` function and waits for `predicate.call(web_socket)` to return a truthy value. Will throw an error if the page is closed before the WebSocket event is fired.
|
1441
|
+
|
1396
1442
|
## accessibility
|
1397
1443
|
|
1398
1444
|
## keyboard
|