playwright-ruby-client 0.6.4 → 0.8.0

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