playwright-ruby-client 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/docs/api_coverage.md +102 -49
  3. data/lib/playwright.rb +1 -0
  4. data/lib/playwright/channel.rb +10 -10
  5. data/lib/playwright/channel_owners/binding_call.rb +3 -0
  6. data/lib/playwright/channel_owners/browser_context.rb +149 -3
  7. data/lib/playwright/channel_owners/dialog.rb +28 -0
  8. data/lib/playwright/channel_owners/page.rb +47 -10
  9. data/lib/playwright/channel_owners/playwright.rb +4 -0
  10. data/lib/playwright/channel_owners/request.rb +26 -2
  11. data/lib/playwright/channel_owners/response.rb +60 -0
  12. data/lib/playwright/channel_owners/route.rb +78 -0
  13. data/lib/playwright/channel_owners/selectors.rb +19 -1
  14. data/lib/playwright/route_handler_entry.rb +36 -0
  15. data/lib/playwright/utils.rb +1 -0
  16. data/lib/playwright/version.rb +1 -1
  17. data/lib/playwright_api/android.rb +80 -8
  18. data/lib/playwright_api/android_device.rb +145 -28
  19. data/lib/playwright_api/android_input.rb +17 -13
  20. data/lib/playwright_api/android_socket.rb +16 -0
  21. data/lib/playwright_api/android_web_view.rb +21 -0
  22. data/lib/playwright_api/binding_call.rb +11 -6
  23. data/lib/playwright_api/browser.rb +6 -6
  24. data/lib/playwright_api/browser_context.rb +33 -28
  25. data/lib/playwright_api/browser_type.rb +14 -14
  26. data/lib/playwright_api/chromium_browser_context.rb +6 -6
  27. data/lib/playwright_api/console_message.rb +6 -6
  28. data/lib/playwright_api/dialog.rb +32 -5
  29. data/lib/playwright_api/download.rb +6 -6
  30. data/lib/playwright_api/element_handle.rb +6 -6
  31. data/lib/playwright_api/file_chooser.rb +1 -1
  32. data/lib/playwright_api/frame.rb +13 -11
  33. data/lib/playwright_api/js_handle.rb +6 -6
  34. data/lib/playwright_api/page.rb +48 -46
  35. data/lib/playwright_api/playwright.rb +7 -7
  36. data/lib/playwright_api/request.rb +8 -8
  37. data/lib/playwright_api/response.rb +27 -17
  38. data/lib/playwright_api/route.rb +27 -5
  39. data/lib/playwright_api/selectors.rb +7 -7
  40. metadata +7 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 140f77362280a6874d89ed73fde1e80fa47e2b83f075b6207835f02ab62cb97f
4
- data.tar.gz: e715b39c620668eeea1a0dbb022865f759d02f59d2f3d23948c7c20536ca0136
3
+ metadata.gz: cbaaa0e61bbc515a26d0f0e6af6ca8c36bbf3db5cc6913a6895f175154ba893b
4
+ data.tar.gz: cdc467f161030497d4efb94689bef4901c0e15bd24e9cc8be189106f5dfe4493
5
5
  SHA512:
6
- metadata.gz: 0315d44031788794eca7f506ba9a20a81dbb6bf77c15efda873a1efc3e25074d46e1629ae07551f2dd8368f8a7609568cd719fd1470fdd3bf2717373168655a2
7
- data.tar.gz: a3b6a02b60059ac3ef14c0ca1222e3b88a3aaee588b8510c49ef748fab5f27c354417b1e38cc6adfe98e6b1f38805ed1c0cead8cfb465f4968e449c98dd5a9a5
6
+ metadata.gz: 585d3989547fd8e38e1e9503bf8aee20e732b1234bd62783c51b2e77a6061325c9a0c44de0de2b65557726dbebd6dc944ab44f72ffb8cbba69449ff3c0886a59
7
+ data.tar.gz: e50bd506a34d5fe1d84d6f75d0fbe8bc1128c0f93c3529dc94ba6af7dabf59e564625e6ca0b5a16cf7ad8066ffe91aeeda369599a30c0bb9e5629f54dfe54fd1
data/docs/api_coverage.md CHANGED
@@ -19,24 +19,24 @@
19
19
 
20
20
  ## Response
21
21
 
22
- * ~~body~~
23
- * ~~finished~~
24
- * ~~frame~~
25
- * ~~headers~~
26
- * ~~json~~
27
- * ~~ok~~
28
- * ~~request~~
29
- * ~~status~~
30
- * ~~status_text~~
31
- * ~~text~~
32
- * ~~url~~
22
+ * body
23
+ * finished
24
+ * frame
25
+ * headers
26
+ * json
27
+ * ok
28
+ * request
29
+ * status
30
+ * status_text
31
+ * text
32
+ * url
33
33
 
34
- ## ~~Route~~
34
+ ## Route
35
35
 
36
- * ~~abort~~
37
- * ~~continue_~~
38
- * ~~fulfill~~
39
- * ~~request~~
36
+ * abort
37
+ * continue
38
+ * fulfill
39
+ * request
40
40
 
41
41
  ## ~~WebSocket~~
42
42
 
@@ -182,7 +182,7 @@
182
182
 
183
183
  ## Selectors
184
184
 
185
- * ~~register~~
185
+ * register
186
186
 
187
187
  ## ConsoleMessage
188
188
 
@@ -191,13 +191,13 @@
191
191
  * text
192
192
  * type
193
193
 
194
- ## ~~Dialog~~
194
+ ## Dialog
195
195
 
196
- * ~~accept~~
197
- * ~~default_value~~
198
- * ~~dismiss~~
199
- * ~~message~~
200
- * ~~type~~
196
+ * accept
197
+ * default_value
198
+ * dismiss
199
+ * message
200
+ * type
201
201
 
202
202
  ## Download
203
203
 
@@ -258,7 +258,7 @@
258
258
  * query_selector
259
259
  * query_selector_all
260
260
  * reload
261
- * ~~route~~
261
+ * route
262
262
  * screenshot
263
263
  * select_option
264
264
  * set_content
@@ -272,24 +272,24 @@
272
272
  * title
273
273
  * type
274
274
  * uncheck
275
- * ~~unroute~~
275
+ * unroute
276
276
  * url
277
277
  * ~~video~~
278
278
  * viewport_size
279
+ * expect_console_message
280
+ * expect_download
279
281
  * expect_event
282
+ * expect_file_chooser
280
283
  * wait_for_function
281
284
  * wait_for_load_state
282
285
  * expect_navigation
286
+ * expect_popup
283
287
  * expect_request
284
288
  * expect_response
285
289
  * wait_for_selector
286
290
  * ~~wait_for_timeout~~
287
- * ~~workers~~
288
- * expect_download
289
- * expect_popup
290
291
  * ~~expect_worker~~
291
- * expect_console_message
292
- * expect_file_chooser
292
+ * ~~workers~~
293
293
  * ~~wait_for_event~~
294
294
  * accessibility
295
295
  * keyboard
@@ -298,28 +298,28 @@
298
298
 
299
299
  ## BrowserContext
300
300
 
301
- * ~~add_cookies~~
302
- * ~~add_init_script~~
303
- * ~~browser~~
304
- * ~~clear_cookies~~
305
- * ~~clear_permissions~~
301
+ * add_cookies
302
+ * add_init_script
303
+ * browser
304
+ * clear_cookies
305
+ * clear_permissions
306
306
  * close
307
- * ~~cookies~~
308
- * ~~expose_binding~~
309
- * ~~expose_function~~
310
- * ~~grant_permissions~~
307
+ * cookies
308
+ * expose_binding
309
+ * expose_function
310
+ * grant_permissions
311
311
  * new_page
312
312
  * pages
313
- * ~~route~~
314
- * ~~set_default_navigation_timeout~~
315
- * ~~set_default_timeout~~
316
- * ~~set_extra_http_headers~~
317
- * ~~set_geolocation~~
318
- * ~~set_offline~~
313
+ * route
314
+ * set_default_navigation_timeout
315
+ * set_default_timeout
316
+ * set_extra_http_headers
317
+ * set_geolocation
318
+ * set_offline
319
319
  * ~~storage_state~~
320
- * ~~unroute~~
321
- * ~~expect_event~~
322
- * ~~expect_page~~
320
+ * unroute
321
+ * expect_event
322
+ * expect_page
323
323
  * ~~wait_for_event~~
324
324
 
325
325
  ## ~~CDPSession~~
@@ -355,5 +355,58 @@
355
355
  * chromium
356
356
  * devices
357
357
  * firefox
358
- * ~~selectors~~
358
+ * selectors
359
359
  * webkit
360
+
361
+ ## Android
362
+
363
+ * devices
364
+ * ~~set_default_timeout~~
365
+
366
+ ## AndroidDevice
367
+
368
+ * close
369
+ * ~~drag~~
370
+ * ~~fill~~
371
+ * ~~fling~~
372
+ * info
373
+ * ~~install_apk~~
374
+ * launch_browser
375
+ * ~~long_tap~~
376
+ * model
377
+ * ~~open~~
378
+ * ~~pinch_close~~
379
+ * ~~pinch_open~~
380
+ * ~~press~~
381
+ * ~~push~~
382
+ * screenshot
383
+ * ~~scroll~~
384
+ * serial
385
+ * ~~set_default_timeout~~
386
+ * shell
387
+ * ~~swipe~~
388
+ * ~~tap_point~~
389
+ * ~~wait~~
390
+ * ~~wait_for_event~~
391
+ * ~~web_view~~
392
+ * ~~web_views~~
393
+ * input
394
+
395
+ ## AndroidInput
396
+
397
+ * drag
398
+ * press
399
+ * ~~swipe~~
400
+ * tap_point
401
+ * type
402
+
403
+ ## ~~AndroidSocket~~
404
+
405
+ * ~~close~~
406
+ * ~~write~~
407
+
408
+ ## ~~AndroidWebView~~
409
+
410
+ * ~~page~~
411
+ * ~~pid~~
412
+ * ~~pkg~~
data/lib/playwright.rb CHANGED
@@ -20,6 +20,7 @@ require 'playwright/channel_owner'
20
20
  require 'playwright/http_headers'
21
21
  require 'playwright/input_files'
22
22
  require 'playwright/connection'
23
+ require 'playwright/route_handler_entry'
23
24
  require 'playwright/select_option_values'
24
25
  require 'playwright/timeout_settings'
25
26
  require 'playwright/transport'
@@ -16,20 +16,20 @@ module Playwright
16
16
  # @param method [String]
17
17
  # @param params [Hash]
18
18
  def send_message_to_server(method, params = {})
19
- result = @connection.send_message_to_server(@guid, method, params)
20
- if result.is_a?(Hash)
21
- _type, channel_owner = result.first
22
- channel_owner
23
- else
24
- nil
25
- end
19
+ async_send_message_to_server(method, params).value!
26
20
  end
27
21
 
28
22
  # @param method [String]
29
23
  # @param params [Hash]
30
- def send_no_reply(method, params)
31
- @connection.async_send_message_to_server(@guid, method, params)
32
- nil
24
+ def async_send_message_to_server(method, params = {})
25
+ @connection.async_send_message_to_server(@guid, method, params).then do |result|
26
+ if result.is_a?(Hash)
27
+ _type, channel_owner = result.first
28
+ channel_owner
29
+ else
30
+ nil
31
+ end
32
+ end
33
33
  end
34
34
  end
35
35
  end
@@ -1,4 +1,7 @@
1
1
  module Playwright
2
2
  define_channel_owner :BindingCall do
3
+ def name
4
+ @initializer['name']
5
+ end
3
6
  end
4
7
  end
@@ -2,11 +2,16 @@ module Playwright
2
2
  # @ref https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_browser_context.py
3
3
  define_channel_owner :BrowserContext do
4
4
  include Utils::Errors::SafeCloseError
5
- attr_writer :browser, :owner_page, :options
5
+ attr_accessor :browser
6
+ attr_writer :owner_page, :options
6
7
 
7
8
  private def after_initialize
8
9
  @pages = Set.new
10
+ @routes = Set.new
11
+ @bindings = {}
12
+ @timeout_settings = TimeoutSettings.new
9
13
 
14
+ @channel.on('bindingCall', ->(params) { on_binding(ChannelOwners::BindingCall.from(params['binding'])) })
10
15
  @channel.once('close', ->(_) { on_close })
11
16
  @channel.on('page', ->(params) { on_page(ChannelOwners::Page.from(params['page']) )})
12
17
  @channel.on('route', ->(params) {
@@ -21,8 +26,32 @@ module Playwright
21
26
  end
22
27
 
23
28
  private def on_route(route, request)
24
- # @routes.each ...
25
- route.continue_
29
+ # It is not desired to use PlaywrightApi.wrap directly.
30
+ # However it is a little difficult to define wrapper for `handler` parameter in generate_api.
31
+ # Just a workaround...
32
+ wrapped_route = PlaywrightApi.wrap(route)
33
+ wrapped_request = PlaywrightApi.wrap(request)
34
+
35
+ if @routes.none? { |handler_entry| handler_entry.handle(wrapped_route, wrapped_request) }
36
+ route.continue
37
+ end
38
+ end
39
+
40
+ private def on_binding(binding_call)
41
+ func = @binding[binding_call.name]
42
+ if func
43
+ binding_call.call(func)
44
+ end
45
+ end
46
+
47
+ def set_default_navigation_timeout(timeout)
48
+ @timeout_settings.default_navigation_timeout = timeout
49
+ @channel.send_message_to_server('setDefaultNavigationTimeoutNoReply', timeout: timeout)
50
+ end
51
+
52
+ def set_default_timeout(timeout)
53
+ @timeout_settings.default_timeout = timeout
54
+ @channel.send_message_to_server('setDefaultTimeoutNoReply', timeout: timeout)
26
55
  end
27
56
 
28
57
  def pages
@@ -36,6 +65,111 @@ module Playwright
36
65
  ChannelOwners::Page.from(resp)
37
66
  end
38
67
 
68
+ def cookies(urls: nil)
69
+ target_urls =
70
+ if urls.nil?
71
+ []
72
+ elsif urls.is_a?(Enumerable)
73
+ urls
74
+ else
75
+ [urls]
76
+ end
77
+ @channel.send_message_to_server('cookies', urls: urls)
78
+ end
79
+
80
+ def add_cookies(cookies)
81
+ @channel.send_message_to_server('addCookies', cookies: cookies)
82
+ end
83
+
84
+ def clear_cookies
85
+ @channel.send_message_to_server('clearCookies')
86
+ end
87
+
88
+ def grant_permissions(permissions, origin: nil)
89
+ params = {
90
+ permissions: permissions,
91
+ origin: origin,
92
+ }.compact
93
+ @channel.send_message_to_server('grantPermissions', params)
94
+ end
95
+
96
+ def clear_permissions
97
+ @channel.send_message_to_server('clearPermissions')
98
+ end
99
+
100
+ def set_geolocation(geolocation)
101
+ @channel.send_message_to_server('setGeolocation', geolocation: geolocation)
102
+ end
103
+
104
+ def set_extra_http_headers(headers)
105
+ @channel.send_message_to_server('setExtraHTTPHeaders',
106
+ headers: HttpHeaders.new(headers).as_serialized)
107
+ end
108
+
109
+ def set_offline(offline)
110
+ @channel.send_message_to_server('setOffline', offline: offline)
111
+ end
112
+
113
+ def add_init_script(path: nil, script: nil)
114
+ source =
115
+ if path
116
+ File.read(path)
117
+ elsif script
118
+ script
119
+ else
120
+ raise ArgumentError.new('Either path or script parameter must be specified')
121
+ end
122
+
123
+ @channel.send_message_to_server('addInitScript', source: script)
124
+ nil
125
+ end
126
+
127
+ def expose_binding(name, callback, handle: nil)
128
+ if @pages.any? { |page| page.send(:has_bindings?, name) }
129
+ raise ArgumentError.new("Function \"#{name}\" has been already registered in one of the pages")
130
+ end
131
+ if @bindings.key?(name)
132
+ raise ArgumentError.new("Function \"#{name}\" has been already registered")
133
+ end
134
+ params = {
135
+ name: name,
136
+ needsHandle: handle,
137
+ }.compact
138
+ @bindings[name] = callback
139
+ @channel.send_message_to_server('exposeBinding', params)
140
+ end
141
+
142
+ def expose_function(name, callback)
143
+ expose_binding(name, ->(_source, *args) { callback.call(*args) }, )
144
+ end
145
+
146
+ def route(url, handler)
147
+ entry = RouteHandlerEntry.new(url, handler)
148
+ @routes << entry
149
+ if @routes.count >= 1
150
+ @channel.send_message_to_server('setNetworkInterceptionEnabled', enabled: true)
151
+ end
152
+ end
153
+
154
+ def unroute(url, handler: nil)
155
+ @routes.reject! do |handler_entry|
156
+ handler_entry.same_value?(url: url, handler: handler)
157
+ end
158
+ if @routes.count == 0
159
+ @channel.send_message_to_server('setNetworkInterceptionEnabled', enabled: false)
160
+ end
161
+ end
162
+
163
+ def expect_event(event, predicate: nil, timeout: nil, &block)
164
+ wait_helper = WaitHelper.new
165
+ wait_helper.reject_on_timeout(timeout || @timeout_settings.timeout, "Timeout while waiting for event \"#{event}\"")
166
+ wait_helper.wait_for_event(self, event, predicate: predicate)
167
+
168
+ block&.call
169
+
170
+ wait_helper.promise.value!
171
+ end
172
+
39
173
  private def on_close
40
174
  @closed_or_closing = true
41
175
  @browser&.send(:remove_context, self)
@@ -51,6 +185,18 @@ module Playwright
51
185
  raise unless safe_close_error?(err)
52
186
  end
53
187
 
188
+ def pause
189
+ @channel.send_message_to_server('pause')
190
+ end
191
+
192
+ def expect_page(predicate: nil, timeout: nil)
193
+ params = {
194
+ predicate: predicate,
195
+ timeout: timeout,
196
+ }.compact
197
+ expect_event(Events::BrowserContext::Page, params)
198
+ end
199
+
54
200
  # called from Page#on_close with send(:remove_page, page), so keep private
55
201
  private def remove_page(page)
56
202
  @pages.delete(page)