playwright-ruby-client 1.20.1 → 1.22.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/api_request_context.md +15 -2
  3. data/documentation/docs/api/browser_type.md +1 -1
  4. data/documentation/docs/api/console_message.md +27 -1
  5. data/documentation/docs/api/element_handle.md +23 -8
  6. data/documentation/docs/api/experimental/android.md +1 -1
  7. data/documentation/docs/api/file_chooser.md +1 -1
  8. data/documentation/docs/api/frame.md +12 -5
  9. data/documentation/docs/api/frame_locator.md +1 -1
  10. data/documentation/docs/api/locator.md +32 -8
  11. data/documentation/docs/api/page.md +18 -8
  12. data/documentation/docs/api/route.md +2 -0
  13. data/documentation/docs/include/api_coverage.md +1 -0
  14. data/documentation/package.json +6 -6
  15. data/documentation/yarn.lock +2931 -3220
  16. data/lib/playwright/channel_owners/android.rb +2 -1
  17. data/lib/playwright/channel_owners/android_device.rb +0 -4
  18. data/lib/playwright/channel_owners/browser_context.rb +10 -2
  19. data/lib/playwright/channel_owners/element_handle.rb +12 -3
  20. data/lib/playwright/channel_owners/frame.rb +4 -5
  21. data/lib/playwright/channel_owners/page.rb +12 -8
  22. data/lib/playwright/channel_owners/writable_stream.rb +14 -0
  23. data/lib/playwright/input_files.rb +60 -8
  24. data/lib/playwright/javascript/value_parser.rb +30 -17
  25. data/lib/playwright/javascript/value_serializer.rb +13 -2
  26. data/lib/playwright/javascript/visitor_info.rb +26 -0
  27. data/lib/playwright/locator_impl.rb +15 -0
  28. data/lib/playwright/playwright_api.rb +26 -6
  29. data/lib/playwright/transport.rb +12 -3
  30. data/lib/playwright/version.rb +2 -2
  31. data/lib/playwright_api/accessibility.rb +2 -1
  32. data/lib/playwright_api/android.rb +2 -2
  33. data/lib/playwright_api/android_device.rb +0 -5
  34. data/lib/playwright_api/api_request.rb +3 -3
  35. data/lib/playwright_api/api_request_context.rb +15 -2
  36. data/lib/playwright_api/browser_context.rb +5 -5
  37. data/lib/playwright_api/browser_type.rb +2 -2
  38. data/lib/playwright_api/console_message.rb +20 -1
  39. data/lib/playwright_api/element_handle.rb +53 -38
  40. data/lib/playwright_api/file_chooser.rb +1 -1
  41. data/lib/playwright_api/frame.rb +30 -23
  42. data/lib/playwright_api/frame_locator.rb +1 -1
  43. data/lib/playwright_api/locator.rb +48 -27
  44. data/lib/playwright_api/page.rb +39 -29
  45. data/lib/playwright_api/playwright.rb +1 -1
  46. data/lib/playwright_api/route.rb +2 -0
  47. data/lib/playwright_api/selectors.rb +1 -1
  48. data/lib/playwright_api/tracing.rb +1 -1
  49. data/lib/playwright_api/worker.rb +4 -4
  50. metadata +5 -3
@@ -5,7 +5,8 @@ module Playwright
5
5
  end
6
6
 
7
7
  def devices(port: nil)
8
- resp = @channel.send_message_to_server('devices', port: port)
8
+ params = { port: port }.compact
9
+ resp = @channel.send_message_to_server('devices', params)
9
10
  resp.map { |device| ChannelOwners::AndroidDevice.from(device) }
10
11
  end
11
12
  end
@@ -65,10 +65,6 @@ module Playwright
65
65
  @channel.send_message_to_server('info', selector: to_selector_channel(selector))
66
66
  end
67
67
 
68
- def tree
69
- @channel.send_message_to_server('tree')
70
- end
71
-
72
68
  def screenshot(path: nil)
73
69
  encoded_binary = @channel.send_message_to_server('screenshot')
74
70
  decoded_binary = Base64.strict_decode64(encoded_binary)
@@ -180,7 +180,7 @@ module Playwright
180
180
  else
181
181
  [urls]
182
182
  end
183
- @channel.send_message_to_server('cookies', urls: urls)
183
+ @channel.send_message_to_server('cookies', urls: target_urls)
184
184
  end
185
185
 
186
186
  def add_cookies(cookies)
@@ -226,7 +226,7 @@ module Playwright
226
226
  raise ArgumentError.new('Either path or script parameter must be specified')
227
227
  end
228
228
 
229
- @channel.send_message_to_server('addInitScript', source: script)
229
+ @channel.send_message_to_server('addInitScript', source: source)
230
230
  nil
231
231
  end
232
232
 
@@ -367,5 +367,13 @@ module Playwright
367
367
  private def base_url
368
368
  @options[:baseURL]
369
369
  end
370
+
371
+ # called from InputFiles
372
+ # @param name [string]
373
+ # @return [WritableStream]
374
+ private def create_temp_file(name)
375
+ result = @channel.send_message_to_server('createTempFile', name: name)
376
+ ChannelOwners::WritableStream.from(result)
377
+ end
370
378
  end
371
379
  end
@@ -205,9 +205,14 @@ module Playwright
205
205
  end
206
206
 
207
207
  def set_input_files(files, noWaitAfter: nil, timeout: nil)
208
- file_payloads = InputFiles.new(files).as_params
209
- params = { files: file_payloads, noWaitAfter: noWaitAfter, timeout: timeout }.compact
210
- @channel.send_message_to_server('setInputFiles', params)
208
+ frame = owner_frame
209
+ unless frame
210
+ raise 'Cannot set input files to detached element'
211
+ end
212
+
213
+ method_name, params = InputFiles.new(frame.page.context, files).as_method_and_params
214
+ params.merge!({ noWaitAfter: noWaitAfter, timeout: timeout }.compact)
215
+ @channel.send_message_to_server(method_name, params)
211
216
 
212
217
  nil
213
218
  end
@@ -282,18 +287,22 @@ module Playwright
282
287
 
283
288
  def screenshot(
284
289
  animations: nil,
290
+ caret: nil,
285
291
  mask: nil,
286
292
  omitBackground: nil,
287
293
  path: nil,
288
294
  quality: nil,
295
+ scale: nil,
289
296
  timeout: nil,
290
297
  type: nil)
291
298
 
292
299
  params = {
293
300
  animations: animations,
301
+ caret: caret,
294
302
  omitBackground: omitBackground,
295
303
  path: path,
296
304
  quality: quality,
305
+ scale: scale,
297
306
  timeout: timeout,
298
307
  type: type,
299
308
  }.compact
@@ -487,15 +487,14 @@ module Playwright
487
487
  end
488
488
 
489
489
  def set_input_files(selector, files, noWaitAfter: nil, strict: nil, timeout: nil)
490
- file_payloads = InputFiles.new(files).as_params
491
- params = {
492
- files: file_payloads,
490
+ method_name, params = InputFiles.new(page.context, files).as_method_and_params
491
+ params.merge!({
493
492
  selector: selector,
494
493
  noWaitAfter: noWaitAfter,
495
494
  strict: strict,
496
495
  timeout: timeout,
497
- }.compact
498
- @channel.send_message_to_server('setInputFiles', params)
496
+ }.compact)
497
+ @channel.send_message_to_server(method_name, params)
499
498
 
500
499
  nil
501
500
  end
@@ -386,7 +386,7 @@ module Playwright
386
386
  raise ArgumentError.new('Either path or script parameter must be specified')
387
387
  end
388
388
 
389
- @channel.send_message_to_server('addInitScript', source: script)
389
+ @channel.send_message_to_server('addInitScript', source: source)
390
390
  nil
391
391
  end
392
392
 
@@ -408,15 +408,17 @@ module Playwright
408
408
  end
409
409
 
410
410
  def screenshot(
411
- path: nil,
412
- type: nil,
413
- quality: nil,
414
- fullPage: nil,
415
- clip: nil,
416
- omitBackground: nil,
417
411
  animations: nil,
412
+ caret: nil,
413
+ clip: nil,
414
+ fullPage: nil,
418
415
  mask: nil,
419
- timeout: nil)
416
+ omitBackground: nil,
417
+ path: nil,
418
+ quality: nil,
419
+ scale: nil,
420
+ timeout: nil,
421
+ type: nil)
420
422
 
421
423
  params = {
422
424
  type: type,
@@ -425,6 +427,8 @@ module Playwright
425
427
  clip: clip,
426
428
  omitBackground: omitBackground,
427
429
  animations: animations,
430
+ caret: caret,
431
+ scale: scale,
428
432
  timeout: timeout,
429
433
  }.compact
430
434
  if mask.is_a?(Enumerable)
@@ -0,0 +1,14 @@
1
+ require 'base64'
2
+
3
+ module Playwright
4
+ define_channel_owner :WritableStream do
5
+ # @param readable [File|IO]
6
+ def write(readable, bufsize = 1048576)
7
+ while buf = readable.read(bufsize)
8
+ binary = Base64.strict_encode64(buf)
9
+ @channel.send_message_to_server('write', binary: binary)
10
+ end
11
+ @channel.send_message_to_server('close')
12
+ end
13
+ end
14
+ end
@@ -2,18 +2,64 @@ require 'base64'
2
2
 
3
3
  module Playwright
4
4
  class InputFiles
5
- def initialize(files)
6
- @params = convert(files)
5
+ def initialize(context, files)
6
+ @context = context
7
+ if files.is_a?(Enumerable)
8
+ @files = files
9
+ else
10
+ @files = [files]
11
+ end
7
12
  end
8
13
 
9
- def as_params
10
- @params
14
+ def as_method_and_params
15
+ if has_large_file?
16
+ ['setInputFilePaths', params_for_set_input_file_paths]
17
+ else
18
+ ['setInputFiles', params_for_set_input_files]
19
+ end
11
20
  end
12
21
 
13
- private def convert(files)
14
- return convert([files]) unless files.is_a?(Array)
22
+ private def has_large_file?
23
+ max_bufsize = 1024 * 1024 # 1MB
15
24
 
16
- files.map do |file|
25
+ @files.any? do |file|
26
+ case file
27
+ when String
28
+ File::Stat.new(file).size > max_bufsize
29
+ when File
30
+ file.stat.size > max_bufsize
31
+ else
32
+ raise_argument_error
33
+ end
34
+ end
35
+ end
36
+
37
+ private def params_for_set_input_file_paths
38
+ writable_streams = @files.map do |file|
39
+ case file
40
+ when String
41
+ writable_stream = @context.send(:create_temp_file, File.basename(file))
42
+
43
+ File.open(file, 'rb') do |file|
44
+ writable_stream.write(file)
45
+ end
46
+
47
+ writable_stream.channel
48
+ when File
49
+ writable_stream = @context.send(:create_temp_file, File.basename(file.path))
50
+ writable_stream.write(file)
51
+
52
+ writable_stream.channel
53
+ else
54
+ raise_argument_error
55
+ end
56
+ end
57
+
58
+ { streams: writable_streams }
59
+ end
60
+
61
+ private def params_for_set_input_files
62
+ file_payloads = @files.map do |file|
17
63
  case file
18
64
  when String
19
65
  {
@@ -26,9 +72,15 @@ module Playwright
26
72
  buffer: Base64.strict_encode64(file.read),
27
73
  }
28
74
  else
29
- raise ArgumentError.new('file must be a String or File.')
75
+ raise_argument_error
30
76
  end
31
77
  end
78
+
79
+ { files: file_payloads }
80
+ end
81
+
82
+ private def raise_argument_error
83
+ raise ArgumentError.new('file must be a String or File.')
32
84
  end
33
85
  end
34
86
  end
@@ -5,6 +5,7 @@ module Playwright
5
5
  class ValueParser
6
6
  def initialize(hash)
7
7
  @hash = hash
8
+ @refs = {}
8
9
  end
9
10
 
10
11
  # @return [Hash]
@@ -23,22 +24,24 @@ module Playwright
23
24
  return hash[key] if hash.key?(key)
24
25
  end
25
26
 
27
+ if hash.key?('ref')
28
+ return @refs[hash['ref']]
29
+ end
30
+
26
31
  if hash.key?('v')
27
- return
28
- case hash['v']
29
- when 'undefined'
30
- nil
31
- when 'null'
32
- nil
33
- when 'NaN'
34
- Float::NAN
35
- when 'Infinity'
36
- Float::INFINITY
37
- when '-Infinity'
38
- -Float::INFINITY
39
- when '-0'
40
- -0
41
- end
32
+ return case hash['v']
33
+ when 'undefined'
34
+ nil
35
+ when 'null'
36
+ nil
37
+ when 'NaN'
38
+ Float::NAN
39
+ when 'Infinity'
40
+ Float::INFINITY
41
+ when '-Infinity'
42
+ -Float::INFINITY when '-0'
43
+ -0
44
+ end
42
45
  end
43
46
 
44
47
  if hash.key?('d')
@@ -57,11 +60,21 @@ module Playwright
57
60
  end
58
61
 
59
62
  if hash.key?('a')
60
- return hash['a'].map { |value| parse_hash(value) }
63
+ result = []
64
+ if hash['id']
65
+ @refs[hash['id']] = result
66
+ end
67
+ hash['a'].each { |value| result << parse_hash(value) }
68
+ return result
61
69
  end
62
70
 
63
71
  if hash.key?('o')
64
- return hash['o'].map { |obj| [obj['k'], parse_hash(obj['v'])] }.to_h
72
+ result = {}
73
+ if hash['id']
74
+ @refs[hash['id']] = result
75
+ end
76
+ hash['o'].each { |obj| result[obj['k']] = parse_hash(obj['v']) }
77
+ return result
65
78
  end
66
79
 
67
80
  if hash.key?('h')
@@ -1,8 +1,11 @@
1
+ require_relative './visitor_info'
2
+
1
3
  module Playwright
2
4
  module JavaScript
3
5
  class ValueSerializer
4
6
  def initialize(ruby_value)
5
7
  @value = ruby_value
8
+ @visited = VisitorInfo.new
6
9
  end
7
10
 
8
11
  # @return [Hash]
@@ -41,10 +44,18 @@ module Playwright
41
44
  flags << 'ms' if (value.options & Regexp::MULTILINE) != 0
42
45
  flags << 'i' if (value.options & Regexp::IGNORECASE) != 0
43
46
  { r: { p: value.source, f: flags.join('') } }
47
+ when -> (value) { @visited.ref(value) }
48
+ { ref: @visited.ref(value) }
44
49
  when Array
45
- { a: value.map { |v| serialize_value(v) } }
50
+ id = @visited.log(value)
51
+ result = []
52
+ value.each { |v| result << serialize_value(v) }
53
+ { a: result, id: id }
46
54
  when Hash
47
- { o: value.map { |key, v| { k: key, v: serialize_value(v) } } }
55
+ id = @visited.log(value)
56
+ result = []
57
+ value.each { |key, v| result << { k: key, v: serialize_value(v) } }
58
+ { o: result, id: id }
48
59
  else
49
60
  raise ArgumentError.new("Unexpected value: #{value}")
50
61
  end
@@ -0,0 +1,26 @@
1
+ module Playwright
2
+ module JavaScript
3
+ class VisitorInfo
4
+ def initialize
5
+ @data = {}
6
+ @last_id = 0
7
+ end
8
+
9
+ # returns [Integer|nil]
10
+ def ref(object)
11
+ @data[object]
12
+ end
13
+
14
+ def log(object)
15
+ if @data[object]
16
+ raise ArgumentError.new("Already visited")
17
+ end
18
+
19
+ id = @last_id + 1
20
+ @last_id = id # FIXME: should thread-safe
21
+
22
+ @data[object] = id
23
+ end
24
+ end
25
+ end
26
+ end
@@ -239,6 +239,16 @@ module Playwright
239
239
  @frame.query_selector_all(@selector)
240
240
  end
241
241
 
242
+ def filter(has: nil, hasText: nil)
243
+ LocatorImpl.new(
244
+ frame: @frame,
245
+ timeout_settings: @timeout_settings,
246
+ selector: @selector,
247
+ hasText: hasText,
248
+ has: has,
249
+ )
250
+ end
251
+
242
252
  def first
243
253
  LocatorImpl.new(
244
254
  frame: @frame,
@@ -314,19 +324,24 @@ module Playwright
314
324
 
315
325
  def screenshot(
316
326
  animations: nil,
327
+ caret: nil,
317
328
  mask: nil,
318
329
  omitBackground: nil,
319
330
  path: nil,
320
331
  quality: nil,
332
+ scale: nil,
321
333
  timeout: nil,
322
334
  type: nil)
335
+
323
336
  with_element(timeout: timeout) do |handle, options|
324
337
  handle.screenshot(
325
338
  animations: animations,
339
+ caret: caret,
326
340
  mask: mask,
327
341
  omitBackground: omitBackground,
328
342
  path: path,
329
343
  quality: quality,
344
+ scale: scale,
330
345
  timeout: options[:timeout],
331
346
  type: type)
332
347
  end
@@ -122,21 +122,41 @@ module Playwright
122
122
  }
123
123
  end
124
124
 
125
- private def wrap_impl(object)
125
+ private def wrap_impl(object, visited: {})
126
126
  if object.is_a?(Array)
127
- object.map { |obj| wrap_impl(obj) }
127
+ unless visited[object]
128
+ visited[object] = []
129
+ object.each { |obj| visited[object] << wrap_impl(obj) }
130
+ end
131
+ visited[object]
128
132
  elsif object.is_a?(Hash)
129
- object.map { |key, obj| [key, wrap_impl(obj)] }.to_h
133
+ unless visited[object]
134
+ visited[object] = {}
135
+ object.each do |key, obj|
136
+ visited[object][key] = wrap_impl(obj, visited: visited)
137
+ end
138
+ end
139
+ visited[object]
130
140
  else
131
141
  ::Playwright::PlaywrightApi.wrap(object)
132
142
  end
133
143
  end
134
144
 
135
- private def unwrap_impl(object)
145
+ private def unwrap_impl(object, visited: {})
136
146
  if object.is_a?(Array)
137
- object.map { |obj| unwrap_impl(obj) }
147
+ unless visited[object]
148
+ visited[object] = []
149
+ object.each { |obj| visited[object] << unwrap_impl(obj) }
150
+ end
151
+ visited[object]
138
152
  elsif object.is_a?(Hash)
139
- object.map { |key, obj| [key, unwrap_impl(obj)] }.to_h
153
+ unless visited[object]
154
+ visited[object] = {}
155
+ object.each do |key, obj|
156
+ visited[object][key] = unwrap_impl(obj, visited: visited)
157
+ end
158
+ end
159
+ visited[object]
140
160
  elsif object.is_a?(PlaywrightApi)
141
161
  ::Playwright::PlaywrightApi.unwrap(object)
142
162
  else
@@ -46,7 +46,6 @@ module Playwright
46
46
  #
47
47
  # @note This method blocks until playwright-cli exited. Consider using Thread or Future.
48
48
  def async_run
49
- popen3_args = {}
50
49
  @stdin, @stdout, @stderr, @thread = run_driver_with_open3
51
50
  @stdin.binmode # Ensure Strings are written 1:1 without encoding conversion, necessary for integer values
52
51
 
@@ -111,12 +110,22 @@ module Playwright
111
110
 
112
111
  def debug_send_message(message)
113
112
  metadata = message.delete(:metadata)
114
- puts "\x1b[33mSEND>\x1b[0m#{message}"
113
+ puts "\x1b[33mSEND>\x1b[0m#{shorten_double_quoted_string(message)}"
115
114
  message[:metadata] = metadata
116
115
  end
117
116
 
118
117
  def debug_recv_message(message)
119
- puts "\x1b[33mRECV>\x1b[0m#{message}"
118
+ puts "\x1b[33mRECV>\x1b[0m#{shorten_double_quoted_string(message)}"
119
+ end
120
+
121
+ def shorten_double_quoted_string(message, maxlen: 512)
122
+ message.to_s.gsub(/"([^"]+)"/) do |str|
123
+ if $1.length > maxlen
124
+ "\"#{$1[0...maxlen]}...\""
125
+ else
126
+ str
127
+ end
128
+ end
120
129
  end
121
130
  end
122
131
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playwright
4
- VERSION = '1.20.1'
5
- COMPATIBLE_PLAYWRIGHT_VERSION = '1.20.1'
4
+ VERSION = '1.22.0'
5
+ COMPATIBLE_PLAYWRIGHT_VERSION = '1.22.1'
6
6
  end
@@ -35,7 +35,8 @@ module Playwright
35
35
  # return node
36
36
  # for child in (node.get("children") or []):
37
37
  # found_node = find_focused_node(child)
38
- # return found_node
38
+ # if (found_node)
39
+ # return found_node
39
40
  # return None
40
41
  #
41
42
  # snapshot = page.accessibility.snapshot()
@@ -26,8 +26,8 @@ module Playwright
26
26
  class Android < PlaywrightApi
27
27
 
28
28
  # Returns the list of detected Android devices.
29
- def devices(port: nil)
30
- wrap_impl(@impl.devices(port: unwrap_impl(port)))
29
+ def devices(host: nil, omitDriverInstall: nil, port: nil)
30
+ wrap_impl(@impl.devices(host: unwrap_impl(host), omitDriverInstall: unwrap_impl(omitDriverInstall), port: unwrap_impl(port)))
31
31
  end
32
32
 
33
33
  # This setting will change the default maximum time for all the methods accepting `timeout` option.
@@ -169,11 +169,6 @@ module Playwright
169
169
  wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
170
170
  end
171
171
 
172
- # @nodoc
173
- def tree
174
- wrap_impl(@impl.tree)
175
- end
176
-
177
172
  # -- inherited from EventEmitter --
178
173
  # @nodoc
179
174
  def off(event, callback)
@@ -1,7 +1,7 @@
1
1
  module Playwright
2
- # Exposes API that can be used for the Web API testing. Each Playwright browser context has a APIRequestContext instance
3
- # attached which shares cookies with the page context. Its also possible to create a new APIRequestContext instance
4
- # manually. For more information see [here](./class-apirequestcontext).
2
+ # Exposes API that can be used for the Web API testing. This class is used for creating `APIRequestContext` instance which
3
+ # in turn can be used for sending web requests. An instance of this class can be obtained via
4
+ # [`property: Playwright.request`]. For more information see `APIRequestContext`.
5
5
  class APIRequest < PlaywrightApi
6
6
 
7
7
  # Creates new instances of `APIRequestContext`.
@@ -1,9 +1,22 @@
1
1
  module Playwright
2
2
  # This API is used for the Web API testing. You can use it to trigger API endpoints, configure micro-services, prepare
3
- # environment or the service to your e2e test. When used on `Page` or a `BrowserContext`, this API will automatically use
4
- # the cookies from the corresponding `BrowserContext`. This means that if you log in using this API, your e2e test will be
3
+ # environment or the service to your e2e test.
4
+ #
5
+ # Each Playwright browser context has associated with it `APIRequestContext` instance which shares cookie storage with the
6
+ # browser context and can be accessed via [`property: BrowserContext.request`] or [`property: Page.request`]. It is also
7
+ # possible to create a new APIRequestContext instance manually by calling [`method: APIRequest.newContext`].
8
+ #
9
+ # **Cookie management**
10
+ #
11
+ # `APIRequestContext` retuned by [`property: BrowserContext.request`] and [`property: Page.request`] shares cookie storage
12
+ # with the corresponding `BrowserContext`. Each API request will have `Cookie` header populated with the values from the
13
+ # browser context. If the API response contains `Set-Cookie` header it will automatically update `BrowserContext` cookies
14
+ # and requests made from the page will pick them up. This means that if you log in using this API, your e2e test will be
5
15
  # logged in and vice versa.
6
16
  #
17
+ # If you want API requests to not interfere with the browser cookies you shoud create a new `APIRequestContext` by calling
18
+ # [`method: APIRequest.newContext`]. Such `APIRequestContext` object will have its own isolated cookie storage.
19
+ #
7
20
  # ```python sync
8
21
  # import os
9
22
  # from playwright.sync_api import sync_playwright
@@ -371,6 +371,11 @@ module Playwright
371
371
  raise NotImplementedError.new('wait_for_event is not implemented yet.')
372
372
  end
373
373
 
374
+ # @nodoc
375
+ def options=(req)
376
+ wrap_impl(@impl.options=(unwrap_impl(req)))
377
+ end
378
+
374
379
  # @nodoc
375
380
  def pause
376
381
  wrap_impl(@impl.pause)
@@ -391,11 +396,6 @@ module Playwright
391
396
  wrap_impl(@impl.owner_page=(unwrap_impl(req)))
392
397
  end
393
398
 
394
- # @nodoc
395
- def options=(req)
396
- wrap_impl(@impl.options=(unwrap_impl(req)))
397
- end
398
-
399
399
  # -- inherited from EventEmitter --
400
400
  # @nodoc
401
401
  def off(event, callback)
@@ -18,12 +18,12 @@ module Playwright
18
18
  # ```
19
19
  class BrowserType < PlaywrightApi
20
20
 
21
- # This methods attaches Playwright to an existing browser instance.
21
+ # This method attaches Playwright to an existing browser instance.
22
22
  def connect(wsEndpoint, headers: nil, slowMo: nil, timeout: nil)
23
23
  raise NotImplementedError.new('connect is not implemented yet.')
24
24
  end
25
25
 
26
- # This methods attaches Playwright to an existing browser instance using the Chrome DevTools Protocol.
26
+ # This method attaches Playwright to an existing browser instance using the Chrome DevTools Protocol.
27
27
  #
28
28
  # The default browser context is accessible via [`method: Browser.contexts`].
29
29
  #
@@ -1,5 +1,24 @@
1
1
  module Playwright
2
- # `ConsoleMessage` objects are dispatched by page via the [`event: Page.console`] event.
2
+ # `ConsoleMessage` objects are dispatched by page via the [`event: Page.console`] event. For each console messages logged
3
+ # in the page there will be corresponding event in the Playwright context.
4
+ #
5
+ # ```python sync
6
+ # # Listen for all console logs
7
+ # page.on("console", lambda msg: print(msg.text))
8
+ #
9
+ # # Listen for all console events and handle errors
10
+ # page.on("console", lambda msg: print(f"error: {msg.text}") if msg.type == "error" else None)
11
+ #
12
+ # # Get the next console log
13
+ # with page.expect_console_message() as msg_info:
14
+ # # Issue console.log inside the page
15
+ # page.evaluate("console.log('hello', 42, { foo: 'bar' })")
16
+ # msg = msg_info.value
17
+ #
18
+ # # Deconstruct print arguments
19
+ # msg.args[0].json_value() # hello
20
+ # msg.args[1].json_value() # 42
21
+ # ```
3
22
  class ConsoleMessage < PlaywrightApi
4
23
 
5
24
  # List of arguments passed to a `console` function call. See also [`event: Page.console`].