playwright-ruby-client 1.58.1.alpha2 → 1.59.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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -7
  3. data/documentation/docs/api/browser_context.md +26 -0
  4. data/documentation/docs/api/browser_type.md +2 -0
  5. data/documentation/docs/api/console_message.md +9 -0
  6. data/documentation/docs/api/frame.md +2 -2
  7. data/documentation/docs/api/frame_locator.md +2 -2
  8. data/documentation/docs/api/locator.md +16 -3
  9. data/documentation/docs/api/page.md +68 -5
  10. data/documentation/docs/api/request.md +13 -0
  11. data/documentation/docs/api/response.md +9 -0
  12. data/documentation/docs/api/tracing.md +1 -0
  13. data/documentation/docs/article/guides/rails_integration_with_null_driver.md +46 -0
  14. data/documentation/docs/include/api_coverage.md +15 -0
  15. data/lib/playwright/channel_owners/browser_context.rb +24 -4
  16. data/lib/playwright/channel_owners/debugger.rb +4 -0
  17. data/lib/playwright/channel_owners/dialog.rb +3 -1
  18. data/lib/playwright/channel_owners/disposable.rb +9 -0
  19. data/lib/playwright/channel_owners/overlay.rb +4 -0
  20. data/lib/playwright/channel_owners/page.rb +54 -31
  21. data/lib/playwright/channel_owners/request.rb +8 -0
  22. data/lib/playwright/channel_owners/response.rb +5 -0
  23. data/lib/playwright/channel_owners/tracing.rb +2 -1
  24. data/lib/playwright/console_message_impl.rb +4 -0
  25. data/lib/playwright/disposable.rb +11 -0
  26. data/lib/playwright/har_router.rb +16 -1
  27. data/lib/playwright/locator_impl.rb +19 -3
  28. data/lib/playwright/screencast.rb +91 -0
  29. data/lib/playwright/utils.rb +19 -0
  30. data/lib/playwright/version.rb +2 -2
  31. data/lib/playwright/video.rb +6 -4
  32. data/lib/playwright.rb +2 -0
  33. data/lib/playwright_api/android.rb +7 -7
  34. data/lib/playwright_api/android_device.rb +6 -6
  35. data/lib/playwright_api/api_request_context.rb +6 -6
  36. data/lib/playwright_api/browser.rb +18 -6
  37. data/lib/playwright_api/browser_context.rb +42 -16
  38. data/lib/playwright_api/browser_type.rb +11 -9
  39. data/lib/playwright_api/cdp_session.rb +6 -6
  40. data/lib/playwright_api/console_message.rb +6 -0
  41. data/lib/playwright_api/dialog.rb +6 -6
  42. data/lib/playwright_api/element_handle.rb +6 -6
  43. data/lib/playwright_api/frame.rb +8 -8
  44. data/lib/playwright_api/frame_locator.rb +2 -2
  45. data/lib/playwright_api/js_handle.rb +6 -6
  46. data/lib/playwright_api/locator.rb +14 -4
  47. data/lib/playwright_api/page.rb +68 -19
  48. data/lib/playwright_api/playwright.rb +6 -6
  49. data/lib/playwright_api/request.rb +16 -6
  50. data/lib/playwright_api/response.rb +12 -6
  51. data/lib/playwright_api/route.rb +6 -6
  52. data/lib/playwright_api/tracing.rb +8 -7
  53. data/lib/playwright_api/web_socket.rb +6 -6
  54. data/lib/playwright_api/worker.rb +8 -8
  55. data/playwright.gemspec +7 -1
  56. data/sig/playwright.rbs +28 -15
  57. metadata +7 -11
  58. data/AGENTS.md +0 -4
  59. data/CLAUDE/api_generation.md +0 -28
  60. data/CLAUDE/ci_expectations.md +0 -23
  61. data/CLAUDE/gem_release_flow.md +0 -39
  62. data/CLAUDE/past_upgrade_pr_patterns.md +0 -42
  63. data/CLAUDE/playwright_upgrade_workflow.md +0 -35
  64. data/CLAUDE/rspec_debugging.md +0 -30
  65. data/CLAUDE/unimplemented_examples.md +0 -18
  66. data/CLAUDE.md +0 -32
@@ -56,7 +56,9 @@ module Playwright
56
56
  emit(Events::Page::PageError, Error.parse(params['error']['error']))
57
57
  })
58
58
  @channel.on('route', ->(params) { on_route(ChannelOwners::Route.from(params['route'])) })
59
- @channel.on('video', method(:on_video))
59
+ if @initializer['video']
60
+ @video_artifact = ChannelOwners::Artifact.from(@initializer['video'])
61
+ end
60
62
  @channel.on('viewportSizeChanged', method(:on_viewport_size_changed))
61
63
  @channel.on('webSocket', ->(params) {
62
64
  emit(Events::Page::WebSocket, ChannelOwners::WebSocket.from(params['webSocket']))
@@ -171,11 +173,6 @@ module Playwright
171
173
  emit(Events::Page::Download, download)
172
174
  end
173
175
 
174
- private def on_video(params)
175
- artifact = ChannelOwners::Artifact.from(params['artifact'])
176
- video.send(:set_artifact, artifact)
177
- end
178
-
179
176
  private def on_viewport_size_changed(params)
180
177
  @viewport_size = {
181
178
  width: params['viewportSize']['width'],
@@ -307,8 +304,9 @@ module Playwright
307
304
  end
308
305
 
309
306
  def expose_function(name, callback)
310
- @channel.send_message_to_server('exposeBinding', name: name)
307
+ result = @channel.send_message_to_server_result('exposeBinding', name: name)
311
308
  @bindings[name] = ->(_source, *args) { callback.call(*args) }
309
+ ChannelOwners::Disposable.from(result['disposable'])
312
310
  end
313
311
 
314
312
  def expose_binding(name, callback, handle: nil)
@@ -316,8 +314,9 @@ module Playwright
316
314
  name: name,
317
315
  needsHandle: handle,
318
316
  }.compact
319
- @channel.send_message_to_server('exposeBinding', params)
317
+ result = @channel.send_message_to_server_result('exposeBinding', params)
320
318
  @bindings[name] = callback
319
+ ChannelOwners::Disposable.from(result['disposable'])
321
320
  end
322
321
 
323
322
  def set_extra_http_headers(headers)
@@ -412,14 +411,15 @@ module Playwright
412
411
  raise ArgumentError.new('Either path or script parameter must be specified')
413
412
  end
414
413
 
415
- @channel.send_message_to_server('addInitScript', source: source)
416
- nil
414
+ result = @channel.send_message_to_server_result('addInitScript', source: source)
415
+ ChannelOwners::Disposable.from(result['disposable'])
417
416
  end
418
417
 
419
418
  def route(url, handler, times: nil)
420
419
  entry = RouteHandler.new(url, @browser_context.send(:base_url), handler, times)
421
420
  @routes.unshift(entry)
422
421
  update_interception_patterns
422
+ DisposableStub.new { unroute(url, handler: handler) }
423
423
  end
424
424
 
425
425
  def unroute_all(behavior: nil)
@@ -646,20 +646,49 @@ module Playwright
646
646
  timeout: timeout)
647
647
  end
648
648
 
649
- def console_messages
650
- messages = @channel.send_message_to_server('consoleMessages')
649
+ def console_messages(filter: nil)
650
+ params = {}
651
+ params[:filter] = filter if filter
652
+ messages = @channel.send_message_to_server('consoleMessages', params)
651
653
  messages.map do |message|
652
654
  ConsoleMessageImpl.new(message, self, nil)
653
655
  end
654
656
  end
655
657
 
656
- def page_errors
657
- errors = @channel.send_message_to_server('pageErrors')
658
+ def page_errors(filter: nil)
659
+ params = {}
660
+ params[:filter] = filter if filter
661
+ errors = @channel.send_message_to_server('pageErrors', params)
658
662
  errors.map do |error|
659
663
  Error.parse(error['error'])
660
664
  end
661
665
  end
662
666
 
667
+ def clear_console_messages
668
+ @channel.send_message_to_server('clearConsoleMessages')
669
+ end
670
+
671
+ def clear_page_errors
672
+ @channel.send_message_to_server('clearPageErrors')
673
+ end
674
+
675
+ def cancel_pick_locator
676
+ @channel.send_message_to_server('cancelPickLocator')
677
+ end
678
+
679
+ def aria_snapshot(depth: nil, mode: nil, timeout: nil, _track: nil)
680
+ params = { selector: 'body' }
681
+ params[:timeout] = @timeout_settings.timeout(timeout)
682
+ params[:depth] = depth if depth
683
+ params[:mode] = mode if mode
684
+ if _track
685
+ params.delete(:selector)
686
+ params[:track] = _track
687
+ end
688
+ result = @main_frame.channel.send_message_to_server_result('ariaSnapshot', params)
689
+ result['snapshot']
690
+ end
691
+
663
692
  def locator(
664
693
  selector,
665
694
  has: nil,
@@ -904,28 +933,22 @@ module Playwright
904
933
  decoded_binary
905
934
  end
906
935
 
936
+ def screencast
937
+ @screencast ||= Screencast.new(self)
938
+ end
939
+
907
940
  def video
908
941
  return nil unless @browser_context.send(:has_record_video_option?)
909
- @video ||= Video.new(self)
942
+ @video ||= Video.new(self, artifact: @video_artifact)
910
943
  end
911
944
 
912
- def snapshot_for_ai(timeout: nil, mode: nil, track: nil)
913
- option_mode = mode || 'full'
914
- unless ['full', 'incremental'].include?(option_mode)
915
- raise ArgumentError.new("mode must be either 'full' or 'incremental'")
916
- end
945
+ def pick_locator
946
+ result = @channel.send_message_to_server_result('pickLocator', {})
947
+ @main_frame.locator(result['selector'])
948
+ end
917
949
 
918
- options = {
919
- timeout: @timeout_settings.timeout(timeout),
920
- mode: option_mode,
921
- }
922
- options[:track] = track if track
923
- result = @channel.send_message_to_server_result('snapshotForAI', options)
924
- if option_mode == 'full'
925
- result['full']
926
- elsif option_mode == 'incremental'
927
- result['incremental']
928
- end
950
+ def snapshot_for_ai(timeout: nil, depth: nil, _track: nil)
951
+ aria_snapshot(mode: 'ai', timeout: timeout, depth: depth, _track: _track)
929
952
  end
930
953
 
931
954
  def start_js_coverage(resetOnNavigation: nil, reportAnonymousScripts: nil)
@@ -81,6 +81,10 @@ module Playwright
81
81
  end
82
82
  end
83
83
 
84
+ def existing_response
85
+ @response
86
+ end
87
+
84
88
  def response
85
89
  resp = @channel.send_message_to_server('response')
86
90
  ChannelOwners::Response.from_nullable(resp)
@@ -162,6 +166,10 @@ module Playwright
162
166
  res.send(:sizes)
163
167
  end
164
168
 
169
+ private def update_response(response)
170
+ @response = response
171
+ end
172
+
165
173
  private def update_redirected_to(request)
166
174
  @redirected_to = request
167
175
  end
@@ -7,6 +7,7 @@ module Playwright
7
7
  private def after_initialize
8
8
  @provisional_headers = RawHeaders.new(@initializer['headers'])
9
9
  @request = ChannelOwners::Request.from(@initializer['request'])
10
+ @request.send(:update_response, self)
10
11
  timing = @initializer['timing']
11
12
  @request.send(:update_timings,
12
13
  start_time: timing["startTime"],
@@ -74,6 +75,10 @@ module Playwright
74
75
  actual_headers.get_all(name)
75
76
  end
76
77
 
78
+ def http_version
79
+ @channel.send_message_to_server('httpVersion')
80
+ end
81
+
77
82
  def server_addr
78
83
  @channel.send_message_to_server('serverAddr')
79
84
  end
@@ -1,11 +1,12 @@
1
1
  module Playwright
2
2
  define_channel_owner :Tracing do
3
- def start(name: nil, title: nil, screenshots: nil, snapshots: nil, sources: nil)
3
+ def start(name: nil, title: nil, screenshots: nil, snapshots: nil, sources: nil, live: nil)
4
4
  params = {
5
5
  name: name,
6
6
  screenshots: screenshots,
7
7
  snapshots: snapshots,
8
8
  sources: sources,
9
+ live: live,
9
10
  }.compact
10
11
  @include_sources = params[:sources] || false
11
12
  @channel.send_message_to_server('tracingStart', params)
@@ -25,5 +25,9 @@ module Playwright
25
25
  def location
26
26
  @event['location']
27
27
  end
28
+
29
+ def timestamp
30
+ @event['timestamp']
31
+ end
28
32
  end
29
33
  end
@@ -0,0 +1,11 @@
1
+ module Playwright
2
+ class Disposable
3
+ def initialize(impl)
4
+ @impl = impl
5
+ end
6
+
7
+ def dispose
8
+ @impl.dispose
9
+ end
10
+ end
11
+ end
@@ -53,9 +53,10 @@ module Playwright
53
53
  # test when HAR was recorded but we'd abort it immediately.
54
54
  return if response['status'] == -1
55
55
 
56
+ headers = merge_har_response_headers(response['headers'])
56
57
  route.fulfill(
57
58
  status: response['status'],
58
- headers: response['headers'].map { |header| [header['name'], header['value']] }.to_h,
59
+ headers: headers,
59
60
  body: Base64.strict_decode64(response['body']),
60
61
  )
61
62
  else
@@ -82,6 +83,20 @@ module Playwright
82
83
  page.once(Events::Page::Close, method(:dispose))
83
84
  end
84
85
 
86
+ private def merge_har_response_headers(headers)
87
+ headers.each_with_object({}) do |header, merged|
88
+ name = header['name']
89
+ value = header['value']
90
+
91
+ if name.casecmp('set-cookie').zero?
92
+ key = merged.keys.find { |existing| existing.casecmp('set-cookie').zero? } || name
93
+ merged[key] = merged[key] ? "#{merged[key]}\n#{value}" : value
94
+ else
95
+ merged[name] = value
96
+ end
97
+ end
98
+ end
99
+
85
100
  def dispose
86
101
  @local_utils.async_har_close(@har_id)
87
102
  end
@@ -426,11 +426,27 @@ module Playwright
426
426
  end
427
427
  end
428
428
 
429
- def aria_snapshot(timeout: nil)
430
- @frame.channel.send_message_to_server('ariaSnapshot', {
429
+ def aria_snapshot(depth: nil, mode: nil, timeout: nil, _track: nil)
430
+ params = {
431
431
  selector: @selector,
432
432
  timeout: _timeout(timeout),
433
- }.compact)
433
+ }
434
+ params[:depth] = depth if depth
435
+ params[:mode] = mode if mode
436
+ if _track
437
+ params.delete(:selector)
438
+ params[:track] = _track
439
+ end
440
+ result = @frame.channel.send_message_to_server_result('ariaSnapshot', params.compact)
441
+ result['snapshot']
442
+ end
443
+
444
+ def normalize
445
+ resolved_selector = @frame.channel.send_message_to_server('resolveSelector', { selector: @selector })
446
+ LocatorImpl.new(
447
+ frame: @frame,
448
+ selector: resolved_selector,
449
+ )
434
450
  end
435
451
 
436
452
  def scroll_into_view_if_needed(timeout: nil)
@@ -0,0 +1,91 @@
1
+ require 'base64'
2
+
3
+ module Playwright
4
+ class Screencast
5
+ def initialize(page)
6
+ @page = page
7
+ @started = false
8
+ @save_path = nil
9
+ @artifact = nil
10
+ @on_frame = nil
11
+ @page.send(:channel).on('screencastFrame', method(:handle_screencast_frame))
12
+ end
13
+
14
+ def start(path: nil, size: nil, quality: nil, &on_frame)
15
+ raise 'Screencast is already started' if @started
16
+
17
+ @started = true
18
+ @on_frame = on_frame if on_frame
19
+
20
+ params = {}
21
+ params[:record] = true if path
22
+ params[:size] = size if size
23
+ params[:quality] = quality if quality
24
+ params[:sendFrames] = true if on_frame
25
+
26
+ result = @page.send(:channel).send_message_to_server_result('screencastStart', params)
27
+ if result.is_a?(Hash) && result['artifact']
28
+ @artifact = ChannelOwners::Artifact.from(result['artifact'])
29
+ @save_path = path
30
+ end
31
+
32
+ DisposableStub.new { stop }
33
+ end
34
+
35
+ def stop
36
+ return unless @started
37
+
38
+ @started = false
39
+ @on_frame = nil
40
+ @page.send(:channel).send_message_to_server('screencastStop')
41
+
42
+ if @save_path && @artifact
43
+ @artifact.save_as(@save_path)
44
+ end
45
+ @artifact = nil
46
+ @save_path = nil
47
+ end
48
+
49
+ def show_overlay(html, duration: nil)
50
+ params = { html: html }
51
+ params[:duration] = duration if duration
52
+ result = @page.send(:channel).send_message_to_server_result('screencastShowOverlay', params)
53
+ overlay_id = result['id'] if result.is_a?(Hash)
54
+ DisposableStub.new {
55
+ @page.send(:channel).send_message_to_server('screencastRemoveOverlay', id: overlay_id) if overlay_id
56
+ }
57
+ end
58
+
59
+ def show_chapter(title, description: nil, duration: nil)
60
+ params = { title: title }
61
+ params[:description] = description if description
62
+ params[:duration] = duration if duration
63
+ @page.send(:channel).send_message_to_server('screencastChapter', params)
64
+ end
65
+
66
+ def show_actions(duration: nil, fontSize: nil, position: nil)
67
+ params = {}
68
+ params[:duration] = duration if duration
69
+ params[:fontSize] = fontSize if fontSize
70
+ params[:position] = position if position
71
+ @page.send(:channel).send_message_to_server('screencastShowActions', params)
72
+ DisposableStub.new { hide_actions }
73
+ end
74
+
75
+ def hide_actions
76
+ @page.send(:channel).send_message_to_server('screencastHideActions')
77
+ end
78
+
79
+ def show_overlays
80
+ @page.send(:channel).send_message_to_server('screencastSetOverlayVisible', visible: true)
81
+ end
82
+
83
+ def hide_overlays
84
+ @page.send(:channel).send_message_to_server('screencastSetOverlayVisible', visible: false)
85
+ end
86
+
87
+ private def handle_screencast_frame(event)
88
+ @on_frame&.call(Base64.strict_decode64(event['data']))
89
+ end
90
+ end
91
+ end
@@ -1,6 +1,22 @@
1
1
  require 'base64'
2
2
 
3
3
  module Playwright
4
+ class DisposableStub
5
+ def initialize(&block)
6
+ @block = block
7
+ end
8
+
9
+ def dispose
10
+ return unless @block
11
+
12
+ block = @block
13
+ @block = nil
14
+ block.call
15
+ rescue TargetClosedError
16
+ nil
17
+ end
18
+ end
19
+
4
20
  module Utils
5
21
  module PrepareBrowserContextOptions
6
22
  # @see https://github.com/microsoft/playwright/blob/5a2cfdbd47ed3c3deff77bb73e5fac34241f649d/src/client/browserContext.ts#L265
@@ -19,6 +35,9 @@ module Playwright
19
35
  if params[:record_video_size]
20
36
  params[:recordVideo][:size] = params.delete(:record_video_size)
21
37
  end
38
+ if params[:record_video_show_actions]
39
+ params[:recordVideo][:showActions] = params.delete(:record_video_show_actions)
40
+ end
22
41
  end
23
42
  if params[:storageState].is_a?(String)
24
43
  params[:storageState] = JSON.parse(File.read(params[:storageState]))
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playwright
4
- VERSION = '1.58.1.alpha2'
5
- COMPATIBLE_PLAYWRIGHT_VERSION = '1.58.0'
4
+ VERSION = '1.59.0'
5
+ COMPATIBLE_PLAYWRIGHT_VERSION = '1.59.0'
6
6
  end
@@ -1,9 +1,11 @@
1
1
  module Playwright
2
2
  class Video
3
- def initialize(page)
3
+ def initialize(page, artifact: nil)
4
4
  @page = page
5
5
  @artifact = Concurrent::Promises.resolvable_future
6
- if @page.closed?
6
+ if artifact
7
+ @artifact.fulfill(artifact)
8
+ elsif @page.closed?
7
9
  on_page_closed
8
10
  else
9
11
  page.once('close', -> { on_page_closed })
@@ -16,9 +18,9 @@ module Playwright
16
18
  end
17
19
  end
18
20
 
19
- # called only from Page#on_video via send(:set_artifact, artifact)
21
+ # called only from Page with send(:set_artifact, artifact)
20
22
  private def set_artifact(artifact)
21
- @artifact.fulfill(artifact)
23
+ @artifact.fulfill(artifact) unless @artifact.resolved?
22
24
  end
23
25
 
24
26
  def path
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/disposable'
23
24
  require 'playwright/har_router'
24
25
  require 'playwright/raw_headers'
25
26
  require 'playwright/route_handler'
@@ -28,6 +29,7 @@ require 'playwright/timeout_settings'
28
29
  require 'playwright/transport'
29
30
  require 'playwright/url_matcher'
30
31
  require 'playwright/version'
32
+ require 'playwright/screencast'
31
33
  require 'playwright/video'
32
34
  require 'playwright/waiter'
33
35
 
@@ -21,7 +21,7 @@ module Playwright
21
21
  #
22
22
  # This methods attaches Playwright to an existing Android device.
23
23
  # Use [`method: Android.launchServer`] to launch a new Android server instance.
24
- def connect(wsEndpoint, headers: nil, slowMo: nil, timeout: nil)
24
+ def connect(endpoint, headers: nil, slowMo: nil, timeout: nil)
25
25
  raise NotImplementedError.new('connect is not implemented yet.')
26
26
  end
27
27
 
@@ -43,12 +43,6 @@ module Playwright
43
43
  wrap_impl(@impl.set_default_navigation_timeout(unwrap_impl(timeout)))
44
44
  end
45
45
 
46
- # -- inherited from EventEmitter --
47
- # @nodoc
48
- def once(event, callback)
49
- event_emitter_proxy.once(event, callback)
50
- end
51
-
52
46
  # -- inherited from EventEmitter --
53
47
  # @nodoc
54
48
  def on(event, callback)
@@ -61,6 +55,12 @@ module Playwright
61
55
  event_emitter_proxy.off(event, callback)
62
56
  end
63
57
 
58
+ # -- inherited from EventEmitter --
59
+ # @nodoc
60
+ def once(event, callback)
61
+ event_emitter_proxy.once(event, callback)
62
+ end
63
+
64
64
  private def event_emitter_proxy
65
65
  @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
66
66
  end
@@ -204,12 +204,6 @@ module Playwright
204
204
  wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
205
205
  end
206
206
 
207
- # -- inherited from EventEmitter --
208
- # @nodoc
209
- def once(event, callback)
210
- event_emitter_proxy.once(event, callback)
211
- end
212
-
213
207
  # -- inherited from EventEmitter --
214
208
  # @nodoc
215
209
  def on(event, callback)
@@ -222,6 +216,12 @@ module Playwright
222
216
  event_emitter_proxy.off(event, callback)
223
217
  end
224
218
 
219
+ # -- inherited from EventEmitter --
220
+ # @nodoc
221
+ def once(event, callback)
222
+ event_emitter_proxy.once(event, callback)
223
+ end
224
+
225
225
  private def event_emitter_proxy
226
226
  @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
227
227
  end
@@ -286,12 +286,6 @@ module Playwright
286
286
  raise NotImplementedError.new('storage_state is not implemented yet.')
287
287
  end
288
288
 
289
- # -- inherited from EventEmitter --
290
- # @nodoc
291
- def once(event, callback)
292
- event_emitter_proxy.once(event, callback)
293
- end
294
-
295
289
  # -- inherited from EventEmitter --
296
290
  # @nodoc
297
291
  def on(event, callback)
@@ -304,6 +298,12 @@ module Playwright
304
298
  event_emitter_proxy.off(event, callback)
305
299
  end
306
300
 
301
+ # -- inherited from EventEmitter --
302
+ # @nodoc
303
+ def once(event, callback)
304
+ event_emitter_proxy.once(event, callback)
305
+ end
306
+
307
307
  private def event_emitter_proxy
308
308
  @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
309
309
  end
@@ -172,6 +172,12 @@ module Playwright
172
172
  wrap_impl(@impl.new_page(acceptDownloads: unwrap_impl(acceptDownloads), baseURL: unwrap_impl(baseURL), bypassCSP: unwrap_impl(bypassCSP), clientCertificates: unwrap_impl(clientCertificates), colorScheme: unwrap_impl(colorScheme), contrast: unwrap_impl(contrast), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), forcedColors: unwrap_impl(forcedColors), 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_content: unwrap_impl(record_har_content), record_har_mode: unwrap_impl(record_har_mode), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_har_url_filter: unwrap_impl(record_har_url_filter), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), reducedMotion: unwrap_impl(reducedMotion), screen: unwrap_impl(screen), serviceWorkers: unwrap_impl(serviceWorkers), storageState: unwrap_impl(storageState), strictSelectors: unwrap_impl(strictSelectors), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
173
173
  end
174
174
 
175
+ #
176
+ # Binds the browser to a named pipe or web socket, making it available for other clients to connect to.
177
+ def bind(title, host: nil, port: nil, workspaceDir: nil)
178
+ raise NotImplementedError.new('bind is not implemented yet.')
179
+ end
180
+
175
181
  #
176
182
  # **NOTE**: This API controls [Chromium Tracing](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool) which is a low-level chromium-specific debugging tool. API to control [Playwright Tracing](../trace-viewer) could be found [here](./class-tracing).
177
183
  #
@@ -197,18 +203,18 @@ module Playwright
197
203
  wrap_impl(@impl.stop_tracing)
198
204
  end
199
205
 
206
+ #
207
+ # Unbinds the browser server previously bound with [`method: Browser.bind`].
208
+ def unbind
209
+ raise NotImplementedError.new('unbind is not implemented yet.')
210
+ end
211
+
200
212
  #
201
213
  # Returns the browser version.
202
214
  def version
203
215
  wrap_impl(@impl.version)
204
216
  end
205
217
 
206
- # -- inherited from EventEmitter --
207
- # @nodoc
208
- def once(event, callback)
209
- event_emitter_proxy.once(event, callback)
210
- end
211
-
212
218
  # -- inherited from EventEmitter --
213
219
  # @nodoc
214
220
  def on(event, callback)
@@ -221,6 +227,12 @@ module Playwright
221
227
  event_emitter_proxy.off(event, callback)
222
228
  end
223
229
 
230
+ # -- inherited from EventEmitter --
231
+ # @nodoc
232
+ def once(event, callback)
233
+ event_emitter_proxy.once(event, callback)
234
+ end
235
+
224
236
  private def event_emitter_proxy
225
237
  @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
226
238
  end