playwright-ruby-client 0.0.8 → 0.3.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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/docs/api_coverage.md +159 -101
  4. data/lib/playwright.rb +5 -2
  5. data/lib/playwright/{input_types/android_input.rb → android_input_impl.rb} +5 -1
  6. data/lib/playwright/api_implementation.rb +18 -0
  7. data/lib/playwright/channel.rb +13 -6
  8. data/lib/playwright/channel_owner.rb +3 -5
  9. data/lib/playwright/channel_owners/android.rb +1 -1
  10. data/lib/playwright/channel_owners/android_device.rb +12 -12
  11. data/lib/playwright/channel_owners/binding_call.rb +3 -0
  12. data/lib/playwright/channel_owners/browser.rb +1 -1
  13. data/lib/playwright/channel_owners/browser_context.rb +157 -3
  14. data/lib/playwright/channel_owners/dialog.rb +28 -0
  15. data/lib/playwright/channel_owners/download.rb +27 -0
  16. data/lib/playwright/channel_owners/element_handle.rb +15 -4
  17. data/lib/playwright/channel_owners/frame.rb +24 -5
  18. data/lib/playwright/channel_owners/js_handle.rb +1 -1
  19. data/lib/playwright/channel_owners/page.rb +367 -29
  20. data/lib/playwright/channel_owners/playwright.rb +4 -0
  21. data/lib/playwright/channel_owners/request.rb +35 -3
  22. data/lib/playwright/channel_owners/response.rb +60 -0
  23. data/lib/playwright/channel_owners/route.rb +78 -0
  24. data/lib/playwright/channel_owners/selectors.rb +19 -1
  25. data/lib/playwright/errors.rb +1 -1
  26. data/lib/playwright/event_emitter.rb +8 -1
  27. data/lib/playwright/event_emitter_proxy.rb +49 -0
  28. data/lib/playwright/file_chooser_impl.rb +23 -0
  29. data/lib/playwright/http_headers.rb +20 -0
  30. data/lib/playwright/input_files.rb +1 -1
  31. data/lib/playwright/{input_types/keyboard.rb → keyboard_impl.rb} +5 -1
  32. data/lib/playwright/mouse_impl.rb +7 -0
  33. data/lib/playwright/playwright_api.rb +59 -20
  34. data/lib/playwright/route_handler_entry.rb +36 -0
  35. data/lib/playwright/select_option_values.rb +14 -4
  36. data/lib/playwright/touchscreen_impl.rb +7 -0
  37. data/lib/playwright/utils.rb +4 -3
  38. data/lib/playwright/version.rb +1 -1
  39. data/lib/playwright/wait_helper.rb +1 -1
  40. data/lib/playwright_api/android.rb +82 -11
  41. data/lib/playwright_api/android_device.rb +148 -32
  42. data/lib/playwright_api/android_input.rb +17 -13
  43. data/lib/playwright_api/android_socket.rb +16 -0
  44. data/lib/playwright_api/android_web_view.rb +21 -0
  45. data/lib/playwright_api/binding_call.rb +14 -5
  46. data/lib/playwright_api/browser.rb +22 -23
  47. data/lib/playwright_api/browser_context.rb +49 -35
  48. data/lib/playwright_api/browser_type.rb +24 -64
  49. data/lib/playwright_api/chromium_browser_context.rb +10 -8
  50. data/lib/playwright_api/console_message.rb +10 -6
  51. data/lib/playwright_api/dialog.rb +37 -6
  52. data/lib/playwright_api/download.rb +28 -11
  53. data/lib/playwright_api/element_handle.rb +107 -96
  54. data/lib/playwright_api/file_chooser.rb +18 -10
  55. data/lib/playwright_api/frame.rb +124 -117
  56. data/lib/playwright_api/js_handle.rb +20 -22
  57. data/lib/playwright_api/keyboard.rb +5 -5
  58. data/lib/playwright_api/page.rb +206 -148
  59. data/lib/playwright_api/playwright.rb +33 -45
  60. data/lib/playwright_api/request.rb +11 -12
  61. data/lib/playwright_api/response.rb +30 -16
  62. data/lib/playwright_api/route.rb +27 -5
  63. data/lib/playwright_api/selectors.rb +14 -10
  64. data/lib/playwright_api/web_socket.rb +10 -1
  65. data/lib/playwright_api/worker.rb +13 -13
  66. metadata +16 -7
  67. data/lib/playwright/input_type.rb +0 -19
  68. data/lib/playwright/input_types/mouse.rb +0 -4
  69. data/lib/playwright/input_types/touchscreen.rb +0 -4
@@ -1,7 +1,7 @@
1
1
  module Playwright
2
2
  # @ref https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_frame.py
3
3
  define_channel_owner :Frame do
4
- def after_initialize
4
+ private def after_initialize
5
5
  if @initializer['parentFrame']
6
6
  @parent_frame = ChannelOwners::Frame.from(@initializer['parentFrame'])
7
7
  @parent_frame.send(:append_child_frame_from_child, self)
@@ -144,6 +144,13 @@ module Playwright
144
144
  end
145
145
  end
146
146
 
147
+ def wait_for_selector(selector, state: nil, timeout: nil)
148
+ params = { selector: selector, state: state, timeout: timeout }.compact
149
+ resp = @channel.send_message_to_server('waitForSelector', params)
150
+
151
+ ChannelOwners::ElementHandle.from_nullable(resp)
152
+ end
153
+
147
154
  def checked?(selector, timeout: nil)
148
155
  params = { selector: selector, timeout: timeout }.compact
149
156
  @channel.send_message_to_server('isChecked', params)
@@ -391,8 +398,20 @@ module Playwright
391
398
  nil
392
399
  end
393
400
 
394
- def select_option(selector, values, noWaitAfter: nil, timeout: nil)
395
- base_params = SelectOptionValues.new(values).as_params
401
+ def select_option(
402
+ selector,
403
+ element: nil,
404
+ index: nil,
405
+ value: nil,
406
+ label: nil,
407
+ noWaitAfter: nil,
408
+ timeout: nil)
409
+ base_params = SelectOptionValues.new(
410
+ element: element,
411
+ index: index,
412
+ value: value,
413
+ label: label,
414
+ ).as_params
396
415
  params = base_params + { selector: selector, noWaitAfter: noWaitAfter, timeout: timeout }.compact
397
416
  @channel.send_message_to_server('selectOption', params)
398
417
 
@@ -400,8 +419,8 @@ module Playwright
400
419
  end
401
420
 
402
421
  def set_input_files(selector, files, noWaitAfter: nil, timeout: nil)
403
- base_params = InputFiles.new(values).as_params
404
- params = base_params + { selector: selector, noWaitAfter: noWaitAfter, timeout: timeout }.compact
422
+ file_payloads = InputFiles.new(files).as_params
423
+ params = { files: file_payloads, selector: selector, noWaitAfter: noWaitAfter, timeout: timeout }.compact
405
424
  @channel.send_message_to_server('setInputFiles', params)
406
425
 
407
426
  nil
@@ -1,6 +1,6 @@
1
1
  module Playwright
2
2
  define_channel_owner :JSHandle do
3
- def after_initialize
3
+ private def after_initialize
4
4
  @preview = @initializer['preview']
5
5
  @channel.on('previewUpdated', method(:on_preview_updated))
6
6
  end
@@ -6,16 +6,24 @@ module Playwright
6
6
  include Utils::Errors::SafeCloseError
7
7
  attr_writer :owned_context
8
8
 
9
- def after_initialize
9
+ private def after_initialize
10
10
  @browser_context = @parent
11
11
  @timeout_settings = TimeoutSettings.new(@browser_context.send(:_timeout_settings))
12
12
  @accessibility = Accessibility.new(@channel)
13
- @keyboard = InputTypes::Keyboard.new(@channel)
14
- @mouse = InputTypes::Mouse.new(@channel)
15
- @touchscreen = InputTypes::Touchscreen.new(@channel)
16
-
17
- @viewport_size = @initializer['viewportSize']
13
+ @keyboard = KeyboardImpl.new(@channel)
14
+ @mouse = MouseImpl.new(@channel)
15
+ @touchscreen = TouchscreenImpl.new(@channel)
16
+
17
+ if @initializer['viewportSize']
18
+ @viewport_size = {
19
+ width: @initializer['viewportSize']['width'],
20
+ height: @initializer['viewportSize']['height'],
21
+ }
22
+ end
18
23
  @closed = false
24
+ @bindings = {}
25
+ @routes = Set.new
26
+
19
27
  @main_frame = ChannelOwners::Frame.from(@initializer['mainFrame'])
20
28
  @main_frame.send(:update_page_from_page, self)
21
29
  @frames = Set.new
@@ -26,7 +34,19 @@ module Playwright
26
34
  console_message = ChannelOwners::ConsoleMessage.from(params['message'])
27
35
  emit(Events::Page::Console, console_message)
28
36
  })
37
+ @channel.on('crash', ->(_) { emit(Events::Page::Crash) })
38
+ @channel.on('dialog', method(:on_dialog))
29
39
  @channel.on('domcontentloaded', ->(_) { emit(Events::Page::DOMContentLoaded) })
40
+ @channel.on('download', ->(params) {
41
+ emit(Events::Page::Download, ChannelOwners::Download.from(params['download']))
42
+ })
43
+ @channel.on('fileChooser', ->(params) {
44
+ chooser = FileChooserImpl.new(
45
+ page: self,
46
+ element_handle: ChannelOwners::ElementHandle.from(params['element']),
47
+ is_multiple: params['isMultiple'])
48
+ emit(Events::Page::FileChooser, chooser)
49
+ })
30
50
  @channel.on('frameAttached', ->(params) {
31
51
  on_frame_attached(ChannelOwners::Frame.from(params['frame']))
32
52
  })
@@ -34,9 +54,43 @@ module Playwright
34
54
  on_frame_detached(ChannelOwners::Frame.from(params['frame']))
35
55
  })
36
56
  @channel.on('load', ->(_) { emit(Events::Page::Load) })
57
+ @channel.on('pageError', ->(params) {
58
+ emit(Events::Page::PageError, Error.parse(params['error']['error']))
59
+ })
37
60
  @channel.on('popup', ->(params) {
38
61
  emit(Events::Page::Popup, ChannelOwners::Page.from(params['page']))
39
62
  })
63
+ @channel.on('request', ->(params) {
64
+ emit(Events::Page::Request, ChannelOwners::Request.from(params['request']))
65
+ })
66
+ @channel.on('requestFailed', ->(params) {
67
+ on_request_failed(
68
+ ChannelOwners::Request.from(params['request']),
69
+ params['responseEndTiming'],
70
+ params['failureText'],
71
+ )
72
+ })
73
+ @channel.on('requestFinished', ->(params) {
74
+ on_request_finished(
75
+ ChannelOwners::Request.from(params['request']),
76
+ params['responseEndTiming'],
77
+ )
78
+ })
79
+ @channel.on('response', ->(params) {
80
+ emit(Events::Page::Response, ChannelOwners::Response.from(params['response']))
81
+ })
82
+ @channel.on('route', ->(params) {
83
+ on_route(ChannelOwners::Route.from(params['route']), ChannelOwners::Request.from(params['request']))
84
+ })
85
+ @channel.on('video', ->(params) {
86
+ video.send(:update_relative_path, params['relativePath'])
87
+ })
88
+ @channel.on('webSocket', ->(params) {
89
+ emit(Events::Page::WebSocket, ChannelOwners::WebSocket.from(params['webSocket']))
90
+ })
91
+ @channel.on('worker', ->(params) {
92
+ on_worker(ChannelOwners::Worker.from(params['worker']))
93
+ })
40
94
  end
41
95
 
42
96
  attr_reader \
@@ -47,6 +101,17 @@ module Playwright
47
101
  :viewport_size,
48
102
  :main_frame
49
103
 
104
+ private def on_request_failed(request, response_end_timing, failure_text)
105
+ request.send(:update_failure_text, failure_text)
106
+ request.send(:update_response_end_timing, response_end_timing)
107
+ emit(Events::Page::RequestFailed, request)
108
+ end
109
+
110
+ private def on_request_finished(request, response_end_timing)
111
+ request.send(:update_response_end_timing, response_end_timing)
112
+ emit(Events::Page::RequestFinished, request)
113
+ end
114
+
50
115
  private def on_frame_attached(frame)
51
116
  frame.send(:update_page_from_page, self)
52
117
  @frames << frame
@@ -59,12 +124,55 @@ module Playwright
59
124
  emit(Events::Page::FrameDetached, frame)
60
125
  end
61
126
 
127
+ private def on_route(route, request)
128
+ # It is not desired to use PlaywrightApi.wrap directly.
129
+ # However it is a little difficult to define wrapper for `handler` parameter in generate_api.
130
+ # Just a workaround...
131
+ wrapped_route = PlaywrightApi.wrap(route)
132
+ wrapped_request = PlaywrightApi.wrap(request)
133
+
134
+ if @routes.none? { |handler_entry| handler_entry.handle(wrapped_route, wrapped_request) }
135
+ @browser_context.send(:on_route, route, request)
136
+ end
137
+ end
138
+
62
139
  private def on_close
63
140
  @closed = true
64
141
  @browser_context.send(:remove_page, self)
65
142
  emit(Events::Page::Close)
66
143
  end
67
144
 
145
+ private def on_dialog(params)
146
+ dialog = ChannelOwners::Dialog.from(params['dialog'])
147
+ unless emit(Events::Page::Dialog, dialog)
148
+ dialog.dismiss
149
+ end
150
+ end
151
+
152
+ # @override
153
+ def on(event, callback)
154
+ if event == Events::Page::FileChooser && listener_count(event) == 0
155
+ @channel.async_send_message_to_server('setFileChooserInterceptedNoReply', intercepted: true)
156
+ end
157
+ super
158
+ end
159
+
160
+ # @override
161
+ def once(event, callback)
162
+ if event == Events::Page::FileChooser && listener_count(event) == 0
163
+ @channel.async_send_message_to_server('setFileChooserInterceptedNoReply', intercepted: true)
164
+ end
165
+ super
166
+ end
167
+
168
+ # @override
169
+ def off(event, callback)
170
+ super
171
+ if event == Events::Page::FileChooser && listener_count(event) == 0
172
+ @channel.async_send_message_to_server('setFileChooserInterceptedNoReply', intercepted: false)
173
+ end
174
+ end
175
+
68
176
  def context
69
177
  @browser_context
70
178
  end
@@ -74,14 +182,7 @@ module Playwright
74
182
  ChannelOwners::Page.from(resp)
75
183
  end
76
184
 
77
- def frame(frameSelector)
78
- name, url =
79
- if frameSelector.is_a?(Hash)
80
- [frameSelector[:name], frameSelector[:url]]
81
- else
82
- [frameSelector, nil]
83
- end
84
-
185
+ def frame(name: nil, url: nil)
85
186
  if name
86
187
  @frames.find { |f| f.name == name }
87
188
  elsif url
@@ -121,6 +222,38 @@ module Playwright
121
222
  @main_frame.query_selector_all(selector)
122
223
  end
123
224
 
225
+ def wait_for_selector(selector, state: nil, timeout: nil)
226
+ @main_frame.wait_for_selector(selector, state: state, timeout: timeout)
227
+ end
228
+
229
+ def checked?(selector, timeout: nil)
230
+ @main_frame.checked?(selector, timeout: timeout)
231
+ end
232
+
233
+ def disabled?(selector, timeout: nil)
234
+ @main_frame.disabled?(selector, timeout: timeout)
235
+ end
236
+
237
+ def editable?(selector, timeout: nil)
238
+ @main_frame.editable?(selector, timeout: timeout)
239
+ end
240
+
241
+ def enabled?(selector, timeout: nil)
242
+ @main_frame.enabled?(selector, timeout: timeout)
243
+ end
244
+
245
+ def hidden?(selector, timeout: nil)
246
+ @main_frame.hidden?(selector, timeout: timeout)
247
+ end
248
+
249
+ def visible?(selector, timeout: nil)
250
+ @main_frame.visible?(selector, timeout: timeout)
251
+ end
252
+
253
+ def dispatch_event(selector, type, eventInit: nil, timeout: nil)
254
+ @main_frame.dispatch_event(selector, type, eventInit: eventInit, timeout: timeout)
255
+ end
256
+
124
257
  def evaluate(pageFunction, arg: nil)
125
258
  @main_frame.evaluate(pageFunction, arg: arg)
126
259
  end
@@ -145,6 +278,25 @@ module Playwright
145
278
  @main_frame.add_style_tag(content: content, path: path, url: url)
146
279
  end
147
280
 
281
+ def expose_function(name, callback)
282
+ @channel.send_message_to_server('exposeBinding', name: name)
283
+ @bindings[name] = ->(_source, *args) { callback.call(*args) }
284
+ end
285
+
286
+ def expose_binding(name, callback, handle: nil)
287
+ params = {
288
+ name: name,
289
+ needsHandle: handle,
290
+ }.compact
291
+ @channel.send_message_to_server('exposeBinding', params)
292
+ @bindings[name] = callback
293
+ end
294
+
295
+ def set_extra_http_headers(headers)
296
+ serialized_headers = HttpHeaders.new(headers).as_serialized
297
+ @channel.send_message_to_server('setExtraHTTPHeaders', headers: serialized_headers)
298
+ end
299
+
148
300
  def url
149
301
  @main_frame.url
150
302
  end
@@ -174,12 +326,70 @@ module Playwright
174
326
  @main_frame.wait_for_load_state(state: state, timeout: timeout)
175
327
  end
176
328
 
329
+ def go_back(timeout: nil, waitUntil: nil)
330
+ params = { timeout: timeout, waitUntil: waitUntil }.compact
331
+ resp = @channel.send_message_to_server('goBack', params)
332
+ ChannelOwners::Response.from_nullable(resp)
333
+ end
334
+
335
+ def go_forward(timeout: nil, waitUntil: nil)
336
+ params = { timeout: timeout, waitUntil: waitUntil }.compact
337
+ resp = @channel.send_message_to_server('goForward', params)
338
+ ChannelOwners::Response.from_nullable(resp)
339
+ end
340
+
341
+ def emulate_media(colorScheme: nil, media: nil)
342
+ params = {
343
+ colorScheme: colorScheme,
344
+ media: media,
345
+ }.compact
346
+ @channel.send_message_to_server('emulateMedia', params)
347
+
348
+ nil
349
+ end
350
+
177
351
  def set_viewport_size(viewportSize)
178
352
  @viewport_size = viewportSize
179
353
  @channel.send_message_to_server('setViewportSize', { viewportSize: viewportSize })
180
354
  nil
181
355
  end
182
356
 
357
+ def bring_to_front
358
+ @channel.send_message_to_server('bringToFront')
359
+ nil
360
+ end
361
+
362
+ def add_init_script(path: nil, script: nil)
363
+ source =
364
+ if path
365
+ File.read(path)
366
+ elsif script
367
+ script
368
+ else
369
+ raise ArgumentError.new('Either path or script parameter must be specified')
370
+ end
371
+
372
+ @channel.send_message_to_server('addInitScript', source: script)
373
+ nil
374
+ end
375
+
376
+ def route(url, handler)
377
+ entry = RouteHandlerEntry.new(url, handler)
378
+ @routes << entry
379
+ if @routes.count >= 1
380
+ @channel.send_message_to_server('setNetworkInterceptionEnabled', enabled: true)
381
+ end
382
+ end
383
+
384
+ def unroute(url, handler: nil)
385
+ @routes.reject! do |handler_entry|
386
+ handler_entry.same_value?(url: url, handler: handler)
387
+ end
388
+ if @routes.count == 0
389
+ @channel.send_message_to_server('setNetworkInterceptionEnabled', enabled: false)
390
+ end
391
+ end
392
+
183
393
  def screenshot(
184
394
  path: nil,
185
395
  type: nil,
@@ -269,6 +479,23 @@ module Playwright
269
479
  )
270
480
  end
271
481
 
482
+ def tap_point(
483
+ selector,
484
+ force: nil,
485
+ modifiers: nil,
486
+ noWaitAfter: nil,
487
+ position: nil,
488
+ timeout: nil)
489
+ @main_frame.tap_point(
490
+ selector,
491
+ force: force,
492
+ modifiers: modifiers,
493
+ noWaitAfter: noWaitAfter,
494
+ position: position,
495
+ timeout: timeout,
496
+ )
497
+ end
498
+
272
499
  def fill(selector, value, noWaitAfter: nil, timeout: nil)
273
500
  @main_frame.fill(selector, value, noWaitAfter: noWaitAfter, timeout: timeout)
274
501
  end
@@ -277,6 +504,60 @@ module Playwright
277
504
  @main_frame.focus(selector, timeout: timeout)
278
505
  end
279
506
 
507
+ def text_content(selector, timeout: nil)
508
+ @main_frame.text_content(selector, timeout: timeout)
509
+ end
510
+
511
+ def inner_text(selector, timeout: nil)
512
+ @main_frame.inner_text(selector, timeout: timeout)
513
+ end
514
+
515
+ def inner_html(selector, timeout: nil)
516
+ @main_frame.inner_html(selector, timeout: timeout)
517
+ end
518
+
519
+ def get_attribute(selector, name, timeout: nil)
520
+ @main_frame.get_attribute(selector, name, timeout: timeout)
521
+ end
522
+
523
+ def hover(
524
+ selector,
525
+ force: nil,
526
+ modifiers: nil,
527
+ position: nil,
528
+ timeout: nil)
529
+ @main_frame.hover(
530
+ selector,
531
+ force: force,
532
+ modifiers: modifiers,
533
+ position: position,
534
+ timeout: timeout,
535
+ )
536
+ end
537
+
538
+ def select_option(
539
+ selector,
540
+ element: nil,
541
+ index: nil,
542
+ value: nil,
543
+ label: nil,
544
+ noWaitAfter: nil,
545
+ timeout: nil)
546
+ @main_frame.select_option(
547
+ selector,
548
+ element: element,
549
+ index: index,
550
+ value: value,
551
+ label: label,
552
+ noWaitAfter: noWaitAfter,
553
+ timeout: timeout,
554
+ )
555
+ end
556
+
557
+ def set_input_files(selector, files, noWaitAfter: nil, timeout: nil)
558
+ @main_frame.set_input_files(selector, files, noWaitAfter: noWaitAfter, timeout: timeout)
559
+ end
560
+
280
561
  def type(
281
562
  selector,
282
563
  text,
@@ -297,10 +578,57 @@ module Playwright
297
578
  @main_frame.press(selector, key, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout)
298
579
  end
299
580
 
581
+ def check(selector, force: nil, noWaitAfter: nil, timeout: nil)
582
+ @main_frame.check(selector, force: force, noWaitAfter: noWaitAfter, timeout: timeout)
583
+ end
584
+
585
+ def uncheck(selector, force: nil, noWaitAfter: nil, timeout: nil)
586
+ @main_frame.uncheck(selector, force: force, noWaitAfter: noWaitAfter, timeout: timeout)
587
+ end
588
+
300
589
  def wait_for_function(pageFunction, arg: nil, polling: nil, timeout: nil)
301
590
  @main_frame.wait_for_function(pageFunction, arg: arg, polling: polling, timeout: timeout)
302
591
  end
303
592
 
593
+ def pdf(
594
+ displayHeaderFooter: nil,
595
+ footerTemplate: nil,
596
+ format: nil,
597
+ headerTemplate: nil,
598
+ height: nil,
599
+ landscape: nil,
600
+ margin: nil,
601
+ pageRanges: nil,
602
+ path: nil,
603
+ preferCSSPageSize: nil,
604
+ printBackground: nil,
605
+ scale: nil,
606
+ width: nil)
607
+
608
+ params = {
609
+ displayHeaderFooter: displayHeaderFooter,
610
+ footerTemplate: footerTemplate,
611
+ format: format,
612
+ headerTemplate: headerTemplate,
613
+ height: height,
614
+ landscape: landscape,
615
+ margin: margin,
616
+ pageRanges: pageRanges,
617
+ preferCSSPageSize: preferCSSPageSize,
618
+ printBackground: printBackground,
619
+ scale: scale,
620
+ width: width,
621
+ }.compact
622
+ encoded_binary = @channel.send_message_to_server('pdf', params)
623
+ decoded_binary = Base64.strict_decode64(encoded_binary)
624
+ if path
625
+ File.open(path, 'wb') do |f|
626
+ f.write(decoded_binary)
627
+ end
628
+ end
629
+ decoded_binary
630
+ end
631
+
304
632
  class CrashedError < StandardError
305
633
  def initialize
306
634
  super('Page crashed')
@@ -319,20 +647,9 @@ module Playwright
319
647
  end
320
648
  end
321
649
 
322
- def expect_event(event, optionsOrPredicate: nil, &block)
323
- predicate, timeout =
324
- case optionsOrPredicate
325
- when Proc
326
- [optionsOrPredicate, nil]
327
- when Hash
328
- [optionsOrPredicate[:predicate], optionsOrPredicate[:timeout]]
329
- else
330
- [nil, nil]
331
- end
332
- timeout ||= @timeout_settings.timeout
333
-
650
+ def expect_event(event, predicate: nil, timeout: nil, &block)
334
651
  wait_helper = WaitHelper.new
335
- wait_helper.reject_on_timeout(timeout, "Timeout while waiting for event \"#{event}\"")
652
+ wait_helper.reject_on_timeout(timeout || @timeout_settings.timeout, "Timeout while waiting for event \"#{event}\"")
336
653
 
337
654
  unless event == Events::Page::Crash
338
655
  wait_helper.reject_on_event(self, Events::Page::Crash, CrashedError.new)
@@ -349,6 +666,18 @@ module Playwright
349
666
  wait_helper.promise.value!
350
667
  end
351
668
 
669
+ def expect_console_message(predicate: nil, timeout: nil, &block)
670
+ expect_event(Events::Page::Console, predicate: predicate, timeout: timeout, &block)
671
+ end
672
+
673
+ def expect_download(predicate: nil, timeout: nil, &block)
674
+ expect_event(Events::Page::Download, predicate: predicate, timeout: timeout, &block)
675
+ end
676
+
677
+ def expect_file_chooser(predicate: nil, timeout: nil, &block)
678
+ expect_event(Events::Page::FileChooser, predicate: predicate, timeout: timeout, &block)
679
+ end
680
+
352
681
  def expect_navigation(timeout: nil, url: nil, waitUntil: nil, &block)
353
682
  @main_frame.expect_navigation(
354
683
  timeout: timeout,
@@ -357,6 +686,10 @@ module Playwright
357
686
  &block)
358
687
  end
359
688
 
689
+ def expect_popup(predicate: nil, timeout: nil, &block)
690
+ expect_event(Events::Page::Popup, predicate: predicate, timeout: timeout, &block)
691
+ end
692
+
360
693
  def expect_request(urlOrPredicate, timeout: nil)
361
694
  predicate =
362
695
  case urlOrPredicate
@@ -369,7 +702,7 @@ module Playwright
369
702
  -> (_) { true }
370
703
  end
371
704
 
372
- expect_event(Events::Page::Request, optionsOrPredicate: { predicate: predicate, timeout: timeout})
705
+ expect_event(Events::Page::Request, predicate: predicate, timeout: timeout)
373
706
  end
374
707
 
375
708
  def expect_response(urlOrPredicate, timeout: nil)
@@ -384,7 +717,7 @@ module Playwright
384
717
  -> (_) { true }
385
718
  end
386
719
 
387
- expect_event(Events::Page::Response, optionsOrPredicate: { predicate: predicate, timeout: timeout})
720
+ expect_event(Events::Page::Response, predicate: predicate, timeout: timeout)
388
721
  end
389
722
 
390
723
  # called from BrowserContext#on_page with send(:update_browser_context, page), so keep private.
@@ -397,5 +730,10 @@ module Playwright
397
730
  private def timeout_settings
398
731
  @timeout_settings
399
732
  end
733
+
734
+ # called from BrowserContext#expose_binding
735
+ private def has_bindings?(name)
736
+ @bindings.key?(name)
737
+ end
400
738
  end
401
739
  end