playwright-ruby-client 0.7.0 → 0.9.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -0
  3. data/documentation/docs/api/browser.md +18 -2
  4. data/documentation/docs/api/browser_context.md +10 -0
  5. data/documentation/docs/api/browser_type.md +1 -0
  6. data/documentation/docs/api/cdp_session.md +41 -1
  7. data/documentation/docs/api/download.md +97 -0
  8. data/documentation/docs/api/element_handle.md +38 -4
  9. data/documentation/docs/api/experimental/android_device.md +1 -0
  10. data/documentation/docs/api/frame.md +78 -17
  11. data/documentation/docs/api/keyboard.md +11 -20
  12. data/documentation/docs/api/locator.md +650 -0
  13. data/documentation/docs/api/page.md +107 -19
  14. data/documentation/docs/api/response.md +16 -0
  15. data/documentation/docs/article/guides/inspector.md +31 -0
  16. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +91 -0
  17. data/documentation/docs/article/guides/rails_integration.md +1 -1
  18. data/documentation/docs/article/guides/semi_automation.md +5 -1
  19. data/documentation/docs/include/api_coverage.md +70 -7
  20. data/lib/playwright.rb +36 -4
  21. data/lib/playwright/channel_owners/artifact.rb +4 -0
  22. data/lib/playwright/channel_owners/browser.rb +5 -0
  23. data/lib/playwright/channel_owners/browser_context.rb +37 -3
  24. data/lib/playwright/channel_owners/cdp_session.rb +19 -0
  25. data/lib/playwright/channel_owners/element_handle.rb +11 -4
  26. data/lib/playwright/channel_owners/frame.rb +103 -34
  27. data/lib/playwright/channel_owners/page.rb +140 -53
  28. data/lib/playwright/channel_owners/response.rb +9 -1
  29. data/lib/playwright/connection.rb +2 -4
  30. data/lib/playwright/{download.rb → download_impl.rb} +5 -1
  31. data/lib/playwright/javascript/expression.rb +5 -4
  32. data/lib/playwright/locator_impl.rb +314 -0
  33. data/lib/playwright/route_handler_entry.rb +3 -2
  34. data/lib/playwright/timeout_settings.rb +4 -4
  35. data/lib/playwright/transport.rb +0 -1
  36. data/lib/playwright/url_matcher.rb +12 -2
  37. data/lib/playwright/version.rb +2 -2
  38. data/lib/playwright/web_socket_client.rb +164 -0
  39. data/lib/playwright/web_socket_transport.rb +104 -0
  40. data/lib/playwright_api/android.rb +6 -6
  41. data/lib/playwright_api/android_device.rb +10 -9
  42. data/lib/playwright_api/browser.rb +17 -11
  43. data/lib/playwright_api/browser_context.rb +14 -9
  44. data/lib/playwright_api/browser_type.rb +8 -7
  45. data/lib/playwright_api/cdp_session.rb +30 -8
  46. data/lib/playwright_api/console_message.rb +6 -6
  47. data/lib/playwright_api/dialog.rb +6 -6
  48. data/lib/playwright_api/download.rb +70 -0
  49. data/lib/playwright_api/element_handle.rb +44 -24
  50. data/lib/playwright_api/frame.rb +100 -49
  51. data/lib/playwright_api/js_handle.rb +6 -6
  52. data/lib/playwright_api/locator.rb +509 -0
  53. data/lib/playwright_api/page.rb +110 -57
  54. data/lib/playwright_api/playwright.rb +6 -6
  55. data/lib/playwright_api/request.rb +6 -6
  56. data/lib/playwright_api/response.rb +15 -10
  57. data/lib/playwright_api/route.rb +6 -6
  58. data/lib/playwright_api/selectors.rb +6 -6
  59. data/lib/playwright_api/web_socket.rb +6 -6
  60. data/lib/playwright_api/worker.rb +6 -6
  61. metadata +15 -5
@@ -60,20 +60,20 @@ module Playwright
60
60
 
61
61
  # -- inherited from EventEmitter --
62
62
  # @nodoc
63
- def on(event, callback)
64
- event_emitter_proxy.on(event, callback)
63
+ def once(event, callback)
64
+ event_emitter_proxy.once(event, callback)
65
65
  end
66
66
 
67
67
  # -- inherited from EventEmitter --
68
68
  # @nodoc
69
- def off(event, callback)
70
- event_emitter_proxy.off(event, callback)
69
+ def on(event, callback)
70
+ event_emitter_proxy.on(event, callback)
71
71
  end
72
72
 
73
73
  # -- inherited from EventEmitter --
74
74
  # @nodoc
75
- def once(event, callback)
76
- event_emitter_proxy.once(event, callback)
75
+ def off(event, callback)
76
+ event_emitter_proxy.off(event, callback)
77
77
  end
78
78
 
79
79
  private def event_emitter_proxy
@@ -0,0 +1,70 @@
1
+ module Playwright
2
+ # `Download` objects are dispatched by page via the [`event: Page.download`] event.
3
+ #
4
+ # All the downloaded files belonging to the browser context are deleted when the browser context is closed.
5
+ #
6
+ # Download event is emitted once the download starts. Download path becomes available once download completes:
7
+ #
8
+ # ```python sync
9
+ # with page.expect_download() as download_info:
10
+ # page.click("a")
11
+ # download = download_info.value
12
+ # # wait for download to complete
13
+ # path = download.path()
14
+ # ```
15
+ #
16
+ # > NOTE: Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the
17
+ # downloaded content. If `acceptDownloads` is not set, download events are emitted, but the actual download is not
18
+ # performed and user has no access to the downloaded files.
19
+ class Download < PlaywrightApi
20
+
21
+ # Cancels a download. Will not fail if the download is already finished or canceled. Upon successful cancellations,
22
+ # `download.failure()` would resolve to `'canceled'`.
23
+ def cancel
24
+ wrap_impl(@impl.cancel)
25
+ end
26
+
27
+ # Deletes the downloaded file. Will wait for the download to finish if necessary.
28
+ def delete
29
+ wrap_impl(@impl.delete)
30
+ end
31
+
32
+ # Returns download error if any. Will wait for the download to finish if necessary.
33
+ def failure
34
+ wrap_impl(@impl.failure)
35
+ end
36
+
37
+ # Get the page that the download belongs to.
38
+ def page
39
+ wrap_impl(@impl.page)
40
+ end
41
+
42
+ # Returns path to the downloaded file in case of successful download. The method will wait for the download to finish if
43
+ # necessary. The method throws when connected remotely.
44
+ #
45
+ # Note that the download's file name is a random GUID, use [`method: Download.suggestedFilename`] to get suggested file
46
+ # name.
47
+ def path
48
+ wrap_impl(@impl.path)
49
+ end
50
+
51
+ # Copy the download to a user-specified path. It is safe to call this method while the download is still in progress. Will
52
+ # wait for the download to finish if necessary.
53
+ def save_as(path)
54
+ wrap_impl(@impl.save_as(unwrap_impl(path)))
55
+ end
56
+
57
+ # Returns suggested filename for this download. It is typically computed by the browser from the
58
+ # [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) response header
59
+ # or the `download` attribute. See the spec on [whatwg](https://html.spec.whatwg.org/#downloading-resources). Different
60
+ # browsers can use different logic for computing it.
61
+ def suggested_filename
62
+ wrap_impl(@impl.suggested_filename)
63
+ end
64
+
65
+ # Returns downloaded url.
66
+ def url
67
+ wrap_impl(@impl.url)
68
+ end
69
+ end
70
+ end
@@ -7,19 +7,8 @@ module Playwright
7
7
  # method.
8
8
  #
9
9
  # ```python sync
10
- # from playwright.sync_api import sync_playwright
11
- #
12
- # def run(playwright):
13
- # chromium = playwright.chromium
14
- # browser = chromium.launch()
15
- # page = browser.new_page()
16
- # page.goto("https://example.com")
17
- # href_element = page.query_selector("a")
18
- # href_element.click()
19
- # # ...
20
- #
21
- # with sync_playwright() as playwright:
22
- # run(playwright)
10
+ # href_element = page.query_selector("a")
11
+ # href_element.click()
23
12
  # ```
24
13
  #
25
14
  # ElementHandle prevents DOM element from garbage collection unless the handle is disposed with
@@ -27,6 +16,31 @@ module Playwright
27
16
  #
28
17
  # ElementHandle instances can be used as an argument in [`method: Page.evalOnSelector`] and [`method: Page.evaluate`]
29
18
  # methods.
19
+ #
20
+ # > NOTE: In most cases, you would want to use the `Locator` object instead. You should only use `ElementHandle` if you
21
+ # want to retain a handle to a particular DOM Node that you intend to pass into [`method: Page.evaluate`] as an argument.
22
+ #
23
+ # The difference between the `Locator` and ElementHandle is that the ElementHandle points to a particular element, while
24
+ # `Locator` captures the logic of how to retrieve an element.
25
+ #
26
+ # In the example below, handle points to a particular DOM element on page. If that element changes text or is used by
27
+ # React to render an entirely different component, handle is still pointing to that very DOM element. This can lead to
28
+ # unexpected behaviors.
29
+ #
30
+ # ```python sync
31
+ # handle = page.query_selector("text=Submit")
32
+ # handle.hover()
33
+ # handle.click()
34
+ # ```
35
+ #
36
+ # With the locator, every time the `element` is used, up-to-date DOM element is located in the page using the selector. So
37
+ # in the snippet below, underlying DOM element is going to be located twice.
38
+ #
39
+ # ```python sync
40
+ # locator = page.locator("text=Submit")
41
+ # locator.hover()
42
+ # locator.click()
43
+ # ```
30
44
  class ElementHandle < JSHandle
31
45
 
32
46
  # This method returns the bounding box of the element, or `null` if the element is not visible. The bounding box is
@@ -210,8 +224,8 @@ module Playwright
210
224
  # instead.
211
225
  #
212
226
  # To send fine-grained keyboard events, use [`method: ElementHandle.type`].
213
- def fill(value, noWaitAfter: nil, timeout: nil)
214
- wrap_impl(@impl.fill(unwrap_impl(value), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
227
+ def fill(value, force: nil, noWaitAfter: nil, timeout: nil)
228
+ wrap_impl(@impl.fill(unwrap_impl(value), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
215
229
  end
216
230
 
217
231
  # Calls [focus](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on the element.
@@ -254,6 +268,11 @@ module Playwright
254
268
  wrap_impl(@impl.inner_text)
255
269
  end
256
270
 
271
+ # Returns `input.value` for `<input>` or `<textarea>` element. Throws for non-input elements.
272
+ def input_value(timeout: nil)
273
+ wrap_impl(@impl.input_value(timeout: unwrap_impl(timeout)))
274
+ end
275
+
257
276
  # Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
258
277
  def checked?
259
278
  wrap_impl(@impl.checked?)
@@ -381,15 +400,16 @@ module Playwright
381
400
  index: nil,
382
401
  value: nil,
383
402
  label: nil,
403
+ force: nil,
384
404
  noWaitAfter: nil,
385
405
  timeout: nil)
386
- wrap_impl(@impl.select_option(element: unwrap_impl(element), index: unwrap_impl(index), value: unwrap_impl(value), label: unwrap_impl(label), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
406
+ wrap_impl(@impl.select_option(element: unwrap_impl(element), index: unwrap_impl(index), value: unwrap_impl(value), label: unwrap_impl(label), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
387
407
  end
388
408
 
389
409
  # This method waits for [actionability](./actionability.md) checks, then focuses the element and selects all its text
390
410
  # content.
391
- def select_text(timeout: nil)
392
- wrap_impl(@impl.select_text(timeout: unwrap_impl(timeout)))
411
+ def select_text(force: nil, timeout: nil)
412
+ wrap_impl(@impl.select_text(force: unwrap_impl(force), timeout: unwrap_impl(timeout)))
393
413
  end
394
414
 
395
415
  # This method expects `elementHandle` to point to an
@@ -511,20 +531,20 @@ module Playwright
511
531
 
512
532
  # -- inherited from EventEmitter --
513
533
  # @nodoc
514
- def on(event, callback)
515
- event_emitter_proxy.on(event, callback)
534
+ def once(event, callback)
535
+ event_emitter_proxy.once(event, callback)
516
536
  end
517
537
 
518
538
  # -- inherited from EventEmitter --
519
539
  # @nodoc
520
- def off(event, callback)
521
- event_emitter_proxy.off(event, callback)
540
+ def on(event, callback)
541
+ event_emitter_proxy.on(event, callback)
522
542
  end
523
543
 
524
544
  # -- inherited from EventEmitter --
525
545
  # @nodoc
526
- def once(event, callback)
527
- event_emitter_proxy.once(event, callback)
546
+ def off(event, callback)
547
+ event_emitter_proxy.off(event, callback)
528
548
  end
529
549
 
530
550
  private def event_emitter_proxy
@@ -65,9 +65,10 @@ module Playwright
65
65
  force: nil,
66
66
  noWaitAfter: nil,
67
67
  position: nil,
68
+ strict: nil,
68
69
  timeout: nil,
69
70
  trial: nil)
70
- wrap_impl(@impl.check(unwrap_impl(selector), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
71
+ wrap_impl(@impl.check(unwrap_impl(selector), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
71
72
  end
72
73
 
73
74
  def child_frames
@@ -93,9 +94,10 @@ module Playwright
93
94
  modifiers: nil,
94
95
  noWaitAfter: nil,
95
96
  position: nil,
97
+ strict: nil,
96
98
  timeout: nil,
97
99
  trial: nil)
98
- 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), trial: unwrap_impl(trial)))
100
+ 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), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
99
101
  end
100
102
 
101
103
  # Gets the full HTML contents of the frame, including the doctype.
@@ -124,9 +126,10 @@ module Playwright
124
126
  modifiers: nil,
125
127
  noWaitAfter: nil,
126
128
  position: nil,
129
+ strict: nil,
127
130
  timeout: nil,
128
131
  trial: nil)
129
- 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), trial: unwrap_impl(trial)))
132
+ 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), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
130
133
  end
131
134
 
132
135
  # The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the element,
@@ -156,8 +159,24 @@ module Playwright
156
159
  # data_transfer = frame.evaluate_handle("new DataTransfer()")
157
160
  # frame.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
158
161
  # ```
159
- def dispatch_event(selector, type, eventInit: nil, timeout: nil)
160
- wrap_impl(@impl.dispatch_event(unwrap_impl(selector), unwrap_impl(type), eventInit: unwrap_impl(eventInit), timeout: unwrap_impl(timeout)))
162
+ def dispatch_event(
163
+ selector,
164
+ type,
165
+ eventInit: nil,
166
+ strict: nil,
167
+ timeout: nil)
168
+ wrap_impl(@impl.dispatch_event(unwrap_impl(selector), unwrap_impl(type), eventInit: unwrap_impl(eventInit), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
169
+ end
170
+
171
+ def drag_and_drop(
172
+ source,
173
+ target,
174
+ force: nil,
175
+ noWaitAfter: nil,
176
+ strict: nil,
177
+ timeout: nil,
178
+ trial: nil)
179
+ wrap_impl(@impl.drag_and_drop(unwrap_impl(source), unwrap_impl(target), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
161
180
  end
162
181
 
163
182
  # Returns the return value of `expression`.
@@ -176,8 +195,8 @@ module Playwright
176
195
  # preload_href = frame.eval_on_selector("link[rel=preload]", "el => el.href")
177
196
  # html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
178
197
  # ```
179
- def eval_on_selector(selector, expression, arg: nil)
180
- wrap_impl(@impl.eval_on_selector(unwrap_impl(selector), unwrap_impl(expression), arg: unwrap_impl(arg)))
198
+ def eval_on_selector(selector, expression, arg: nil, strict: nil)
199
+ wrap_impl(@impl.eval_on_selector(unwrap_impl(selector), unwrap_impl(expression), arg: unwrap_impl(arg), strict: unwrap_impl(strict)))
181
200
  end
182
201
 
183
202
  # Returns the return value of `expression`.
@@ -271,14 +290,20 @@ module Playwright
271
290
  # instead.
272
291
  #
273
292
  # To send fine-grained keyboard events, use [`method: Frame.type`].
274
- def fill(selector, value, noWaitAfter: nil, timeout: nil)
275
- wrap_impl(@impl.fill(unwrap_impl(selector), unwrap_impl(value), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
293
+ def fill(
294
+ selector,
295
+ value,
296
+ force: nil,
297
+ noWaitAfter: nil,
298
+ strict: nil,
299
+ timeout: nil)
300
+ wrap_impl(@impl.fill(unwrap_impl(selector), unwrap_impl(value), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
276
301
  end
277
302
 
278
303
  # This method fetches an element with `selector` and focuses it. If there's no element matching `selector`, the method
279
304
  # waits until a matching element appears in the DOM.
280
- def focus(selector, timeout: nil)
281
- wrap_impl(@impl.focus(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
305
+ def focus(selector, strict: nil, timeout: nil)
306
+ wrap_impl(@impl.focus(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
282
307
  end
283
308
 
284
309
  # Returns the `frame` or `iframe` element handle which corresponds to this frame.
@@ -298,8 +323,8 @@ module Playwright
298
323
  end
299
324
 
300
325
  # Returns element attribute value.
301
- def get_attribute(selector, name, timeout: nil)
302
- wrap_impl(@impl.get_attribute(unwrap_impl(selector), unwrap_impl(name), timeout: unwrap_impl(timeout)))
326
+ def get_attribute(selector, name, strict: nil, timeout: nil)
327
+ wrap_impl(@impl.get_attribute(unwrap_impl(selector), unwrap_impl(name), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
303
328
  end
304
329
 
305
330
  # Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
@@ -339,24 +364,30 @@ module Playwright
339
364
  force: nil,
340
365
  modifiers: nil,
341
366
  position: nil,
367
+ strict: nil,
342
368
  timeout: nil,
343
369
  trial: nil)
344
- wrap_impl(@impl.hover(unwrap_impl(selector), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), position: unwrap_impl(position), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
370
+ wrap_impl(@impl.hover(unwrap_impl(selector), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), position: unwrap_impl(position), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
345
371
  end
346
372
 
347
373
  # Returns `element.innerHTML`.
348
- def inner_html(selector, timeout: nil)
349
- wrap_impl(@impl.inner_html(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
374
+ def inner_html(selector, strict: nil, timeout: nil)
375
+ wrap_impl(@impl.inner_html(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
350
376
  end
351
377
 
352
378
  # Returns `element.innerText`.
353
- def inner_text(selector, timeout: nil)
354
- wrap_impl(@impl.inner_text(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
379
+ def inner_text(selector, strict: nil, timeout: nil)
380
+ wrap_impl(@impl.inner_text(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
381
+ end
382
+
383
+ # Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
384
+ def input_value(selector, strict: nil, timeout: nil)
385
+ wrap_impl(@impl.input_value(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
355
386
  end
356
387
 
357
388
  # Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
358
- def checked?(selector, timeout: nil)
359
- wrap_impl(@impl.checked?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
389
+ def checked?(selector, strict: nil, timeout: nil)
390
+ wrap_impl(@impl.checked?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
360
391
  end
361
392
 
362
393
  # Returns `true` if the frame has been detached, or `false` otherwise.
@@ -365,30 +396,39 @@ module Playwright
365
396
  end
366
397
 
367
398
  # Returns whether the element is disabled, the opposite of [enabled](./actionability.md#enabled).
368
- def disabled?(selector, timeout: nil)
369
- wrap_impl(@impl.disabled?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
399
+ def disabled?(selector, strict: nil, timeout: nil)
400
+ wrap_impl(@impl.disabled?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
370
401
  end
371
402
 
372
403
  # Returns whether the element is [editable](./actionability.md#editable).
373
- def editable?(selector, timeout: nil)
374
- wrap_impl(@impl.editable?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
404
+ def editable?(selector, strict: nil, timeout: nil)
405
+ wrap_impl(@impl.editable?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
375
406
  end
376
407
 
377
408
  # Returns whether the element is [enabled](./actionability.md#enabled).
378
- def enabled?(selector, timeout: nil)
379
- wrap_impl(@impl.enabled?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
409
+ def enabled?(selector, strict: nil, timeout: nil)
410
+ wrap_impl(@impl.enabled?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
380
411
  end
381
412
 
382
413
  # Returns whether the element is hidden, the opposite of [visible](./actionability.md#visible). `selector` that does not
383
414
  # match any elements is considered hidden.
384
- def hidden?(selector, timeout: nil)
385
- wrap_impl(@impl.hidden?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
415
+ def hidden?(selector, strict: nil, timeout: nil)
416
+ wrap_impl(@impl.hidden?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
386
417
  end
387
418
 
388
419
  # Returns whether the element is [visible](./actionability.md#visible). `selector` that does not match any elements is
389
420
  # considered not visible.
390
- def visible?(selector, timeout: nil)
391
- wrap_impl(@impl.visible?(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
421
+ def visible?(selector, strict: nil, timeout: nil)
422
+ wrap_impl(@impl.visible?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
423
+ end
424
+
425
+ # The method returns an element locator that can be used to perform actions in the frame. Locator is resolved to the
426
+ # element immediately before performing an action, so a series of actions on the same locator can in fact be performed on
427
+ # different DOM elements. That would happen if the DOM structure between those actions has changed.
428
+ #
429
+ # Note that locator always implies visibility, so it will always be locating visible elements.
430
+ def locator(selector)
431
+ wrap_impl(@impl.locator(unwrap_impl(selector)))
392
432
  end
393
433
 
394
434
  # Returns frame's name attribute as specified in the tag.
@@ -431,16 +471,17 @@ module Playwright
431
471
  key,
432
472
  delay: nil,
433
473
  noWaitAfter: nil,
474
+ strict: nil,
434
475
  timeout: nil)
435
- wrap_impl(@impl.press(unwrap_impl(selector), unwrap_impl(key), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
476
+ wrap_impl(@impl.press(unwrap_impl(selector), unwrap_impl(key), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
436
477
  end
437
478
 
438
479
  # Returns the ElementHandle pointing to the frame element.
439
480
  #
440
481
  # The method finds an element matching the specified selector within the frame. See
441
482
  # [Working with selectors](./selectors.md) for more details. If no elements match the selector, returns `null`.
442
- def query_selector(selector)
443
- wrap_impl(@impl.query_selector(unwrap_impl(selector)))
483
+ def query_selector(selector, strict: nil)
484
+ wrap_impl(@impl.query_selector(unwrap_impl(selector), strict: unwrap_impl(strict)))
444
485
  end
445
486
 
446
487
  # Returns the ElementHandles pointing to the frame elements.
@@ -476,9 +517,11 @@ module Playwright
476
517
  index: nil,
477
518
  value: nil,
478
519
  label: nil,
520
+ force: nil,
479
521
  noWaitAfter: nil,
522
+ strict: nil,
480
523
  timeout: nil)
481
- 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)))
524
+ wrap_impl(@impl.select_option(unwrap_impl(selector), element: unwrap_impl(element), index: unwrap_impl(index), value: unwrap_impl(value), label: unwrap_impl(label), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
482
525
  end
483
526
 
484
527
  def set_content(html, timeout: nil, waitUntil: nil)
@@ -491,8 +534,13 @@ module Playwright
491
534
  #
492
535
  # Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
493
536
  # are resolved relative to the the current working directory. For empty array, clears the selected files.
494
- def set_input_files(selector, files, noWaitAfter: nil, timeout: nil)
495
- wrap_impl(@impl.set_input_files(unwrap_impl(selector), unwrap_impl(files), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
537
+ def set_input_files(
538
+ selector,
539
+ files,
540
+ noWaitAfter: nil,
541
+ strict: nil,
542
+ timeout: nil)
543
+ wrap_impl(@impl.set_input_files(unwrap_impl(selector), unwrap_impl(files), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
496
544
  end
497
545
 
498
546
  # This method taps an element matching `selector` by performing the following steps:
@@ -513,14 +561,15 @@ module Playwright
513
561
  modifiers: nil,
514
562
  noWaitAfter: nil,
515
563
  position: nil,
564
+ strict: nil,
516
565
  timeout: nil,
517
566
  trial: nil)
518
- 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), trial: unwrap_impl(trial)))
567
+ wrap_impl(@impl.tap_point(unwrap_impl(selector), force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
519
568
  end
520
569
 
521
570
  # Returns `element.textContent`.
522
- def text_content(selector, timeout: nil)
523
- wrap_impl(@impl.text_content(unwrap_impl(selector), timeout: unwrap_impl(timeout)))
571
+ def text_content(selector, strict: nil, timeout: nil)
572
+ wrap_impl(@impl.text_content(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
524
573
  end
525
574
 
526
575
  # Returns the page title.
@@ -542,8 +591,9 @@ module Playwright
542
591
  text,
543
592
  delay: nil,
544
593
  noWaitAfter: nil,
594
+ strict: nil,
545
595
  timeout: nil)
546
- wrap_impl(@impl.type(unwrap_impl(selector), unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
596
+ wrap_impl(@impl.type(unwrap_impl(selector), unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
547
597
  end
548
598
 
549
599
  # This method checks an element matching `selector` by performing the following steps:
@@ -564,9 +614,10 @@ module Playwright
564
614
  force: nil,
565
615
  noWaitAfter: nil,
566
616
  position: nil,
617
+ strict: nil,
567
618
  timeout: nil,
568
619
  trial: nil)
569
- wrap_impl(@impl.uncheck(unwrap_impl(selector), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
620
+ wrap_impl(@impl.uncheck(unwrap_impl(selector), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
570
621
  end
571
622
 
572
623
  # Returns frame's url.
@@ -660,8 +711,8 @@ module Playwright
660
711
  # with sync_playwright() as playwright:
661
712
  # run(playwright)
662
713
  # ```
663
- def wait_for_selector(selector, state: nil, timeout: nil)
664
- wrap_impl(@impl.wait_for_selector(unwrap_impl(selector), state: unwrap_impl(state), timeout: unwrap_impl(timeout)))
714
+ def wait_for_selector(selector, state: nil, strict: nil, timeout: nil)
715
+ wrap_impl(@impl.wait_for_selector(unwrap_impl(selector), state: unwrap_impl(state), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
665
716
  end
666
717
 
667
718
  # Waits for the given `timeout` in milliseconds.
@@ -689,20 +740,20 @@ module Playwright
689
740
 
690
741
  # -- inherited from EventEmitter --
691
742
  # @nodoc
692
- def on(event, callback)
693
- event_emitter_proxy.on(event, callback)
743
+ def once(event, callback)
744
+ event_emitter_proxy.once(event, callback)
694
745
  end
695
746
 
696
747
  # -- inherited from EventEmitter --
697
748
  # @nodoc
698
- def off(event, callback)
699
- event_emitter_proxy.off(event, callback)
749
+ def on(event, callback)
750
+ event_emitter_proxy.on(event, callback)
700
751
  end
701
752
 
702
753
  # -- inherited from EventEmitter --
703
754
  # @nodoc
704
- def once(event, callback)
705
- event_emitter_proxy.once(event, callback)
755
+ def off(event, callback)
756
+ event_emitter_proxy.off(event, callback)
706
757
  end
707
758
 
708
759
  private def event_emitter_proxy