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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -0
  3. data/documentation/docs/api/browser.md +18 -2
  4. data/documentation/docs/api/browser_context.md +10 -0
  5. data/documentation/docs/api/browser_type.md +1 -0
  6. data/documentation/docs/api/cdp_session.md +41 -1
  7. data/documentation/docs/api/element_handle.md +11 -2
  8. data/documentation/docs/api/experimental/android_device.md +1 -0
  9. data/documentation/docs/api/frame.md +29 -1
  10. data/documentation/docs/api/keyboard.md +11 -20
  11. data/documentation/docs/api/page.md +48 -2
  12. data/documentation/docs/api/response.md +16 -0
  13. data/documentation/docs/api/web_socket.md +37 -0
  14. data/documentation/docs/article/guides/launch_browser.md +2 -0
  15. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +91 -0
  16. data/documentation/docs/article/guides/rails_integration.md +1 -1
  17. data/documentation/docs/article/guides/semi_automation.md +71 -0
  18. data/documentation/docs/include/api_coverage.md +18 -11
  19. data/lib/playwright.rb +36 -3
  20. data/lib/playwright/channel_owners/artifact.rb +4 -0
  21. data/lib/playwright/channel_owners/browser.rb +5 -0
  22. data/lib/playwright/channel_owners/browser_context.rb +12 -3
  23. data/lib/playwright/channel_owners/cdp_session.rb +19 -0
  24. data/lib/playwright/channel_owners/element_handle.rb +11 -4
  25. data/lib/playwright/channel_owners/frame.rb +36 -4
  26. data/lib/playwright/channel_owners/page.rb +45 -16
  27. data/lib/playwright/channel_owners/response.rb +9 -1
  28. data/lib/playwright/channel_owners/web_socket.rb +83 -0
  29. data/lib/playwright/connection.rb +2 -4
  30. data/lib/playwright/download.rb +4 -0
  31. data/lib/playwright/route_handler_entry.rb +3 -2
  32. data/lib/playwright/transport.rb +0 -1
  33. data/lib/playwright/url_matcher.rb +12 -2
  34. data/lib/playwright/version.rb +2 -2
  35. data/lib/playwright/web_socket_client.rb +164 -0
  36. data/lib/playwright/web_socket_transport.rb +104 -0
  37. data/lib/playwright_api/android.rb +6 -6
  38. data/lib/playwright_api/android_device.rb +10 -9
  39. data/lib/playwright_api/browser.rb +17 -11
  40. data/lib/playwright_api/browser_context.rb +7 -7
  41. data/lib/playwright_api/browser_type.rb +8 -7
  42. data/lib/playwright_api/cdp_session.rb +30 -8
  43. data/lib/playwright_api/console_message.rb +6 -6
  44. data/lib/playwright_api/dialog.rb +6 -6
  45. data/lib/playwright_api/element_handle.rb +17 -11
  46. data/lib/playwright_api/frame.rb +30 -9
  47. data/lib/playwright_api/js_handle.rb +6 -6
  48. data/lib/playwright_api/page.rb +39 -18
  49. data/lib/playwright_api/playwright.rb +6 -6
  50. data/lib/playwright_api/request.rb +6 -6
  51. data/lib/playwright_api/response.rb +15 -10
  52. data/lib/playwright_api/route.rb +6 -6
  53. data/lib/playwright_api/selectors.rb +6 -6
  54. data/lib/playwright_api/web_socket.rb +12 -12
  55. data/lib/playwright_api/worker.rb +6 -6
  56. data/playwright.gemspec +2 -1
  57. metadata +37 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b548b6927a468b4a1209e9002cc7ca6f20bf0ad7ad4091510336ed610d338bb
4
- data.tar.gz: d8f5e411d5ee99460e77d3d922608996cde6de1a2199ee0f6425c7e3a5eb9a7b
3
+ metadata.gz: 2e631604c0af31dc184fd1bfe6953be910d4f19be8613e8a2a11c83a3d5e9049
4
+ data.tar.gz: b320853082ae065cc09195f09e35f9a5bf18edc3105c729c9bd4a4daeb804948
5
5
  SHA512:
6
- metadata.gz: 645bd780e189153fabc25de3a58b490ae5fb919c8ed9b81f701c8bed0e910483be9cb2c901bda8f4619153bb18924240ae43841b197479665883567980ffd29c
7
- data.tar.gz: 50af6ab226985f5bd7a7631fab3959c4215a6bae7d57d32c5cd9787f7d43a8ed2bbe599443a611a9eafd73e7e8dd74ace7783781a95d04357d5a9ff4c4e69313
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
+ ![structure](https://user-images.githubusercontent.com/11763113/124934448-ad4d0700-e03f-11eb-942e-b9f3282bb703.png)
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: Tracing is only supported on Chromium-based browsers.
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: Tracing is only supported on Chromium-based browsers.
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
  ```
@@ -103,6 +103,7 @@ def launch_persistent_context(
103
103
  userDataDir,
104
104
  acceptDownloads: nil,
105
105
  args: nil,
106
+ baseURL: nil,
106
107
  bypassCSP: nil,
107
108
  channel: nil,
108
109
  chromiumSandbox: nil,
@@ -4,4 +4,44 @@ sidebar_position: 10
4
4
 
5
5
  # CDPSession
6
6
 
7
- Not Implemented
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
@@ -28,6 +28,7 @@ Returns information about a widget defined by `selector`.
28
28
  ```
29
29
  def launch_browser(
30
30
  acceptDownloads: nil,
31
+ baseURL: nil,
31
32
  bypassCSP: nil,
32
33
  colorScheme: nil,
33
34
  command: nil,
@@ -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(selector, value, noWaitAfter: nil, timeout: nil)
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
- ```python sync title=example_575870a45e4fe08d3e06be3420e8a11be03f85791cd8174f27198c016031ae72.py
15
+ ```ruby
16
16
  page.keyboard.type("Hello World!")
17
17
  page.keyboard.press("ArrowLeft")
18
18
  page.keyboard.down("Shift")
19
- for i in range(6):
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
- ```python sync title=example_a4f00f0cd486431b7eca785304f4e9715522da45b66dda7f3a5f6899b889b9fd.py
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
- ```python sync title=example_2deda0786a20a28cec9e8b438078a5fc567f7c7e5cf369419ab3c4d80a319ff6.py
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
- ```python sync title=example_a9cc2667e9f3e3b8c619649d7e4a7f5db9463e0b76d67a5e588158093a9e9124.py
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
- ```python sync title=example_88943eb85c1ac7c261601e6edbdead07a31c2784326c496e10667ede1a853bab.py
118
- page = browser.new_page()
112
+ ```ruby
119
113
  page.goto("https://keycode.info")
120
114
  page.keyboard.press("a")
121
- page.screenshot(path="a.png")
115
+ page.screenshot(path: "a.png")
122
116
  page.keyboard.press("ArrowLeft")
123
- page.screenshot(path="arrow_left.png")
117
+ page.screenshot(path: "arrow_left.png")
124
118
  page.keyboard.press("Shift+O")
125
- page.screenshot(path="o.png")
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
- ```python sync title=example_d9ced919f139961fd2b795c71375ca96f788a19c1f8e1479c5ec905fb5c02d43.py
134
+ ```ruby
143
135
  page.keyboard.type("Hello") # types instantly
144
- page.keyboard.type("World", delay=100) # types slower, like a user
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(selector, value, noWaitAfter: nil, timeout: nil)
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. See [waiting for event](https://playwright.dev/python/docs/events) for more details
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