playwright-ruby-client 0.0.6 → 0.2.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +117 -5
  3. data/docs/api_coverage.md +359 -0
  4. data/lib/playwright.rb +6 -2
  5. data/lib/playwright/android_input_impl.rb +23 -0
  6. data/lib/playwright/api_implementation.rb +18 -0
  7. data/lib/playwright/channel.rb +7 -0
  8. data/lib/playwright/channel_owner.rb +6 -7
  9. data/lib/playwright/channel_owners/android.rb +10 -1
  10. data/lib/playwright/channel_owners/android_device.rb +163 -0
  11. data/lib/playwright/channel_owners/browser.rb +14 -14
  12. data/lib/playwright/channel_owners/browser_context.rb +10 -2
  13. data/lib/playwright/channel_owners/download.rb +27 -0
  14. data/lib/playwright/channel_owners/element_handle.rb +243 -1
  15. data/lib/playwright/channel_owners/frame.rb +269 -22
  16. data/lib/playwright/channel_owners/js_handle.rb +51 -0
  17. data/lib/playwright/channel_owners/page.rb +379 -34
  18. data/lib/playwright/channel_owners/request.rb +9 -1
  19. data/lib/playwright/channel_owners/webkit_browser.rb +1 -1
  20. data/lib/playwright/connection.rb +9 -6
  21. data/lib/playwright/errors.rb +2 -2
  22. data/lib/playwright/event_emitter.rb +8 -1
  23. data/lib/playwright/event_emitter_proxy.rb +49 -0
  24. data/lib/playwright/file_chooser_impl.rb +23 -0
  25. data/lib/playwright/http_headers.rb +20 -0
  26. data/lib/playwright/input_files.rb +42 -0
  27. data/lib/playwright/javascript/expression.rb +15 -0
  28. data/lib/playwright/javascript/function.rb +15 -0
  29. data/lib/playwright/javascript/value_parser.rb +1 -1
  30. data/lib/playwright/javascript/value_serializer.rb +11 -11
  31. data/lib/playwright/{input_types/keyboard.rb → keyboard_impl.rb} +6 -2
  32. data/lib/playwright/mouse_impl.rb +7 -0
  33. data/lib/playwright/playwright_api.rb +66 -19
  34. data/lib/playwright/select_option_values.rb +42 -0
  35. data/lib/playwright/timeout_settings.rb +1 -1
  36. data/lib/playwright/touchscreen_impl.rb +7 -0
  37. data/lib/playwright/utils.rb +18 -0
  38. data/lib/playwright/version.rb +1 -1
  39. data/lib/playwright/wait_helper.rb +1 -1
  40. data/lib/playwright_api/android.rb +32 -0
  41. data/lib/playwright_api/android_device.rb +77 -0
  42. data/lib/playwright_api/android_input.rb +25 -0
  43. data/lib/playwright_api/binding_call.rb +10 -6
  44. data/lib/playwright_api/browser.rb +22 -22
  45. data/lib/playwright_api/browser_context.rb +31 -22
  46. data/lib/playwright_api/browser_type.rb +16 -56
  47. data/lib/playwright_api/chromium_browser_context.rb +10 -8
  48. data/lib/playwright_api/console_message.rb +9 -10
  49. data/lib/playwright_api/dialog.rb +7 -3
  50. data/lib/playwright_api/download.rb +28 -11
  51. data/lib/playwright_api/element_handle.rb +139 -127
  52. data/lib/playwright_api/file_chooser.rb +17 -9
  53. data/lib/playwright_api/frame.rb +148 -148
  54. data/lib/playwright_api/js_handle.rb +26 -22
  55. data/lib/playwright_api/keyboard.rb +6 -6
  56. data/lib/playwright_api/page.rb +215 -179
  57. data/lib/playwright_api/playwright.rb +34 -46
  58. data/lib/playwright_api/request.rb +7 -8
  59. data/lib/playwright_api/response.rb +10 -6
  60. data/lib/playwright_api/selectors.rb +13 -9
  61. data/lib/playwright_api/web_socket.rb +10 -1
  62. data/lib/playwright_api/worker.rb +13 -13
  63. data/playwright.gemspec +1 -0
  64. metadata +32 -6
  65. data/lib/playwright/input_type.rb +0 -19
  66. data/lib/playwright/input_types/mouse.rb +0 -4
  67. data/lib/playwright/input_types/touchscreen.rb +0 -4
@@ -3,39 +3,47 @@ module Playwright
3
3
  #
4
4
  #
5
5
  # ```js
6
- # page.on('filechooser', async (fileChooser) => {
7
- # await fileChooser.setFiles('/tmp/myfile.pdf');
8
- # });
6
+ # const [fileChooser] = await Promise.all([
7
+ # page.waitForEvent('filechooser'),
8
+ # page.click('upload')
9
+ # ]);
10
+ # await fileChooser.setFiles('myfile.pdf');
9
11
  # ```
10
12
  #
11
13
  # ```python async
12
- # page.on("filechooser", lambda file_chooser: file_chooser.set_files("/tmp/myfile.pdf"))
14
+ # async with page.expect_file_chooser() as fc_info:
15
+ # await page.click("upload")
16
+ # file_chooser = await fc_info.value
17
+ # await file_chooser.set_files("myfile.pdf")
13
18
  # ```
14
19
  #
15
20
  # ```python sync
16
- # page.on("filechooser", lambda file_chooser: file_chooser.set_files("/tmp/myfile.pdf"))
21
+ # with page.expect_file_chooser() as fc_info:
22
+ # page.click("upload")
23
+ # file_chooser = fc_info.value
24
+ # file_chooser.set_files("myfile.pdf")
17
25
  # ```
18
26
  class FileChooser < PlaywrightApi
19
27
 
20
28
  # Returns input element associated with this file chooser.
21
29
  def element
22
- raise NotImplementedError.new('element is not implemented yet.')
30
+ wrap_impl(@impl.element)
23
31
  end
24
32
 
25
33
  # Returns whether this file chooser accepts multiple files.
26
34
  def multiple?
27
- raise NotImplementedError.new('multiple? is not implemented yet.')
35
+ wrap_impl(@impl.multiple?)
28
36
  end
29
37
 
30
38
  # Returns page this file chooser belongs to.
31
39
  def page
32
- raise NotImplementedError.new('page is not implemented yet.')
40
+ wrap_impl(@impl.page)
33
41
  end
34
42
 
35
43
  # Sets the value of the file input this chooser is associated with. If some of the `filePaths` are relative paths, then
36
44
  # they are resolved relative to the the current working directory. For empty array, clears the selected files.
37
45
  def set_files(files, noWaitAfter: nil, timeout: nil)
38
- raise NotImplementedError.new('set_files is not implemented yet.')
46
+ wrap_impl(@impl.set_files(unwrap_impl(files), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
39
47
  end
40
48
  alias_method :files=, :set_files
41
49
  end
@@ -75,87 +75,11 @@ module Playwright
75
75
  # ```
76
76
  class Frame < PlaywrightApi
77
77
 
78
- # Returns the ElementHandle pointing to the frame element.
79
- #
80
- # The method finds an element matching the specified selector within the frame. See
81
- # [Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
82
- # returns `null`.
83
- def query_selector(selector)
84
- wrap_impl(@impl.query_selector(selector))
85
- end
86
-
87
- # Returns the ElementHandles pointing to the frame elements.
88
- #
89
- # The method finds all elements matching the specified selector within the frame. See
90
- # [Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
91
- # returns empty array.
92
- def query_selector_all(selector)
93
- wrap_impl(@impl.query_selector_all(selector))
94
- end
95
-
96
- # Returns the return value of `pageFunction`
97
- #
98
- # The method finds an element matching the specified selector within the frame and passes it as a first argument to
99
- # `pageFunction`. See [Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements
100
- # match the selector, the method throws an error.
101
- #
102
- # If `pageFunction` returns a [Promise], then `frame.$eval` would wait for the promise to resolve and return its value.
103
- #
104
- # Examples:
105
- #
106
- #
107
- # ```js
108
- # const searchValue = await frame.$eval('#search', el => el.value);
109
- # const preloadHref = await frame.$eval('link[rel=preload]', el => el.href);
110
- # const html = await frame.$eval('.main-container', (e, suffix) => e.outerHTML + suffix, 'hello');
111
- # ```
112
- #
113
- # ```python async
114
- # search_value = await frame.eval_on_selector("#search", "el => el.value")
115
- # preload_href = await frame.eval_on_selector("link[rel=preload]", "el => el.href")
116
- # html = await frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
117
- # ```
118
- #
119
- # ```python sync
120
- # search_value = frame.eval_on_selector("#search", "el => el.value")
121
- # preload_href = frame.eval_on_selector("link[rel=preload]", "el => el.href")
122
- # html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
123
- # ```
124
- def eval_on_selector(selector, pageFunction, arg: nil)
125
- wrap_impl(@impl.eval_on_selector(selector, pageFunction, arg: arg))
126
- end
127
-
128
- # Returns the return value of `pageFunction`
129
- #
130
- # The method finds all elements matching the specified selector within the frame and passes an array of matched elements
131
- # as a first argument to `pageFunction`. See [Working with selectors](./selectors.md#working-with-selectors) for more
132
- # details.
133
- #
134
- # If `pageFunction` returns a [Promise], then `frame.$$eval` would wait for the promise to resolve and return its value.
135
- #
136
- # Examples:
137
- #
138
- #
139
- # ```js
140
- # const divsCounts = await frame.$$eval('div', (divs, min) => divs.length >= min, 10);
141
- # ```
142
- #
143
- # ```python async
144
- # divs_counts = await frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
145
- # ```
146
- #
147
- # ```python sync
148
- # divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
149
- # ```
150
- def eval_on_selector_all(selector, pageFunction, arg: nil)
151
- wrap_impl(@impl.eval_on_selector_all(selector, pageFunction, arg: arg))
152
- end
153
-
154
78
  # Returns the added tag when the script's onload fires or when the script content was injected into frame.
155
79
  #
156
80
  # Adds a `<script>` tag into the page with the desired url or content.
157
81
  def add_script_tag(content: nil, path: nil, type: nil, url: nil)
158
- raise NotImplementedError.new('add_script_tag is not implemented yet.')
82
+ wrap_impl(@impl.add_script_tag(content: unwrap_impl(content), path: unwrap_impl(path), type: unwrap_impl(type), url: unwrap_impl(url)))
159
83
  end
160
84
 
161
85
  # Returns the added tag when the stylesheet's onload fires or when the CSS content was injected into frame.
@@ -163,7 +87,7 @@ module Playwright
163
87
  # Adds a `<link rel="stylesheet">` tag into the page with the desired url or a `<style type="text/css">` tag with the
164
88
  # content.
165
89
  def add_style_tag(content: nil, path: nil, url: nil)
166
- raise NotImplementedError.new('add_style_tag is not implemented yet.')
90
+ wrap_impl(@impl.add_style_tag(content: unwrap_impl(content), path: unwrap_impl(path), url: unwrap_impl(url)))
167
91
  end
168
92
 
169
93
  # This method checks an element matching `selector` by performing the following steps:
@@ -180,7 +104,7 @@ module Playwright
180
104
  # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
181
105
  # Passing zero timeout disables this.
182
106
  def check(selector, force: nil, noWaitAfter: nil, timeout: nil)
183
- raise NotImplementedError.new('check is not implemented yet.')
107
+ wrap_impl(@impl.check(unwrap_impl(selector), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
184
108
  end
185
109
 
186
110
  def child_frames
@@ -207,7 +131,7 @@ module Playwright
207
131
  noWaitAfter: nil,
208
132
  position: nil,
209
133
  timeout: nil)
210
- wrap_impl(@impl.click(selector, button: button, clickCount: clickCount, delay: delay, force: force, modifiers: modifiers, noWaitAfter: noWaitAfter, position: position, timeout: timeout))
134
+ wrap_impl(@impl.click(unwrap_impl(selector), button: unwrap_impl(button), clickCount: unwrap_impl(clickCount), delay: unwrap_impl(delay), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), timeout: unwrap_impl(timeout)))
211
135
  end
212
136
 
213
137
  # Gets the full HTML contents of the frame, including the doctype.
@@ -237,7 +161,7 @@ module Playwright
237
161
  noWaitAfter: nil,
238
162
  position: nil,
239
163
  timeout: nil)
240
- raise NotImplementedError.new('dblclick is not implemented yet.')
164
+ wrap_impl(@impl.dblclick(unwrap_impl(selector), button: unwrap_impl(button), delay: unwrap_impl(delay), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), timeout: unwrap_impl(timeout)))
241
165
  end
242
166
 
243
167
  # The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the elment, `click`
@@ -290,17 +214,76 @@ module Playwright
290
214
  # frame.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
291
215
  # ```
292
216
  def dispatch_event(selector, type, eventInit: nil, timeout: nil)
293
- raise NotImplementedError.new('dispatch_event is not implemented yet.')
217
+ wrap_impl(@impl.dispatch_event(unwrap_impl(selector), unwrap_impl(type), eventInit: unwrap_impl(eventInit), timeout: unwrap_impl(timeout)))
294
218
  end
295
219
 
296
- # Returns the return value of `pageFunction`
220
+ # Returns the return value of `expression`.
221
+ #
222
+ # The method finds an element matching the specified selector within the frame and passes it as a first argument to
223
+ # `expression`. See [Working with selectors](./selectors.md) for more details. If no elements match the selector, the
224
+ # method throws an error.
225
+ #
226
+ # If `expression` returns a [Promise], then [`method: Frame.evalOnSelector`] would wait for the promise to resolve and
227
+ # return its value.
228
+ #
229
+ # Examples:
230
+ #
231
+ #
232
+ # ```js
233
+ # const searchValue = await frame.$eval('#search', el => el.value);
234
+ # const preloadHref = await frame.$eval('link[rel=preload]', el => el.href);
235
+ # const html = await frame.$eval('.main-container', (e, suffix) => e.outerHTML + suffix, 'hello');
236
+ # ```
237
+ #
238
+ # ```python async
239
+ # search_value = await frame.eval_on_selector("#search", "el => el.value")
240
+ # preload_href = await frame.eval_on_selector("link[rel=preload]", "el => el.href")
241
+ # html = await frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
242
+ # ```
243
+ #
244
+ # ```python sync
245
+ # search_value = frame.eval_on_selector("#search", "el => el.value")
246
+ # preload_href = frame.eval_on_selector("link[rel=preload]", "el => el.href")
247
+ # html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
248
+ # ```
249
+ def eval_on_selector(selector, expression, arg: nil)
250
+ wrap_impl(@impl.eval_on_selector(unwrap_impl(selector), unwrap_impl(expression), arg: unwrap_impl(arg)))
251
+ end
252
+
253
+ # Returns the return value of `expression`.
254
+ #
255
+ # The method finds all elements matching the specified selector within the frame and passes an array of matched elements
256
+ # as a first argument to `expression`. See [Working with selectors](./selectors.md) for more details.
257
+ #
258
+ # If `expression` returns a [Promise], then [`method: Frame.evalOnSelectorAll`] would wait for the promise to resolve and
259
+ # return its value.
260
+ #
261
+ # Examples:
262
+ #
263
+ #
264
+ # ```js
265
+ # const divsCounts = await frame.$$eval('div', (divs, min) => divs.length >= min, 10);
266
+ # ```
267
+ #
268
+ # ```python async
269
+ # divs_counts = await frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
270
+ # ```
271
+ #
272
+ # ```python sync
273
+ # divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
274
+ # ```
275
+ def eval_on_selector_all(selector, expression, arg: nil)
276
+ wrap_impl(@impl.eval_on_selector_all(unwrap_impl(selector), unwrap_impl(expression), arg: unwrap_impl(arg)))
277
+ end
278
+
279
+ # Returns the return value of `expression`.
297
280
  #
298
281
  # If the function passed to the [`method: Frame.evaluate`] returns a [Promise], then [`method: Frame.evaluate`] would wait
299
282
  # for the promise to resolve and return its value.
300
283
  #
301
- # If the function passed to the [`method: Frame.evaluate`] returns a non-[Serializable] value,
302
- # then[ method: `Frame.evaluate`] returns `undefined`. DevTools Protocol also supports transferring some additional values
303
- # that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
284
+ # If the function passed to the [`method: Frame.evaluate`] returns a non-[Serializable] value, then
285
+ # [`method: Frame.evaluate`] returns `undefined`. Playwright also supports transferring some additional values that are
286
+ # not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`.
304
287
  #
305
288
  #
306
289
  # ```js
@@ -359,17 +342,17 @@ module Playwright
359
342
  # html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
360
343
  # body_handle.dispose()
361
344
  # ```
362
- def evaluate(pageFunction, arg: nil)
363
- wrap_impl(@impl.evaluate(pageFunction, arg: arg))
345
+ def evaluate(expression, arg: nil)
346
+ wrap_impl(@impl.evaluate(unwrap_impl(expression), arg: unwrap_impl(arg)))
364
347
  end
365
348
 
366
- # Returns the return value of `pageFunction` as in-page object (JSHandle).
349
+ # Returns the return value of `expression` as a `JSHandle`.
367
350
  #
368
- # The only difference between [`method: Frame.evaluate`] and [`method: Frame.evaluateHandle`] is
369
- # that[ method: Fframe.evaluateHandle`] returns in-page object (JSHandle).
351
+ # The only difference between [`method: Frame.evaluate`] and [`method: Frame.evaluateHandle`] is that
352
+ # [method: Frame.evaluateHandle`] returns `JSHandle`.
370
353
  #
371
- # If the function, passed to the [`method: Frame.evaluateHandle`], returns a [Promise],
372
- # then[ method: Fframe.evaluateHandle`] would wait for the promise to resolve and return its value.
354
+ # If the function, passed to the [`method: Frame.evaluateHandle`], returns a [Promise], then
355
+ # [`method: Frame.evaluateHandle`] would wait for the promise to resolve and return its value.
373
356
  #
374
357
  #
375
358
  # ```js
@@ -378,7 +361,6 @@ module Playwright
378
361
  # ```
379
362
  #
380
363
  # ```python async
381
- # # FIXME
382
364
  # a_window_handle = await frame.evaluate_handle("Promise.resolve(window)")
383
365
  # a_window_handle # handle for the window object.
384
366
  # ```
@@ -426,24 +408,25 @@ module Playwright
426
408
  # print(result_handle.json_value())
427
409
  # result_handle.dispose()
428
410
  # ```
429
- def evaluate_handle(pageFunction, arg: nil)
430
- wrap_impl(@impl.evaluate_handle(pageFunction, arg: arg))
411
+ def evaluate_handle(expression, arg: nil)
412
+ wrap_impl(@impl.evaluate_handle(unwrap_impl(expression), arg: unwrap_impl(arg)))
431
413
  end
432
414
 
433
415
  # This method waits for an element matching `selector`, waits for [actionability](./actionability.md) checks, focuses the
434
- # element, fills it and triggers an `input` event after filling. If the element matching `selector` is not an `<input>`,
435
- # `<textarea>` or `[contenteditable]` element, this method throws an error. Note that you can pass an empty string to
436
- # clear the input field.
416
+ # element, fills it and triggers an `input` event after filling. If the element is inside the `<label>` element that has
417
+ # associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), that control will be
418
+ # filled instead. If the element to be filled is not an `<input>`, `<textarea>` or `[contenteditable]` element, this
419
+ # method throws an error. Note that you can pass an empty string to clear the input field.
437
420
  #
438
421
  # To send fine-grained keyboard events, use [`method: Frame.type`].
439
422
  def fill(selector, value, noWaitAfter: nil, timeout: nil)
440
- raise NotImplementedError.new('fill is not implemented yet.')
423
+ wrap_impl(@impl.fill(unwrap_impl(selector), unwrap_impl(value), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
441
424
  end
442
425
 
443
426
  # This method fetches an element with `selector` and focuses it. If there's no element matching `selector`, the method
444
427
  # waits until a matching element appears in the DOM.
445
428
  def focus(selector, timeout: nil)
446
- wrap_impl(@impl.focus(selector, timeout: timeout))
429
+ wrap_impl(@impl.focus(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
447
430
  end
448
431
 
449
432
  # Returns the `frame` or `iframe` element handle which corresponds to this frame.
@@ -477,7 +460,7 @@ module Playwright
477
460
 
478
461
  # Returns element attribute value.
479
462
  def get_attribute(selector, name, timeout: nil)
480
- raise NotImplementedError.new('get_attribute is not implemented yet.')
463
+ wrap_impl(@impl.get_attribute(unwrap_impl(selector), unwrap_impl(name), timeout: unwrap_impl(timeout)))
481
464
  end
482
465
 
483
466
  # Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
@@ -499,7 +482,7 @@ module Playwright
499
482
  # > NOTE: Headless mode doesn't support navigation to a PDF document. See the
500
483
  # [upstream issue](https://bugs.chromium.org/p/chromium/issues/detail?id=761295).
501
484
  def goto(url, referer: nil, timeout: nil, waitUntil: nil)
502
- wrap_impl(@impl.goto(url, referer: referer, timeout: timeout, waitUntil: waitUntil))
485
+ wrap_impl(@impl.goto(unwrap_impl(url), referer: unwrap_impl(referer), timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
503
486
  end
504
487
 
505
488
  # This method hovers over an element matching `selector` by performing the following steps:
@@ -518,52 +501,52 @@ module Playwright
518
501
  modifiers: nil,
519
502
  position: nil,
520
503
  timeout: nil)
521
- raise NotImplementedError.new('hover is not implemented yet.')
504
+ wrap_impl(@impl.hover(unwrap_impl(selector), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), position: unwrap_impl(position), timeout: unwrap_impl(timeout)))
522
505
  end
523
506
 
524
507
  # Returns `element.innerHTML`.
525
508
  def inner_html(selector, timeout: nil)
526
- raise NotImplementedError.new('inner_html is not implemented yet.')
509
+ wrap_impl(@impl.inner_html(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
527
510
  end
528
511
 
529
512
  # Returns `element.innerText`.
530
513
  def inner_text(selector, timeout: nil)
531
- raise NotImplementedError.new('inner_text is not implemented yet.')
514
+ wrap_impl(@impl.inner_text(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
532
515
  end
533
516
 
534
517
  # Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
535
518
  def checked?(selector, timeout: nil)
536
- raise NotImplementedError.new('checked? is not implemented yet.')
519
+ wrap_impl(@impl.checked?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
537
520
  end
538
521
 
539
522
  # Returns `true` if the frame has been detached, or `false` otherwise.
540
523
  def detached?
541
- raise NotImplementedError.new('detached? is not implemented yet.')
524
+ wrap_impl(@impl.detached?)
542
525
  end
543
526
 
544
527
  # Returns whether the element is disabled, the opposite of [enabled](./actionability.md#enabled).
545
528
  def disabled?(selector, timeout: nil)
546
- raise NotImplementedError.new('disabled? is not implemented yet.')
529
+ wrap_impl(@impl.disabled?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
547
530
  end
548
531
 
549
532
  # Returns whether the element is [editable](./actionability.md#editable).
550
533
  def editable?(selector, timeout: nil)
551
- raise NotImplementedError.new('editable? is not implemented yet.')
534
+ wrap_impl(@impl.editable?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
552
535
  end
553
536
 
554
537
  # Returns whether the element is [enabled](./actionability.md#enabled).
555
538
  def enabled?(selector, timeout: nil)
556
- raise NotImplementedError.new('enabled? is not implemented yet.')
539
+ wrap_impl(@impl.enabled?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
557
540
  end
558
541
 
559
542
  # Returns whether the element is hidden, the opposite of [visible](./actionability.md#visible).
560
543
  def hidden?(selector, timeout: nil)
561
- raise NotImplementedError.new('hidden? is not implemented yet.')
544
+ wrap_impl(@impl.hidden?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
562
545
  end
563
546
 
564
547
  # Returns whether the element is [visible](./actionability.md#visible).
565
548
  def visible?(selector, timeout: nil)
566
- raise NotImplementedError.new('visible? is not implemented yet.')
549
+ wrap_impl(@impl.visible?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
567
550
  end
568
551
 
569
552
  # Returns frame's name attribute as specified in the tag.
@@ -607,7 +590,23 @@ module Playwright
607
590
  delay: nil,
608
591
  noWaitAfter: nil,
609
592
  timeout: nil)
610
- wrap_impl(@impl.press(selector, key, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout))
593
+ wrap_impl(@impl.press(unwrap_impl(selector), unwrap_impl(key), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
594
+ end
595
+
596
+ # Returns the ElementHandle pointing to the frame element.
597
+ #
598
+ # The method finds an element matching the specified selector within the frame. See
599
+ # [Working with selectors](./selectors.md) for more details. If no elements match the selector, returns `null`.
600
+ def query_selector(selector)
601
+ wrap_impl(@impl.query_selector(unwrap_impl(selector)))
602
+ end
603
+
604
+ # Returns the ElementHandles pointing to the frame elements.
605
+ #
606
+ # The method finds all elements matching the specified selector within the frame. See
607
+ # [Working with selectors](./selectors.md) for more details. If no elements match the selector, returns empty array.
608
+ def query_selector_all(selector)
609
+ wrap_impl(@impl.query_selector_all(unwrap_impl(selector)))
611
610
  end
612
611
 
613
612
  # Returns the array of option values that have been successfully selected.
@@ -646,12 +645,19 @@ module Playwright
646
645
  # # multiple selection
647
646
  # frame.select_option("select#colors", value=["red", "green", "blue"])
648
647
  # ```
649
- def select_option(selector, values, noWaitAfter: nil, timeout: nil)
650
- raise NotImplementedError.new('select_option is not implemented yet.')
648
+ def select_option(
649
+ selector,
650
+ element: nil,
651
+ index: nil,
652
+ value: nil,
653
+ label: nil,
654
+ noWaitAfter: nil,
655
+ timeout: nil)
656
+ wrap_impl(@impl.select_option(unwrap_impl(selector), element: unwrap_impl(element), index: unwrap_impl(index), value: unwrap_impl(value), label: unwrap_impl(label), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
651
657
  end
652
658
 
653
659
  def set_content(html, timeout: nil, waitUntil: nil)
654
- wrap_impl(@impl.set_content(html, timeout: timeout, waitUntil: waitUntil))
660
+ wrap_impl(@impl.set_content(unwrap_impl(html), timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
655
661
  end
656
662
  alias_method :content=, :set_content
657
663
 
@@ -661,7 +667,7 @@ module Playwright
661
667
  # Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
662
668
  # are resolved relative to the the current working directory. For empty array, clears the selected files.
663
669
  def set_input_files(selector, files, noWaitAfter: nil, timeout: nil)
664
- raise NotImplementedError.new('set_input_files is not implemented yet.')
670
+ wrap_impl(@impl.set_input_files(unwrap_impl(selector), unwrap_impl(files), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
665
671
  end
666
672
 
667
673
  # This method taps an element matching `selector` by performing the following steps:
@@ -683,12 +689,12 @@ module Playwright
683
689
  noWaitAfter: nil,
684
690
  position: nil,
685
691
  timeout: nil)
686
- raise NotImplementedError.new('tap_point is not implemented yet.')
692
+ wrap_impl(@impl.tap_point(unwrap_impl(selector), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), timeout: unwrap_impl(timeout)))
687
693
  end
688
694
 
689
695
  # Returns `element.textContent`.
690
696
  def text_content(selector, timeout: nil)
691
- raise NotImplementedError.new('text_content is not implemented yet.')
697
+ wrap_impl(@impl.text_content(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
692
698
  end
693
699
 
694
700
  # Returns the page title.
@@ -716,13 +722,13 @@ module Playwright
716
722
  # frame.type("#mytextarea", "hello") # types instantly
717
723
  # frame.type("#mytextarea", "world", delay=100) # types slower, like a user
718
724
  # ```
719
- def type_text(
725
+ def type(
720
726
  selector,
721
727
  text,
722
728
  delay: nil,
723
729
  noWaitAfter: nil,
724
730
  timeout: nil)
725
- wrap_impl(@impl.type_text(selector, text, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout))
731
+ wrap_impl(@impl.type(unwrap_impl(selector), unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
726
732
  end
727
733
 
728
734
  # This method checks an element matching `selector` by performing the following steps:
@@ -739,7 +745,7 @@ module Playwright
739
745
  # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
740
746
  # Passing zero timeout disables this.
741
747
  def uncheck(selector, force: nil, noWaitAfter: nil, timeout: nil)
742
- raise NotImplementedError.new('uncheck is not implemented yet.')
748
+ wrap_impl(@impl.uncheck(unwrap_impl(selector), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
743
749
  end
744
750
 
745
751
  # Returns frame's url.
@@ -747,9 +753,9 @@ module Playwright
747
753
  wrap_impl(@impl.url)
748
754
  end
749
755
 
750
- # Returns when the `pageFunction` returns a truthy value, returns that value.
756
+ # Returns when the `expression` returns a truthy value, returns that value.
751
757
  #
752
- # The `waitForFunction` can be used to observe viewport size change:
758
+ # The [`method: Frame.waitForFunction`] can be used to observe viewport size change:
753
759
  #
754
760
  #
755
761
  # ```js
@@ -773,7 +779,7 @@ module Playwright
773
779
  # webkit = playwright.webkit
774
780
  # browser = await webkit.launch()
775
781
  # page = await browser.new_page()
776
- # await page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);", force_expr=True)
782
+ # await page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
777
783
  # await page.main_frame.wait_for_function("() => window.x > 0")
778
784
  # await browser.close()
779
785
  #
@@ -790,7 +796,7 @@ module Playwright
790
796
  # webkit = playwright.webkit
791
797
  # browser = webkit.launch()
792
798
  # page = browser.new_page()
793
- # page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);", force_expr=True)
799
+ # page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
794
800
  # page.main_frame.wait_for_function("() => window.x > 0")
795
801
  # browser.close()
796
802
  #
@@ -815,8 +821,8 @@ module Playwright
815
821
  # selector = ".foo"
816
822
  # frame.wait_for_function("selector => !!document.querySelector(selector)", selector)
817
823
  # ```
818
- def wait_for_function(pageFunction, arg: nil, polling: nil, timeout: nil)
819
- raise NotImplementedError.new('wait_for_function is not implemented yet.')
824
+ def wait_for_function(expression, arg: nil, polling: nil, timeout: nil)
825
+ wrap_impl(@impl.wait_for_function(unwrap_impl(expression), arg: unwrap_impl(arg), polling: unwrap_impl(polling), timeout: unwrap_impl(timeout)))
820
826
  end
821
827
 
822
828
  # Waits for the required load state to be reached.
@@ -840,7 +846,7 @@ module Playwright
840
846
  # frame.wait_for_load_state() # the promise resolves after "load" event.
841
847
  # ```
842
848
  def wait_for_load_state(state: nil, timeout: nil)
843
- wrap_impl(@impl.wait_for_load_state(state: state, timeout: timeout))
849
+ wrap_impl(@impl.wait_for_load_state(state: unwrap_impl(state), timeout: unwrap_impl(timeout)))
844
850
  end
845
851
 
846
852
  # Waits for the frame navigation and returns the main resource response. In case of multiple redirects, the navigation
@@ -872,8 +878,8 @@ module Playwright
872
878
  #
873
879
  # > NOTE: Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is
874
880
  # considered a navigation.
875
- def expect_navigation(timeout: nil, url: nil, waitUntil: nil)
876
- raise NotImplementedError.new('expect_navigation is not implemented yet.')
881
+ def expect_navigation(timeout: nil, url: nil, waitUntil: nil, &block)
882
+ wrap_impl(@impl.expect_navigation(timeout: unwrap_impl(timeout), url: unwrap_impl(url), waitUntil: unwrap_impl(waitUntil), &wrap_block_call(block)))
877
883
  end
878
884
 
879
885
  # Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
@@ -938,7 +944,7 @@ module Playwright
938
944
  # run(playwright)
939
945
  # ```
940
946
  def wait_for_selector(selector, state: nil, timeout: nil)
941
- raise NotImplementedError.new('wait_for_selector is not implemented yet.')
947
+ wrap_impl(@impl.wait_for_selector(unwrap_impl(selector), state: unwrap_impl(state), timeout: unwrap_impl(timeout)))
942
948
  end
943
949
 
944
950
  # Waits for the given `timeout` in milliseconds.
@@ -950,36 +956,30 @@ module Playwright
950
956
  end
951
957
 
952
958
  # @nodoc
953
- def wait_for_navigation(timeout: nil, url: nil, waitUntil: nil, &block)
954
- wrap_impl(@impl.wait_for_navigation(timeout: timeout, url: url, waitUntil: waitUntil, &wrap_block_call(block)))
955
- end
956
-
957
- # @nodoc
958
- def after_initialize
959
- wrap_impl(@impl.after_initialize)
959
+ def detached=(req)
960
+ wrap_impl(@impl.detached=(unwrap_impl(req)))
960
961
  end
961
962
 
963
+ # -- inherited from EventEmitter --
962
964
  # @nodoc
963
- def detached=(req)
964
- wrap_impl(@impl.detached=(req))
965
+ def once(event, callback)
966
+ event_emitter_proxy.once(event, callback)
965
967
  end
966
968
 
967
969
  # -- inherited from EventEmitter --
968
970
  # @nodoc
969
971
  def on(event, callback)
970
- wrap_impl(@impl.on(event, callback))
972
+ event_emitter_proxy.on(event, callback)
971
973
  end
972
974
 
973
975
  # -- inherited from EventEmitter --
974
976
  # @nodoc
975
977
  def off(event, callback)
976
- wrap_impl(@impl.off(event, callback))
978
+ event_emitter_proxy.off(event, callback)
977
979
  end
978
980
 
979
- # -- inherited from EventEmitter --
980
- # @nodoc
981
- def once(event, callback)
982
- wrap_impl(@impl.once(event, callback))
981
+ private def event_emitter_proxy
982
+ @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
983
983
  end
984
984
  end
985
985
  end