playwright-ruby-client 0.6.6 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
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