playwright-ruby-client 0.0.8 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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