playwright-ruby-client 0.7.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) 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/download.md +97 -0
  8. data/documentation/docs/api/element_handle.md +38 -4
  9. data/documentation/docs/api/experimental/android_device.md +1 -0
  10. data/documentation/docs/api/frame.md +78 -17
  11. data/documentation/docs/api/keyboard.md +11 -20
  12. data/documentation/docs/api/locator.md +650 -0
  13. data/documentation/docs/api/page.md +107 -19
  14. data/documentation/docs/api/response.md +16 -0
  15. data/documentation/docs/article/guides/inspector.md +31 -0
  16. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +91 -0
  17. data/documentation/docs/article/guides/rails_integration.md +1 -1
  18. data/documentation/docs/article/guides/semi_automation.md +5 -1
  19. data/documentation/docs/include/api_coverage.md +70 -7
  20. data/lib/playwright.rb +36 -4
  21. data/lib/playwright/channel_owners/artifact.rb +4 -0
  22. data/lib/playwright/channel_owners/browser.rb +5 -0
  23. data/lib/playwright/channel_owners/browser_context.rb +37 -3
  24. data/lib/playwright/channel_owners/cdp_session.rb +19 -0
  25. data/lib/playwright/channel_owners/element_handle.rb +11 -4
  26. data/lib/playwright/channel_owners/frame.rb +103 -34
  27. data/lib/playwright/channel_owners/page.rb +140 -53
  28. data/lib/playwright/channel_owners/response.rb +9 -1
  29. data/lib/playwright/connection.rb +2 -4
  30. data/lib/playwright/{download.rb → download_impl.rb} +5 -1
  31. data/lib/playwright/javascript/expression.rb +5 -4
  32. data/lib/playwright/locator_impl.rb +314 -0
  33. data/lib/playwright/route_handler_entry.rb +3 -2
  34. data/lib/playwright/timeout_settings.rb +4 -4
  35. data/lib/playwright/transport.rb +0 -1
  36. data/lib/playwright/url_matcher.rb +12 -2
  37. data/lib/playwright/version.rb +2 -2
  38. data/lib/playwright/web_socket_client.rb +164 -0
  39. data/lib/playwright/web_socket_transport.rb +104 -0
  40. data/lib/playwright_api/android.rb +6 -6
  41. data/lib/playwright_api/android_device.rb +10 -9
  42. data/lib/playwright_api/browser.rb +17 -11
  43. data/lib/playwright_api/browser_context.rb +14 -9
  44. data/lib/playwright_api/browser_type.rb +8 -7
  45. data/lib/playwright_api/cdp_session.rb +30 -8
  46. data/lib/playwright_api/console_message.rb +6 -6
  47. data/lib/playwright_api/dialog.rb +6 -6
  48. data/lib/playwright_api/download.rb +70 -0
  49. data/lib/playwright_api/element_handle.rb +44 -24
  50. data/lib/playwright_api/frame.rb +100 -49
  51. data/lib/playwright_api/js_handle.rb +6 -6
  52. data/lib/playwright_api/locator.rb +509 -0
  53. data/lib/playwright_api/page.rb +110 -57
  54. data/lib/playwright_api/playwright.rb +6 -6
  55. data/lib/playwright_api/request.rb +6 -6
  56. data/lib/playwright_api/response.rb +15 -10
  57. data/lib/playwright_api/route.rb +6 -6
  58. data/lib/playwright_api/selectors.rb +6 -6
  59. data/lib/playwright_api/web_socket.rb +6 -6
  60. data/lib/playwright_api/worker.rb +6 -6
  61. metadata +15 -5
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Playwright
6
+ # ref: https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_transport.py
7
+ class WebSocketTransport
8
+ # @param ws_endpoint [String] EndpointURL of WebSocket
9
+ def initialize(ws_endpoint:)
10
+ @ws_endpoint = ws_endpoint
11
+ @debug = ENV['DEBUG'].to_s == 'true' || ENV['DEBUG'].to_s == '1'
12
+ end
13
+
14
+ def on_message_received(&block)
15
+ @on_message = block
16
+ end
17
+
18
+ def on_driver_crashed(&block)
19
+ @on_driver_crashed = block
20
+ end
21
+
22
+ class AlreadyDisconnectedError < StandardError ; end
23
+
24
+ # @param message [Hash]
25
+ def send_message(message)
26
+ debug_send_message(message) if @debug
27
+ msg = JSON.dump(message)
28
+
29
+ @ws.send_text(msg)
30
+ rescue Errno::EPIPE, IOError
31
+ raise AlreadyDisconnectedError.new('send_message failed')
32
+ end
33
+
34
+ # Terminate playwright-cli driver.
35
+ def stop
36
+ return unless @ws
37
+
38
+ future = Concurrent::Promises.resolvable_future
39
+
40
+ @ws.on_close do
41
+ future.fulfill(nil)
42
+ end
43
+
44
+ begin
45
+ @ws.close
46
+ rescue EOFError => err
47
+ # ignore EOLError. The connection is already closed.
48
+ future.fulfill(err)
49
+ end
50
+
51
+ # Wait for closed actually.
52
+ future.value!
53
+ end
54
+
55
+ # Start `playwright-cli run-driver`
56
+ #
57
+ # @note This method blocks until playwright-cli exited. Consider using Thread or Future.
58
+ def async_run
59
+ ws = WebSocketClient.new(
60
+ url: @ws_endpoint,
61
+ max_payload_size: 256 * 1024 * 1024, # 256MB
62
+ )
63
+ promise = Concurrent::Promises.resolvable_future
64
+ ws.on_open do
65
+ promise.fulfill(ws)
66
+ end
67
+ ws.on_error do |error_message|
68
+ promise.reject(WebSocketClient::TransportError.new(error_message))
69
+ end
70
+
71
+ # Some messages can be sent just after start, before setting @ws.on_message
72
+ # So set this handler before ws.start.
73
+ ws.on_message do |data|
74
+ handle_on_message(data)
75
+ end
76
+
77
+ ws.start
78
+ @ws = promise.value!
79
+ @ws.on_error do |error|
80
+ puts "[WebSocketTransport] error: #{error}"
81
+ @on_driver_crashed&.call
82
+ end
83
+ rescue Errno::ECONNREFUSED => err
84
+ raise WebSocketClient::TransportError.new(err)
85
+ end
86
+
87
+ private
88
+
89
+ def handle_on_message(data)
90
+ obj = JSON.parse(data)
91
+
92
+ debug_recv_message(obj) if @debug
93
+ @on_message&.call(obj)
94
+ end
95
+
96
+ def debug_send_message(message)
97
+ puts "\x1b[33mSEND>\x1b[0m#{message}"
98
+ end
99
+
100
+ def debug_recv_message(message)
101
+ puts "\x1b[33mRECV>\x1b[0m#{message}"
102
+ end
103
+ end
104
+ end
@@ -25,20 +25,20 @@ module Playwright
25
25
 
26
26
  # -- inherited from EventEmitter --
27
27
  # @nodoc
28
- def on(event, callback)
29
- event_emitter_proxy.on(event, callback)
28
+ def once(event, callback)
29
+ event_emitter_proxy.once(event, callback)
30
30
  end
31
31
 
32
32
  # -- inherited from EventEmitter --
33
33
  # @nodoc
34
- def off(event, callback)
35
- event_emitter_proxy.off(event, callback)
34
+ def on(event, callback)
35
+ event_emitter_proxy.on(event, callback)
36
36
  end
37
37
 
38
38
  # -- inherited from EventEmitter --
39
39
  # @nodoc
40
- def once(event, callback)
41
- event_emitter_proxy.once(event, callback)
40
+ def off(event, callback)
41
+ event_emitter_proxy.off(event, callback)
42
42
  end
43
43
 
44
44
  private def event_emitter_proxy
@@ -40,6 +40,7 @@ module Playwright
40
40
  # Launches Chrome browser on the device, and returns its persistent context.
41
41
  def launch_browser(
42
42
  acceptDownloads: nil,
43
+ baseURL: nil,
43
44
  bypassCSP: nil,
44
45
  colorScheme: nil,
45
46
  command: nil,
@@ -65,7 +66,7 @@ module Playwright
65
66
  userAgent: nil,
66
67
  viewport: nil,
67
68
  &block)
68
- wrap_impl(@impl.launch_browser(acceptDownloads: unwrap_impl(acceptDownloads), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), command: unwrap_impl(command), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
69
+ wrap_impl(@impl.launch_browser(acceptDownloads: unwrap_impl(acceptDownloads), baseURL: unwrap_impl(baseURL), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), command: unwrap_impl(command), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
69
70
  end
70
71
 
71
72
  # Performs a long tap on the widget defined by `selector`.
@@ -161,14 +162,20 @@ module Playwright
161
162
  raise NotImplementedError.new('web_views is not implemented yet.')
162
163
  end
163
164
 
165
+ # @nodoc
166
+ def tap_on(selector, duration: nil, timeout: nil)
167
+ wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
168
+ end
169
+
164
170
  # @nodoc
165
171
  def tree
166
172
  wrap_impl(@impl.tree)
167
173
  end
168
174
 
175
+ # -- inherited from EventEmitter --
169
176
  # @nodoc
170
- def tap_on(selector, duration: nil, timeout: nil)
171
- wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
177
+ def once(event, callback)
178
+ event_emitter_proxy.once(event, callback)
172
179
  end
173
180
 
174
181
  # -- inherited from EventEmitter --
@@ -183,12 +190,6 @@ module Playwright
183
190
  event_emitter_proxy.off(event, callback)
184
191
  end
185
192
 
186
- # -- inherited from EventEmitter --
187
- # @nodoc
188
- def once(event, callback)
189
- event_emitter_proxy.once(event, callback)
190
- end
191
-
192
193
  private def event_emitter_proxy
193
194
  @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
194
195
  end
@@ -50,7 +50,7 @@ module Playwright
50
50
  #
51
51
  # Returns the newly created browser session.
52
52
  def new_browser_cdp_session
53
- raise NotImplementedError.new('new_browser_cdp_session is not implemented yet.')
53
+ wrap_impl(@impl.new_browser_cdp_session)
54
54
  end
55
55
 
56
56
  # Creates a new browser context. It won't share cookies/cache with other browser contexts.
@@ -65,6 +65,7 @@ module Playwright
65
65
  # ```
66
66
  def new_context(
67
67
  acceptDownloads: nil,
68
+ baseURL: nil,
68
69
  bypassCSP: nil,
69
70
  colorScheme: nil,
70
71
  deviceScaleFactor: nil,
@@ -91,7 +92,7 @@ module Playwright
91
92
  userAgent: nil,
92
93
  viewport: nil,
93
94
  &block)
94
- wrap_impl(@impl.new_context(acceptDownloads: unwrap_impl(acceptDownloads), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), storageState: unwrap_impl(storageState), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
95
+ wrap_impl(@impl.new_context(acceptDownloads: unwrap_impl(acceptDownloads), baseURL: unwrap_impl(baseURL), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), storageState: unwrap_impl(storageState), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
95
96
  end
96
97
 
97
98
  # Creates a new page in a new browser context. Closing this page will close the context as well.
@@ -101,6 +102,7 @@ module Playwright
101
102
  # [`method: BrowserContext.newPage`] to control their exact life times.
102
103
  def new_page(
103
104
  acceptDownloads: nil,
105
+ baseURL: nil,
104
106
  bypassCSP: nil,
105
107
  colorScheme: nil,
106
108
  deviceScaleFactor: nil,
@@ -127,10 +129,12 @@ module Playwright
127
129
  userAgent: nil,
128
130
  viewport: nil,
129
131
  &block)
130
- wrap_impl(@impl.new_page(acceptDownloads: unwrap_impl(acceptDownloads), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), storageState: unwrap_impl(storageState), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
132
+ wrap_impl(@impl.new_page(acceptDownloads: unwrap_impl(acceptDownloads), baseURL: unwrap_impl(baseURL), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), storageState: unwrap_impl(storageState), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
131
133
  end
132
134
 
133
- # > NOTE: Tracing is only supported on Chromium-based browsers.
135
+ # > NOTE: This API controls [Chromium Tracing](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool)
136
+ # which is a low-level chromium-specific debugging tool. API to control [Playwright Tracing](../trace-viewer) could be
137
+ # found [here](./class-tracing).
134
138
  #
135
139
  # You can use [`method: Browser.startTracing`] and [`method: Browser.stopTracing`] to create a trace file that can be
136
140
  # opened in Chrome DevTools performance panel.
@@ -144,7 +148,9 @@ module Playwright
144
148
  wrap_impl(@impl.start_tracing(page: unwrap_impl(page), categories: unwrap_impl(categories), path: unwrap_impl(path), screenshots: unwrap_impl(screenshots)))
145
149
  end
146
150
 
147
- # > NOTE: Tracing is only supported on Chromium-based browsers.
151
+ # > NOTE: This API controls [Chromium Tracing](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool)
152
+ # which is a low-level chromium-specific debugging tool. API to control [Playwright Tracing](../trace-viewer) could be
153
+ # found [here](./class-tracing).
148
154
  #
149
155
  # Returns the buffer with trace data.
150
156
  def stop_tracing
@@ -158,20 +164,20 @@ module Playwright
158
164
 
159
165
  # -- inherited from EventEmitter --
160
166
  # @nodoc
161
- def on(event, callback)
162
- event_emitter_proxy.on(event, callback)
167
+ def once(event, callback)
168
+ event_emitter_proxy.once(event, callback)
163
169
  end
164
170
 
165
171
  # -- inherited from EventEmitter --
166
172
  # @nodoc
167
- def off(event, callback)
168
- event_emitter_proxy.off(event, callback)
173
+ def on(event, callback)
174
+ event_emitter_proxy.on(event, callback)
169
175
  end
170
176
 
171
177
  # -- inherited from EventEmitter --
172
178
  # @nodoc
173
- def once(event, callback)
174
- event_emitter_proxy.once(event, callback)
179
+ def off(event, callback)
180
+ event_emitter_proxy.off(event, callback)
175
181
  end
176
182
 
177
183
  private def event_emitter_proxy
@@ -204,7 +204,7 @@ module Playwright
204
204
  #
205
205
  # Returns the newly created session.
206
206
  def new_cdp_session(page)
207
- raise NotImplementedError.new('new_cdp_session is not implemented yet.')
207
+ wrap_impl(@impl.new_cdp_session(unwrap_impl(page)))
208
208
  end
209
209
 
210
210
  # Creates a new page in the browser context.
@@ -362,6 +362,16 @@ module Playwright
362
362
  raise NotImplementedError.new('wait_for_event is not implemented yet.')
363
363
  end
364
364
 
365
+ # @nodoc
366
+ def enable_debug_console!
367
+ wrap_impl(@impl.enable_debug_console!)
368
+ end
369
+
370
+ # @nodoc
371
+ def pause
372
+ wrap_impl(@impl.pause)
373
+ end
374
+
365
375
  # @nodoc
366
376
  def browser=(req)
367
377
  wrap_impl(@impl.browser=(unwrap_impl(req)))
@@ -377,9 +387,10 @@ module Playwright
377
387
  wrap_impl(@impl.options=(unwrap_impl(req)))
378
388
  end
379
389
 
390
+ # -- inherited from EventEmitter --
380
391
  # @nodoc
381
- def pause
382
- wrap_impl(@impl.pause)
392
+ def once(event, callback)
393
+ event_emitter_proxy.once(event, callback)
383
394
  end
384
395
 
385
396
  # -- inherited from EventEmitter --
@@ -394,12 +405,6 @@ module Playwright
394
405
  event_emitter_proxy.off(event, callback)
395
406
  end
396
407
 
397
- # -- inherited from EventEmitter --
398
- # @nodoc
399
- def once(event, callback)
400
- event_emitter_proxy.once(event, callback)
401
- end
402
-
403
408
  private def event_emitter_proxy
404
409
  @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
405
410
  end
@@ -96,6 +96,7 @@ module Playwright
96
96
  userDataDir,
97
97
  acceptDownloads: nil,
98
98
  args: nil,
99
+ baseURL: nil,
99
100
  bypassCSP: nil,
100
101
  channel: nil,
101
102
  chromiumSandbox: nil,
@@ -135,7 +136,7 @@ module Playwright
135
136
  userAgent: nil,
136
137
  viewport: nil,
137
138
  &block)
138
- wrap_impl(@impl.launch_persistent_context(unwrap_impl(userDataDir), acceptDownloads: unwrap_impl(acceptDownloads), args: unwrap_impl(args), bypassCSP: unwrap_impl(bypassCSP), channel: unwrap_impl(channel), chromiumSandbox: unwrap_impl(chromiumSandbox), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), devtools: unwrap_impl(devtools), downloadsPath: unwrap_impl(downloadsPath), env: unwrap_impl(env), executablePath: unwrap_impl(executablePath), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), handleSIGHUP: unwrap_impl(handleSIGHUP), handleSIGINT: unwrap_impl(handleSIGINT), handleSIGTERM: unwrap_impl(handleSIGTERM), hasTouch: unwrap_impl(hasTouch), headless: unwrap_impl(headless), httpCredentials: unwrap_impl(httpCredentials), ignoreDefaultArgs: unwrap_impl(ignoreDefaultArgs), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), slowMo: unwrap_impl(slowMo), timeout: unwrap_impl(timeout), timezoneId: unwrap_impl(timezoneId), tracesDir: unwrap_impl(tracesDir), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
139
+ wrap_impl(@impl.launch_persistent_context(unwrap_impl(userDataDir), acceptDownloads: unwrap_impl(acceptDownloads), args: unwrap_impl(args), baseURL: unwrap_impl(baseURL), bypassCSP: unwrap_impl(bypassCSP), channel: unwrap_impl(channel), chromiumSandbox: unwrap_impl(chromiumSandbox), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), devtools: unwrap_impl(devtools), downloadsPath: unwrap_impl(downloadsPath), env: unwrap_impl(env), executablePath: unwrap_impl(executablePath), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), handleSIGHUP: unwrap_impl(handleSIGHUP), handleSIGINT: unwrap_impl(handleSIGINT), handleSIGTERM: unwrap_impl(handleSIGTERM), hasTouch: unwrap_impl(hasTouch), headless: unwrap_impl(headless), httpCredentials: unwrap_impl(httpCredentials), ignoreDefaultArgs: unwrap_impl(ignoreDefaultArgs), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), slowMo: unwrap_impl(slowMo), timeout: unwrap_impl(timeout), timezoneId: unwrap_impl(timezoneId), tracesDir: unwrap_impl(tracesDir), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
139
140
  end
140
141
 
141
142
  # Returns browser name. For example: `'chromium'`, `'webkit'` or `'firefox'`.
@@ -145,20 +146,20 @@ module Playwright
145
146
 
146
147
  # -- inherited from EventEmitter --
147
148
  # @nodoc
148
- def on(event, callback)
149
- event_emitter_proxy.on(event, callback)
149
+ def once(event, callback)
150
+ event_emitter_proxy.once(event, callback)
150
151
  end
151
152
 
152
153
  # -- inherited from EventEmitter --
153
154
  # @nodoc
154
- def off(event, callback)
155
- event_emitter_proxy.off(event, callback)
155
+ def on(event, callback)
156
+ event_emitter_proxy.on(event, callback)
156
157
  end
157
158
 
158
159
  # -- inherited from EventEmitter --
159
160
  # @nodoc
160
- def once(event, callback)
161
- event_emitter_proxy.once(event, callback)
161
+ def off(event, callback)
162
+ event_emitter_proxy.off(event, callback)
162
163
  end
163
164
 
164
165
  private def event_emitter_proxy
@@ -13,12 +13,12 @@ module Playwright
13
13
  #
14
14
  # ```python sync
15
15
  # client = page.context().new_cdp_session(page)
16
- # client.send("animation.enable")
17
- # client.on("animation.animation_created", lambda: print("animation created!"))
18
- # response = client.send("animation.get_playback_rate")
19
- # print("playback rate is " + response["playback_rate"])
20
- # client.send("animation.set_playback_rate", {
21
- # playback_rate: response["playback_rate"] / 2
16
+ # client.send("Animation.enable")
17
+ # client.on("Animation.animationCreated", lambda: print("animation created!"))
18
+ # response = client.send("Animation.getPlaybackRate")
19
+ # print("playback rate is " + str(response["playbackRate"]))
20
+ # client.send("Animation.setPlaybackRate", {
21
+ # playbackRate: response["playbackRate"] / 2
22
22
  # })
23
23
  # ```
24
24
  class CDPSession < PlaywrightApi
@@ -26,11 +26,33 @@ module Playwright
26
26
  # Detaches the CDPSession from the target. Once detached, the CDPSession object won't emit any events and can't be used to
27
27
  # send messages.
28
28
  def detach
29
- raise NotImplementedError.new('detach is not implemented yet.')
29
+ wrap_impl(@impl.detach)
30
30
  end
31
31
 
32
32
  def send_message(method, params: nil)
33
- raise NotImplementedError.new('send_message is not implemented yet.')
33
+ wrap_impl(@impl.send_message(unwrap_impl(method), params: unwrap_impl(params)))
34
+ end
35
+
36
+ # -- inherited from EventEmitter --
37
+ # @nodoc
38
+ def once(event, callback)
39
+ event_emitter_proxy.once(event, callback)
40
+ end
41
+
42
+ # -- inherited from EventEmitter --
43
+ # @nodoc
44
+ def on(event, callback)
45
+ event_emitter_proxy.on(event, callback)
46
+ end
47
+
48
+ # -- inherited from EventEmitter --
49
+ # @nodoc
50
+ def off(event, callback)
51
+ event_emitter_proxy.off(event, callback)
52
+ end
53
+
54
+ private def event_emitter_proxy
55
+ @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
34
56
  end
35
57
  end
36
58
  end
@@ -25,20 +25,20 @@ module Playwright
25
25
 
26
26
  # -- inherited from EventEmitter --
27
27
  # @nodoc
28
- def on(event, callback)
29
- event_emitter_proxy.on(event, callback)
28
+ def once(event, callback)
29
+ event_emitter_proxy.once(event, callback)
30
30
  end
31
31
 
32
32
  # -- inherited from EventEmitter --
33
33
  # @nodoc
34
- def off(event, callback)
35
- event_emitter_proxy.off(event, callback)
34
+ def on(event, callback)
35
+ event_emitter_proxy.on(event, callback)
36
36
  end
37
37
 
38
38
  # -- inherited from EventEmitter --
39
39
  # @nodoc
40
- def once(event, callback)
41
- event_emitter_proxy.once(event, callback)
40
+ def off(event, callback)
41
+ event_emitter_proxy.off(event, callback)
42
42
  end
43
43
 
44
44
  private def event_emitter_proxy