playwright-ruby-client 0.6.4 → 0.8.0

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -0
  3. data/documentation/docs/api/browser.md +10 -0
  4. data/documentation/docs/api/browser_context.md +10 -0
  5. data/documentation/docs/api/browser_type.md +53 -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/frame.md +15 -1
  9. data/documentation/docs/api/page.md +33 -1
  10. data/documentation/docs/api/response.md +16 -0
  11. data/documentation/docs/api/route.md +20 -21
  12. data/documentation/docs/api/web_socket.md +38 -1
  13. data/documentation/docs/article/guides/launch_browser.md +2 -0
  14. data/documentation/docs/article/guides/rails_integration.md +2 -2
  15. data/documentation/docs/article/guides/semi_automation.md +67 -0
  16. data/documentation/docs/include/api_coverage.md +19 -13
  17. data/lib/playwright.rb +36 -3
  18. data/lib/playwright/channel_owners/browser.rb +5 -0
  19. data/lib/playwright/channel_owners/browser_context.rb +5 -0
  20. data/lib/playwright/channel_owners/browser_type.rb +18 -0
  21. data/lib/playwright/channel_owners/cdp_session.rb +19 -0
  22. data/lib/playwright/channel_owners/element_handle.rb +11 -4
  23. data/lib/playwright/channel_owners/frame.rb +14 -2
  24. data/lib/playwright/channel_owners/page.rb +21 -2
  25. data/lib/playwright/channel_owners/response.rb +9 -1
  26. data/lib/playwright/channel_owners/web_socket.rb +87 -0
  27. data/lib/playwright/connection.rb +2 -4
  28. data/lib/playwright/transport.rb +0 -1
  29. data/lib/playwright/version.rb +2 -2
  30. data/lib/playwright/web_socket_client.rb +164 -0
  31. data/lib/playwright/web_socket_transport.rb +104 -0
  32. data/lib/playwright_api/android.rb +6 -6
  33. data/lib/playwright_api/android_device.rb +8 -8
  34. data/lib/playwright_api/browser.rb +7 -7
  35. data/lib/playwright_api/browser_context.rb +7 -7
  36. data/lib/playwright_api/browser_type.rb +9 -8
  37. data/lib/playwright_api/cdp_session.rb +30 -8
  38. data/lib/playwright_api/console_message.rb +6 -6
  39. data/lib/playwright_api/dialog.rb +6 -6
  40. data/lib/playwright_api/element_handle.rb +17 -11
  41. data/lib/playwright_api/frame.rb +20 -9
  42. data/lib/playwright_api/js_handle.rb +6 -6
  43. data/lib/playwright_api/page.rb +28 -17
  44. data/lib/playwright_api/playwright.rb +6 -6
  45. data/lib/playwright_api/request.rb +6 -6
  46. data/lib/playwright_api/response.rb +15 -10
  47. data/lib/playwright_api/route.rb +11 -6
  48. data/lib/playwright_api/selectors.rb +6 -6
  49. data/lib/playwright_api/web_socket.rb +28 -6
  50. data/lib/playwright_api/worker.rb +6 -6
  51. data/playwright.gemspec +2 -1
  52. metadata +37 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 330a0cd5755fdbe5136276e881415f5966f159b2abc62f66a26ab5068b326efe
4
- data.tar.gz: 6108f18234e97d483c17958bee26628f4068be0438d1ce5553748ff1f7489acd
3
+ metadata.gz: 05e5dff936dc4eda78a295d4f6935b5b92d6e82046de9a36c9f4b67aba24e89f
4
+ data.tar.gz: 85f30ee725facdc21d77645007cbeca689cd322dacb559146234fab1de0aab79
5
5
  SHA512:
6
- metadata.gz: c82ea88ac3d7b78e1e746f95ba09f0c6903cd20f9f0410f6bba68b9fdd00cf47a5e1c3103d8884c917542a7e41959ded61ba2b2ae9f58cfa2e2bfe4e1e2edf59
7
- data.tar.gz: 61867b7e5b78b8271db8d937c8e6129e84bba1eb5181179dc464c50930e88b641a25f6a3c1d3bb1e6183f0cb9546b494622a918b2942405ea9b9a3b9356f8321
6
+ metadata.gz: 3c0fefff97e051805fb7d48aa134456d6a45ed5ab6b6818ea506251d93a1991c47bc6fc30aa1e2eae9369b1188564c08e23d083b6f8f8a896efe52d008cf6889
7
+ data.tar.gz: ebaf0d10fea440818cc182496b72c5ac16d192c76825db8aa271b89f891059b496ffdaaecdcfbaf7482ceb37ea868ac13feae678eee81b76c4e856f419627209
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,6 +61,16 @@ 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
  ```
@@ -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
  ```
@@ -96,6 +96,59 @@ differences between Chromium and Chrome.
96
96
  [This article](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md)
97
97
  describes some differences for Linux users.
98
98
 
99
+ ## launch_persistent_context
100
+
101
+ ```
102
+ def launch_persistent_context(
103
+ userDataDir,
104
+ acceptDownloads: nil,
105
+ args: nil,
106
+ bypassCSP: nil,
107
+ channel: nil,
108
+ chromiumSandbox: nil,
109
+ colorScheme: nil,
110
+ deviceScaleFactor: nil,
111
+ devtools: nil,
112
+ downloadsPath: nil,
113
+ env: nil,
114
+ executablePath: nil,
115
+ extraHTTPHeaders: nil,
116
+ geolocation: nil,
117
+ handleSIGHUP: nil,
118
+ handleSIGINT: nil,
119
+ handleSIGTERM: nil,
120
+ hasTouch: nil,
121
+ headless: nil,
122
+ httpCredentials: nil,
123
+ ignoreDefaultArgs: nil,
124
+ ignoreHTTPSErrors: nil,
125
+ isMobile: nil,
126
+ javaScriptEnabled: nil,
127
+ locale: nil,
128
+ noViewport: nil,
129
+ offline: nil,
130
+ permissions: nil,
131
+ proxy: nil,
132
+ record_har_omit_content: nil,
133
+ record_har_path: nil,
134
+ record_video_dir: nil,
135
+ record_video_size: nil,
136
+ reducedMotion: nil,
137
+ screen: nil,
138
+ slowMo: nil,
139
+ timeout: nil,
140
+ timezoneId: nil,
141
+ tracesDir: nil,
142
+ userAgent: nil,
143
+ viewport: nil,
144
+ &block)
145
+ ```
146
+
147
+ Returns the persistent browser context instance.
148
+
149
+ Launches browser that uses persistent storage located at `userDataDir` and returns the only context. Closing this
150
+ context will automatically close the browser.
151
+
99
152
  ## name
100
153
 
101
154
  ```
@@ -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
@@ -326,7 +326,12 @@ result_handle.dispose
326
326
  ## fill
327
327
 
328
328
  ```
329
- def fill(selector, value, noWaitAfter: nil, timeout: nil)
329
+ def fill(
330
+ selector,
331
+ value,
332
+ force: nil,
333
+ noWaitAfter: nil,
334
+ timeout: nil)
330
335
  ```
331
336
 
332
337
  This method waits for an element matching `selector`, waits for [actionability](https://playwright.dev/python/docs/actionability) checks, focuses the
@@ -443,6 +448,14 @@ def inner_text(selector, timeout: nil)
443
448
 
444
449
  Returns `element.innerText`.
445
450
 
451
+ ## input_value
452
+
453
+ ```
454
+ def input_value(selector, timeout: nil)
455
+ ```
456
+
457
+ Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
458
+
446
459
  ## checked?
447
460
 
448
461
  ```
@@ -588,6 +601,7 @@ def select_option(
588
601
  index: nil,
589
602
  value: nil,
590
603
  label: nil,
604
+ force: nil,
591
605
  noWaitAfter: nil,
592
606
  timeout: nil)
593
607
  ```
@@ -499,7 +499,12 @@ page.click("button")
499
499
  ## fill
500
500
 
501
501
  ```
502
- def fill(selector, value, noWaitAfter: nil, timeout: nil)
502
+ def fill(
503
+ selector,
504
+ value,
505
+ force: nil,
506
+ noWaitAfter: nil,
507
+ timeout: nil)
503
508
  ```
504
509
 
505
510
  This method waits for an element matching `selector`, waits for [actionability](https://playwright.dev/python/docs/actionability) checks, focuses the
@@ -650,6 +655,14 @@ def inner_text(selector, timeout: nil)
650
655
 
651
656
  Returns `element.innerText`.
652
657
 
658
+ ## input_value
659
+
660
+ ```
661
+ def input_value(selector, timeout: nil)
662
+ ```
663
+
664
+ Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
665
+
653
666
  ## checked?
654
667
 
655
668
  ```
@@ -934,6 +947,7 @@ def select_option(
934
947
  index: nil,
935
948
  value: nil,
936
949
  label: nil,
950
+ force: nil,
937
951
  noWaitAfter: nil,
938
952
  timeout: nil)
939
953
  ```
@@ -1328,6 +1342,16 @@ puts request.headers
1328
1342
 
1329
1343
 
1330
1344
 
1345
+ ## expect_request_finished
1346
+
1347
+ ```
1348
+ def expect_request_finished(predicate: nil, timeout: nil, &block)
1349
+ ```
1350
+
1351
+ Performs action and waits for a [Request](./request) to finish loading. If predicate is provided, it passes [Request](./request) value into
1352
+ the `predicate` function and waits for `predicate(request)` to return a truthy value. Will throw an error if the page is
1353
+ closed before the [`event: Page.requestFinished`] event is fired.
1354
+
1331
1355
  ## expect_response
1332
1356
 
1333
1357
  ```
@@ -1393,6 +1417,14 @@ page.wait_for_url("**/target.html")
1393
1417
 
1394
1418
  Shortcut for main frame's [Frame#wait_for_url](./frame#wait_for_url).
1395
1419
 
1420
+ ## expect_websocket
1421
+
1422
+ ```
1423
+ def expect_websocket(predicate: nil, timeout: nil, &block)
1424
+ ```
1425
+
1426
+ 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.
1427
+
1396
1428
  ## accessibility
1397
1429
 
1398
1430
  ## keyboard
@@ -64,6 +64,22 @@ def request
64
64
 
65
65
  Returns the matching [Request](./request) object.
66
66
 
67
+ ## security_details
68
+
69
+ ```
70
+ def security_details
71
+ ```
72
+
73
+ Returns SSL and other security information.
74
+
75
+ ## server_addr
76
+
77
+ ```
78
+ def server_addr
79
+ ```
80
+
81
+ Returns the IP address and port of the server.
82
+
67
83
  ## status
68
84
 
69
85
  ```
@@ -23,18 +23,16 @@ def continue(headers: nil, method: nil, postData: nil, url: nil)
23
23
 
24
24
  Continues route's request with optional overrides.
25
25
 
26
- ```python sync title=example_1960aabd58c9553683368e29429d39c1209d35e6e3625bbef1280a1fa022a9ee.py
27
- def handle(route, request):
28
- # override headers
29
- headers = {
30
- **request.headers,
31
- "foo": "bar" # set "foo" header
32
- "origin": None # remove "origin" header
33
- }
34
- route.continue_(headers=headers)
35
- }
36
- page.route("**/*", handle)
37
-
26
+ ```ruby
27
+ def handle(route, request)
28
+ # override headers
29
+ headers = request.headers
30
+ headers['foo'] = 'bar' # set "foo" header
31
+ headers['user-agent'] = 'Unknown Browser' # modify user-agent
32
+
33
+ route.continue(headers: headers)
34
+ end
35
+ page.route("**/*", method(:handle))
38
36
  ```
39
37
 
40
38
 
@@ -54,19 +52,20 @@ Fulfills route's request with given response.
54
52
 
55
53
  An example of fulfilling all requests with 404 responses:
56
54
 
57
- ```python sync title=example_6d2dfd4bb5c8360f8d80bb91c563b0bd9b99aa24595063cf85e5a6e1b105f89c.py
58
- page.route("**/*", lambda route: route.fulfill(
59
- status=404,
60
- content_type="text/plain",
61
- body="not found!"))
62
-
55
+ ```ruby
56
+ page.route("**/*", ->(route, request) {
57
+ route.fulfill(
58
+ status: 404,
59
+ contentType: 'text/plain',
60
+ body: 'not found!!',
61
+ )
62
+ })
63
63
  ```
64
64
 
65
65
  An example of serving static file:
66
66
 
67
- ```python sync title=example_c77fd0986d0b74c905cd9417756c76775e612cc86410f9a5aabc5b46d233d150.py
68
- page.route("**/xhr_endpoint", lambda route: route.fulfill(path="mock_data.json"))
69
-
67
+ ```ruby
68
+ page.route("**/xhr_endpoint", ->(route, _) { route.fulfill(path: "mock_data.json") })
70
69
  ```
71
70
 
72
71
 
@@ -4,4 +4,41 @@ sidebar_position: 10
4
4
 
5
5
  # WebSocket
6
6
 
7
- Not Implemented
7
+ The [WebSocket](./web_socket) class represents websocket connections in the page.
8
+
9
+ ## closed?
10
+
11
+ ```
12
+ def closed?
13
+ ```
14
+
15
+ Indicates that the web socket has been closed.
16
+
17
+ ## url
18
+
19
+ ```
20
+ def url
21
+ ```
22
+
23
+ Contains the URL of the WebSocket.
24
+
25
+ ## expect_event
26
+
27
+ ```
28
+ def expect_event(event, predicate: nil, timeout: nil, &block)
29
+ ```
30
+
31
+ Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy
32
+ value. Will throw an error if the webSocket is closed before the event is fired. Returns the event data value.
33
+
34
+ ## wait_for_event
35
+
36
+ ```
37
+ def wait_for_event(event, predicate: nil, timeout: nil, &block)
38
+ ```
39
+
40
+ > NOTE: In most cases, you should use [WebSocket#wait_for_event](./web_socket#wait_for_event).
41
+
42
+ Waits for given `event` to fire. If predicate is provided, it passes event's value into the `predicate` function and
43
+ waits for `predicate(event)` to return a truthy value. Will throw an error if the socket is closed before the `event` is
44
+ fired.