playwright-ruby-client 1.57.0 → 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 (76) 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 +3 -2
  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 +17 -4
  9. data/documentation/docs/api/locator_assertions.md +1 -1
  10. data/documentation/docs/api/page.md +68 -5
  11. data/documentation/docs/api/request.md +13 -0
  12. data/documentation/docs/api/response.md +9 -0
  13. data/documentation/docs/api/route.md +4 -1
  14. data/documentation/docs/api/tracing.md +1 -0
  15. data/documentation/docs/article/getting_started.md +1 -1
  16. data/documentation/docs/article/guides/inspector.md +1 -1
  17. data/documentation/docs/article/guides/launch_browser.md +5 -5
  18. data/documentation/docs/article/guides/rails_integration.md +3 -3
  19. data/documentation/docs/article/guides/rails_integration_with_null_driver.md +46 -0
  20. data/documentation/docs/article/guides/recording_video.md +2 -2
  21. data/documentation/docs/article/guides/semi_automation.md +1 -1
  22. data/documentation/docs/include/api_coverage.md +16 -0
  23. data/lib/playwright/channel_owners/api_request_context.rb +24 -2
  24. data/lib/playwright/channel_owners/binding_call.rb +37 -3
  25. data/lib/playwright/channel_owners/browser_context.rb +24 -4
  26. data/lib/playwright/channel_owners/browser_type.rb +2 -1
  27. data/lib/playwright/channel_owners/debugger.rb +4 -0
  28. data/lib/playwright/channel_owners/dialog.rb +3 -1
  29. data/lib/playwright/channel_owners/disposable.rb +9 -0
  30. data/lib/playwright/channel_owners/overlay.rb +4 -0
  31. data/lib/playwright/channel_owners/page.rb +58 -32
  32. data/lib/playwright/channel_owners/request.rb +8 -0
  33. data/lib/playwright/channel_owners/response.rb +5 -0
  34. data/lib/playwright/channel_owners/stream.rb +4 -0
  35. data/lib/playwright/channel_owners/tracing.rb +17 -7
  36. data/lib/playwright/channel_owners/web_socket.rb +14 -0
  37. data/lib/playwright/connection.rb +25 -20
  38. data/lib/playwright/console_message_impl.rb +4 -0
  39. data/lib/playwright/disposable.rb +11 -0
  40. data/lib/playwright/har_router.rb +16 -1
  41. data/lib/playwright/javascript/value_serializer.rb +2 -1
  42. data/lib/playwright/locator_assertions_impl.rb +1 -1
  43. data/lib/playwright/locator_impl.rb +19 -3
  44. data/lib/playwright/page_assertions_impl.rb +1 -1
  45. data/lib/playwright/screencast.rb +91 -0
  46. data/lib/playwright/utils.rb +19 -0
  47. data/lib/playwright/version.rb +2 -2
  48. data/lib/playwright/video.rb +6 -4
  49. data/lib/playwright/waiter.rb +24 -6
  50. data/lib/playwright.rb +2 -0
  51. data/lib/playwright_api/android.rb +7 -7
  52. data/lib/playwright_api/android_device.rb +8 -8
  53. data/lib/playwright_api/api_request_context.rb +6 -6
  54. data/lib/playwright_api/browser.rb +18 -6
  55. data/lib/playwright_api/browser_context.rb +32 -6
  56. data/lib/playwright_api/browser_type.rb +13 -12
  57. data/lib/playwright_api/cdp_session.rb +6 -6
  58. data/lib/playwright_api/console_message.rb +6 -0
  59. data/lib/playwright_api/dialog.rb +6 -6
  60. data/lib/playwright_api/element_handle.rb +6 -6
  61. data/lib/playwright_api/frame.rb +8 -8
  62. data/lib/playwright_api/frame_locator.rb +2 -2
  63. data/lib/playwright_api/js_handle.rb +6 -6
  64. data/lib/playwright_api/locator.rb +19 -9
  65. data/lib/playwright_api/locator_assertions.rb +1 -1
  66. data/lib/playwright_api/page.rb +72 -23
  67. data/lib/playwright_api/playwright.rb +6 -6
  68. data/lib/playwright_api/request.rb +28 -6
  69. data/lib/playwright_api/response.rb +12 -6
  70. data/lib/playwright_api/route.rb +10 -7
  71. data/lib/playwright_api/tracing.rb +8 -7
  72. data/lib/playwright_api/web_socket.rb +6 -6
  73. data/lib/playwright_api/worker.rb +6 -6
  74. data/playwright.gemspec +9 -1
  75. data/sig/playwright.rbs +30 -17
  76. metadata +35 -2
@@ -11,9 +11,8 @@ module Playwright
11
11
  dispatch(message)
12
12
  end
13
13
  @transport.on_driver_crashed do
14
- @callbacks.each_value do |callback|
15
- callback.reject(::Playwright::DriverCrashedError.new)
16
- end
14
+ callbacks = @callbacks_mutex.synchronize { @callbacks.values }
15
+ callbacks.each { |callback| callback.reject(::Playwright::DriverCrashedError.new) }
17
16
  raise ::Playwright::DriverCrashedError.new
18
17
  end
19
18
  @transport.on_driver_closed do
@@ -21,8 +20,10 @@ module Playwright
21
20
  end
22
21
 
23
22
  @objects = {} # Hash[ guid => ChannelOwner ]
23
+ @objects_mutex = Mutex.new
24
24
  @waiting_for_object = {} # Hash[ guid => Promise<ChannelOwner> ]
25
25
  @callbacks = {} # Hash [ guid => Promise<ChannelOwner> ]
26
+ @callbacks_mutex = Mutex.new
26
27
  @root_object = RootChannelOwner.new(self)
27
28
  @remote = false
28
29
  @tracing_count = 0
@@ -50,10 +51,10 @@ module Playwright
50
51
 
51
52
  def cleanup(cause: nil)
52
53
  @closed_error = TargetClosedError.new(message: cause)
53
- @callbacks.each_value do |callback|
54
- callback.reject(@closed_error)
54
+ callbacks = @callbacks_mutex.synchronize do
55
+ @callbacks.values.tap { @callbacks.clear }
55
56
  end
56
- @callbacks.clear
57
+ callbacks.each { |callback| callback.reject(@closed_error) }
57
58
  end
58
59
 
59
60
  def initialize_playwright
@@ -80,7 +81,7 @@ module Playwright
80
81
  with_generated_id do |id|
81
82
  # register callback promise object first.
82
83
  # @see https://github.com/YusukeIwaki/puppeteer-ruby/pull/34
83
- @callbacks[id] = callback
84
+ @callbacks_mutex.synchronize { @callbacks[id] = callback }
84
85
 
85
86
  _metadata = {}
86
87
  frames = []
@@ -107,12 +108,12 @@ module Playwright
107
108
  begin
108
109
  @transport.send_message(message)
109
110
  rescue => err
110
- @callbacks.delete(id)
111
+ @callbacks_mutex.synchronize { @callbacks.delete(id) }
111
112
  callback.reject(err)
112
113
  raise unless err.is_a?(Transport::AlreadyDisconnectedError)
113
114
  end
114
115
 
115
- if @tracing_count > 0 && !frames.empty? && guid != 'localUtils'
116
+ if @tracing_count > 0 && !frames.empty? && guid != 'localUtils' && !remote?
116
117
  @local_utils.add_stack_to_tracing_no_reply(id, frames)
117
118
  end
118
119
  end
@@ -132,21 +133,24 @@ module Playwright
132
133
  # end
133
134
  # ````
134
135
  def with_generated_id(&block)
135
- @last_id ||= 0
136
- block.call(@last_id += 1)
136
+ id = @callbacks_mutex.synchronize do
137
+ @last_id ||= 0
138
+ @last_id += 1
139
+ end
140
+ block.call(id)
137
141
  end
138
142
 
139
143
  # @param guid [String]
140
144
  # @param parent [Playwright::ChannelOwner]
141
145
  # @note This method should be used internally. Accessed via .send method from Playwright::ChannelOwner, so keep private!
142
146
  def update_object_from_channel_owner(guid, parent)
143
- @objects[guid] = parent
147
+ @objects_mutex.synchronize { @objects[guid] = parent }
144
148
  end
145
149
 
146
150
  # @param guid [String]
147
151
  # @note This method should be used internally. Accessed via .send method from Playwright::ChannelOwner, so keep private!
148
152
  def delete_object_from_channel_owner(guid)
149
- @objects.delete(guid)
153
+ @objects_mutex.synchronize { @objects.delete(guid) }
150
154
  end
151
155
 
152
156
  def dispatch(msg)
@@ -154,7 +158,7 @@ module Playwright
154
158
 
155
159
  id = msg['id']
156
160
  if id
157
- callback = @callbacks.delete(id)
161
+ callback = @callbacks_mutex.synchronize { @callbacks.delete(id) }
158
162
 
159
163
  unless callback
160
164
  raise "Cannot find command to respond: #{id}"
@@ -190,13 +194,13 @@ module Playwright
190
194
  return
191
195
  end
192
196
 
193
- object = @objects[guid]
197
+ object = @objects_mutex.synchronize { @objects[guid] }
194
198
  unless object
195
199
  raise "Cannot find object to \"#{method}\": #{guid}"
196
200
  end
197
201
 
198
202
  if method == "__adopt__"
199
- child = @objects[params["guid"]]
203
+ child = @objects_mutex.synchronize { @objects[params["guid"]] }
200
204
  unless child
201
205
  raise "Unknown new child: #{params['guid']}"
202
206
  end
@@ -243,8 +247,9 @@ module Playwright
243
247
 
244
248
  if payload.is_a?(Hash)
245
249
  guid = payload['guid']
246
- if guid && @objects[guid]
247
- return @objects[guid].channel
250
+ if guid
251
+ object = @objects_mutex.synchronize { @objects[guid] }
252
+ return object.channel if object
248
253
  end
249
254
 
250
255
  return payload.map { |k, v| [k, replace_guids_with_channels(v)] }.to_h
@@ -255,7 +260,7 @@ module Playwright
255
260
 
256
261
  # @return [Playwright::ChannelOwner|nil]
257
262
  def create_remote_object(parent_guid:, type:, guid:, initializer:)
258
- parent = @objects[parent_guid]
263
+ parent = @objects_mutex.synchronize { @objects[parent_guid] }
259
264
  unless parent
260
265
  raise "Cannot find parent object #{parent_guid} to create #{guid}"
261
266
  end
@@ -273,7 +278,7 @@ module Playwright
273
278
  raise "Missing type #{type}"
274
279
  end
275
280
 
276
- callback = @waiting_for_object.delete(guid)
281
+ callback = @objects_mutex.synchronize { @waiting_for_object.delete(guid) }
277
282
  callback&.fulfill(result)
278
283
 
279
284
  result
@@ -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
@@ -1,5 +1,6 @@
1
1
  require_relative './visitor_info'
2
2
  require_relative './regex'
3
+ require 'uri'
3
4
 
4
5
  module Playwright
5
6
  module JavaScript
@@ -60,7 +61,7 @@ module Playwright
60
61
  when Time
61
62
  require 'time'
62
63
  { d: value.utc.iso8601 }
63
- when URI
64
+ when ::URI
64
65
  { u: value.to_s }
65
66
  when Regexp
66
67
  regex_value = Regex.new(value)
@@ -21,7 +21,7 @@ module Playwright
21
21
  private def expect_impl(expression, expect_options, expected, message, title)
22
22
  expect_options[:timeout] ||= @default_expect_timeout
23
23
  expect_options[:isNot] = @is_not
24
- message.gsub!("expected to", "not expected to") if @is_not
24
+ message = message.gsub("expected to", "not expected to") if @is_not
25
25
  expect_options.delete(:useInnerText) if expect_options.key?(:useInnerText) && expect_options[:useInnerText].nil?
26
26
 
27
27
  result = @locator.expect(expression, expect_options, title)
@@ -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)
@@ -22,7 +22,7 @@ module Playwright
22
22
  private def expect_impl(expression, expect_options, expected, message, title)
23
23
  expect_options[:timeout] ||= @default_expect_timeout
24
24
  expect_options[:isNot] = @is_not
25
- message.gsub!("expected to", "not expected to") if @is_not
25
+ message = message.gsub("expected to", "not expected to") if @is_not
26
26
  expect_options.delete(:useInnerText) if expect_options.key?(:useInnerText) && expect_options[:useInnerText].nil?
27
27
 
28
28
  result = @frame.expect(nil, expression, expect_options, title)
@@ -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.57.0'
5
- COMPATIBLE_PLAYWRIGHT_VERSION = '1.57.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
@@ -10,6 +10,7 @@ module Playwright
10
10
  @event = wait_name
11
11
  @channel = channel_owner.channel
12
12
  @registered_listeners = Set.new
13
+ @listeners_mutex = Mutex.new
13
14
  @logs = []
14
15
  wait_for_event_info_before
15
16
  end
@@ -50,8 +51,7 @@ module Playwright
50
51
  end
51
52
  end
52
53
  }
53
- emitter.on(event, listener)
54
- @registered_listeners << [emitter, event, listener]
54
+ register_listener(emitter, event, listener)
55
55
 
56
56
  self
57
57
  end
@@ -69,16 +69,22 @@ module Playwright
69
69
  end
70
70
 
71
71
  private def cleanup
72
- @registered_listeners.each do |emitter, event, listener|
72
+ listeners = @listeners_mutex.synchronize do
73
+ @registered_listeners.to_a.tap { @registered_listeners.clear }
74
+ end
75
+ listeners.each do |emitter, event, listener|
73
76
  emitter.off(event, listener)
74
77
  end
75
- @registered_listeners.clear
76
78
  end
77
79
 
78
80
  def force_fulfill(result)
79
81
  fulfill(result)
80
82
  end
81
83
 
84
+ def force_reject(error)
85
+ reject(error)
86
+ end
87
+
82
88
  private def fulfill(result)
83
89
  cleanup
84
90
  return if @result.resolved?
@@ -107,12 +113,24 @@ module Playwright
107
113
  reject(err)
108
114
  end
109
115
  }
110
- emitter.on(event, listener)
111
- @registered_listeners << [emitter, event, listener]
116
+ register_listener(emitter, event, listener)
112
117
 
113
118
  self
114
119
  end
115
120
 
121
+ private def register_listener(emitter, event, listener)
122
+ emitter.on(event, listener)
123
+ remove_later = false
124
+ @listeners_mutex.synchronize do
125
+ if @result.resolved?
126
+ remove_later = true
127
+ else
128
+ @registered_listeners << [emitter, event, listener]
129
+ end
130
+ end
131
+ emitter.off(event, listener) if remove_later
132
+ end
133
+
116
134
  attr_reader :result
117
135
 
118
136
  def log(message)
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
@@ -194,20 +194,14 @@ module Playwright
194
194
  raise NotImplementedError.new('web_views is not implemented yet.')
195
195
  end
196
196
 
197
- # @nodoc
198
- def tap_on(selector, duration: nil, timeout: nil)
199
- wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
200
- end
201
-
202
197
  # @nodoc
203
198
  def should_close_connection_on_close!
204
199
  wrap_impl(@impl.should_close_connection_on_close!)
205
200
  end
206
201
 
207
- # -- inherited from EventEmitter --
208
202
  # @nodoc
209
- def once(event, callback)
210
- event_emitter_proxy.once(event, callback)
203
+ def tap_on(selector, duration: nil, timeout: nil)
204
+ wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
211
205
  end
212
206
 
213
207
  # -- inherited from EventEmitter --
@@ -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