playwright-ruby-client 1.26.0 → 1.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/api_request_context.md +86 -0
  3. data/documentation/docs/api/browser_context.md +3 -3
  4. data/documentation/docs/api/download.md +1 -1
  5. data/documentation/docs/api/element_handle.md +2 -1
  6. data/documentation/docs/api/file_chooser.md +1 -1
  7. data/documentation/docs/api/frame.md +151 -4
  8. data/documentation/docs/api/frame_locator.md +151 -4
  9. data/documentation/docs/api/js_handle.md +5 -3
  10. data/documentation/docs/api/keyboard.md +1 -1
  11. data/documentation/docs/api/locator.md +191 -6
  12. data/documentation/docs/api/page.md +166 -9
  13. data/documentation/docs/api/request.md +1 -1
  14. data/documentation/docs/api/tracing.md +1 -1
  15. data/documentation/docs/article/guides/rails_integration.md +1 -0
  16. data/documentation/docs/article/guides/rails_integration_with_null_driver.md +59 -0
  17. data/documentation/docs/include/api_coverage.md +32 -0
  18. data/lib/playwright/channel_owner.rb +41 -0
  19. data/lib/playwright/channel_owners/browser_context.rb +6 -0
  20. data/lib/playwright/channel_owners/element_handle.rb +8 -1
  21. data/lib/playwright/channel_owners/frame.rb +6 -0
  22. data/lib/playwright/channel_owners/page.rb +25 -28
  23. data/lib/playwright/channel_owners/selectors.rb +4 -0
  24. data/lib/playwright/connection.rb +4 -1
  25. data/lib/playwright/frame_locator_impl.rb +6 -2
  26. data/lib/playwright/locator_impl.rb +21 -31
  27. data/lib/playwright/locator_utils.rb +136 -0
  28. data/lib/playwright/utils.rb +6 -0
  29. data/lib/playwright/version.rb +2 -2
  30. data/lib/playwright_api/android.rb +12 -6
  31. data/lib/playwright_api/android_device.rb +6 -6
  32. data/lib/playwright_api/api_request_context.rb +86 -8
  33. data/lib/playwright_api/browser.rb +6 -6
  34. data/lib/playwright_api/browser_context.rb +9 -9
  35. data/lib/playwright_api/browser_type.rb +6 -6
  36. data/lib/playwright_api/cdp_session.rb +6 -6
  37. data/lib/playwright_api/console_message.rb +6 -6
  38. data/lib/playwright_api/dialog.rb +6 -6
  39. data/lib/playwright_api/download.rb +1 -1
  40. data/lib/playwright_api/element_handle.rb +9 -8
  41. data/lib/playwright_api/file_chooser.rb +1 -1
  42. data/lib/playwright_api/frame.rb +119 -11
  43. data/lib/playwright_api/frame_locator.rb +113 -5
  44. data/lib/playwright_api/js_handle.rb +7 -7
  45. data/lib/playwright_api/keyboard.rb +1 -1
  46. data/lib/playwright_api/locator.rb +145 -6
  47. data/lib/playwright_api/page.rb +133 -16
  48. data/lib/playwright_api/playwright.rb +6 -6
  49. data/lib/playwright_api/request.rb +9 -9
  50. data/lib/playwright_api/response.rb +8 -8
  51. data/lib/playwright_api/route.rb +6 -6
  52. data/lib/playwright_api/selectors.rb +14 -3
  53. data/lib/playwright_api/tracing.rb +7 -7
  54. data/lib/playwright_api/web_socket.rb +6 -6
  55. data/lib/playwright_api/worker.rb +8 -8
  56. metadata +5 -4
@@ -4,7 +4,7 @@ module Playwright
4
4
  # [`method: Locator.frameLocator`] method.
5
5
  #
6
6
  # ```python sync
7
- # locator = page.frame_locator("my-frame").locator("text=Submit")
7
+ # locator = page.frame_locator("my-frame").get_by_text("Submit")
8
8
  # locator.click()
9
9
  # ```
10
10
  #
@@ -15,10 +15,10 @@ module Playwright
15
15
  #
16
16
  # ```python sync
17
17
  # # Throws if there are several frames in DOM:
18
- # page.frame_locator('.result-frame').locator('button').click()
18
+ # page.frame_locator('.result-frame').get_by_role('button').click()
19
19
  #
20
20
  # # Works because we explicitly tell locator to pick the first frame:
21
- # page.frame_locator('.result-frame').first.locator('button').click()
21
+ # page.frame_locator('.result-frame').first.get_by_role('button').click()
22
22
  # ```
23
23
  #
24
24
  # **Converting Locator to FrameLocator**
@@ -27,7 +27,7 @@ module Playwright
27
27
  # [`:scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/:scope) CSS selector:
28
28
  #
29
29
  # ```python sync
30
- # frameLocator = locator.frame_locator(":scope");
30
+ # frameLocator = locator.frame_locator(":scope")
31
31
  # ```
32
32
  class FrameLocator < PlaywrightApi
33
33
 
@@ -42,12 +42,120 @@ module Playwright
42
42
  wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
43
43
  end
44
44
 
45
+ # Allows locating elements by their alt text. For example, this method will find the image by alt text "Castle":
46
+ #
47
+ # ```html
48
+ # <img alt='Castle'>
49
+ # ```
50
+ def get_by_alt_text(text, exact: nil)
51
+ wrap_impl(@impl.get_by_alt_text(unwrap_impl(text), exact: unwrap_impl(exact)))
52
+ end
53
+
54
+ # Allows locating input elements by the text of the associated label. For example, this method will find the input by
55
+ # label text "Password" in the following DOM:
56
+ #
57
+ # ```html
58
+ # <label for="password-input">Password:</label>
59
+ # <input id="password-input">
60
+ # ```
61
+ def get_by_label(text, exact: nil)
62
+ wrap_impl(@impl.get_by_label(unwrap_impl(text), exact: unwrap_impl(exact)))
63
+ end
64
+
65
+ # Allows locating input elements by the placeholder text. For example, this method will find the input by placeholder
66
+ # "Country":
67
+ #
68
+ # ```html
69
+ # <input placeholder="Country">
70
+ # ```
71
+ def get_by_placeholder(text, exact: nil)
72
+ wrap_impl(@impl.get_by_placeholder(unwrap_impl(text), exact: unwrap_impl(exact)))
73
+ end
74
+
75
+ # Allows locating elements by their [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles),
76
+ # [ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and
77
+ # [accessible name](https://w3c.github.io/accname/#dfn-accessible-name). Note that role selector **does not replace**
78
+ # accessibility audits and conformance tests, but rather gives early feedback about the ARIA guidelines.
79
+ #
80
+ # Note that many html elements have an implicitly
81
+ # [defined role](https://w3c.github.io/html-aam/#html-element-role-mappings) that is recognized by the role selector. You
82
+ # can find all the [supported roles here](https://www.w3.org/TR/wai-aria-1.2/#role_definitions). ARIA guidelines **do not
83
+ # recommend** duplicating implicit roles and attributes by setting `role` and/or `aria-*` attributes to default values.
84
+ def get_by_role(
85
+ role,
86
+ checked: nil,
87
+ disabled: nil,
88
+ exact: nil,
89
+ expanded: nil,
90
+ includeHidden: nil,
91
+ level: nil,
92
+ name: nil,
93
+ pressed: nil,
94
+ selected: nil)
95
+ wrap_impl(@impl.get_by_role(unwrap_impl(role), checked: unwrap_impl(checked), disabled: unwrap_impl(disabled), exact: unwrap_impl(exact), expanded: unwrap_impl(expanded), includeHidden: unwrap_impl(includeHidden), level: unwrap_impl(level), name: unwrap_impl(name), pressed: unwrap_impl(pressed), selected: unwrap_impl(selected)))
96
+ end
97
+
98
+ # Locate element by the test id. By default, the `data-testid` attribute is used as a test id. Use
99
+ # [`method: Selectors.setTestIdAttribute`] to configure a different test id attribute if necessary.
100
+ def get_by_test_id(testId)
101
+ wrap_impl(@impl.get_by_test_id(unwrap_impl(testId)))
102
+ end
103
+
104
+ # Allows locating elements that contain given text. Consider the following DOM structure:
105
+ #
106
+ # ```html
107
+ # <div>Hello <span>world</span></div>
108
+ # <div>Hello</div>
109
+ # ```
110
+ #
111
+ # You can locate by text substring, exact string, or a regular expression:
112
+ #
113
+ # ```python sync
114
+ # # Matches <span>
115
+ # page.get_by_text("world")
116
+ #
117
+ # # Matches first <div>
118
+ # page.get_by_text("Hello world")
119
+ #
120
+ # # Matches second <div>
121
+ # page.get_by_text("Hello", exact=True)
122
+ #
123
+ # # Matches both <div>s
124
+ # page.get_by_text(re.compile("Hello"))
125
+ #
126
+ # # Matches second <div>
127
+ # page.get_by_text(re.compile("^hello$", re.IGNORECASE))
128
+ # ```
129
+ #
130
+ # See also [`method: Locator.filter`] that allows to match by another criteria, like an accessible role, and then filter
131
+ # by the text content.
132
+ #
133
+ # > NOTE: Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into
134
+ # one, turns line breaks into spaces and ignores leading and trailing whitespace.
135
+ # > NOTE: Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For
136
+ # example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
137
+ def get_by_text(text, exact: nil)
138
+ wrap_impl(@impl.get_by_text(unwrap_impl(text), exact: unwrap_impl(exact)))
139
+ end
140
+
141
+ # Allows locating elements by their title. For example, this method will find the button by its title "Place the order":
142
+ #
143
+ # ```html
144
+ # <button title='Place the order'>Order Now</button>
145
+ # ```
146
+ def get_by_title(text, exact: nil)
147
+ wrap_impl(@impl.get_by_title(unwrap_impl(text), exact: unwrap_impl(exact)))
148
+ end
149
+
45
150
  # Returns locator to the last matching frame.
46
151
  def last
47
152
  wrap_impl(@impl.last)
48
153
  end
49
154
 
50
- # The method finds an element matching the specified selector in the FrameLocator's subtree.
155
+ # The method finds an element matching the specified selector in the locator's subtree. It also accepts filter options,
156
+ # similar to [`method: Locator.filter`] method.
157
+ #
158
+ # [Learn more about locators](../locators.md).
51
159
  def locator(selector, has: nil, hasText: nil)
52
160
  wrap_impl(@impl.locator(unwrap_impl(selector), has: unwrap_impl(has), hasText: unwrap_impl(hasText)))
53
161
  end
@@ -59,7 +59,7 @@ module Playwright
59
59
  # The method returns a map with **own property names** as keys and JSHandle instances for the property values.
60
60
  #
61
61
  # ```python sync
62
- # handle = page.evaluate_handle("{window, document}")
62
+ # handle = page.evaluate_handle("({window, document})")
63
63
  # properties = handle.get_properties()
64
64
  # window_handle = properties.get("window")
65
65
  # document_handle = properties.get("document")
@@ -88,12 +88,6 @@ module Playwright
88
88
  wrap_impl(@impl.to_s)
89
89
  end
90
90
 
91
- # -- inherited from EventEmitter --
92
- # @nodoc
93
- def off(event, callback)
94
- event_emitter_proxy.off(event, callback)
95
- end
96
-
97
91
  # -- inherited from EventEmitter --
98
92
  # @nodoc
99
93
  def once(event, callback)
@@ -106,6 +100,12 @@ module Playwright
106
100
  event_emitter_proxy.on(event, callback)
107
101
  end
108
102
 
103
+ # -- inherited from EventEmitter --
104
+ # @nodoc
105
+ def off(event, callback)
106
+ event_emitter_proxy.off(event, callback)
107
+ end
108
+
109
109
  private def event_emitter_proxy
110
110
  @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
111
111
  end
@@ -1,6 +1,6 @@
1
1
  module Playwright
2
2
  # Keyboard provides an api for managing a virtual keyboard. The high level api is [`method: Keyboard.type`], which takes
3
- # raw characters and generates proper keydown, keypress/input, and keyup events on your page.
3
+ # raw characters and generates proper `keydown`, `keypress`/`input`, and `keyup` events on your page.
4
4
  #
5
5
  # For finer control, you can use [`method: Keyboard.down`], [`method: Keyboard.up`], and [`method: Keyboard.insertText`]
6
6
  # to manually fire events as if they were generated from a real keyboard.
@@ -15,6 +15,11 @@ module Playwright
15
15
  wrap_impl(@impl.all_text_contents)
16
16
  end
17
17
 
18
+ # Calls [blur](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur) on the element.
19
+ def blur(timeout: nil)
20
+ wrap_impl(@impl.blur(timeout: unwrap_impl(timeout)))
21
+ end
22
+
18
23
  # This method returns the bounding box of the element, or `null` if the element is not visible. The bounding box is
19
24
  # calculated relative to the main frame viewport - which is usually the same as the browser window.
20
25
  #
@@ -58,6 +63,17 @@ module Playwright
58
63
  wrap_impl(@impl.check(force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
59
64
  end
60
65
 
66
+ # This method waits for [actionability](../actionability.md) checks, focuses the element, clears it and triggers an
67
+ # `input` event after clearing.
68
+ #
69
+ # If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error.
70
+ # However, if the element is inside the `<label>` element that has an associated
71
+ # [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be cleared
72
+ # instead.
73
+ def clear(force: nil, noWaitAfter: nil, timeout: nil)
74
+ wrap_impl(@impl.clear(force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
75
+ end
76
+
61
77
  # This method clicks the element by performing the following steps:
62
78
  # 1. Wait for [actionability](../actionability.md) checks on the element, unless `force` option is set.
63
79
  # 1. Scroll the element into view if needed.
@@ -142,6 +158,21 @@ module Playwright
142
158
  wrap_impl(@impl.dispatch_event(unwrap_impl(type), eventInit: unwrap_impl(eventInit), timeout: unwrap_impl(timeout)))
143
159
  end
144
160
 
161
+ # This method drags the locator to another target locator or target position. It will first move to the source element,
162
+ # perform a `mousedown`, then move to the target element or position and perform a `mouseup`.
163
+ #
164
+ # ```python sync
165
+ # source = page.locator("#source")
166
+ # target = page.locator("#target")
167
+ #
168
+ # source.drag_to(target)
169
+ # # or specify exact positions relative to the top-left corners of the elements:
170
+ # source.drag_to(
171
+ # target,
172
+ # source_position={"x": 34, "y": 7},
173
+ # target_position={"x": 10, "y": 20}
174
+ # )
175
+ # ```
145
176
  def drag_to(
146
177
  target,
147
178
  force: nil,
@@ -232,7 +263,7 @@ module Playwright
232
263
  # # ...
233
264
  # row_locator
234
265
  # .filter(has_text="text in column 1")
235
- # .filter(has=page.locator("tr", has_text="column 2 button"))
266
+ # .filter(has=page.get_by_role("button", name="column 2 button"))
236
267
  # .screenshot()
237
268
  # ```
238
269
  def filter(has: nil, hasText: nil)
@@ -253,7 +284,7 @@ module Playwright
253
284
  # that iframe:
254
285
  #
255
286
  # ```python sync
256
- # locator = page.frame_locator("iframe").locator("text=Submit")
287
+ # locator = page.frame_locator("iframe").get_by_text("Submit")
257
288
  # locator.click()
258
289
  # ```
259
290
  def frame_locator(selector)
@@ -266,6 +297,111 @@ module Playwright
266
297
  end
267
298
  alias_method :[], :get_attribute
268
299
 
300
+ # Allows locating elements by their alt text. For example, this method will find the image by alt text "Castle":
301
+ #
302
+ # ```html
303
+ # <img alt='Castle'>
304
+ # ```
305
+ def get_by_alt_text(text, exact: nil)
306
+ wrap_impl(@impl.get_by_alt_text(unwrap_impl(text), exact: unwrap_impl(exact)))
307
+ end
308
+
309
+ # Allows locating input elements by the text of the associated label. For example, this method will find the input by
310
+ # label text "Password" in the following DOM:
311
+ #
312
+ # ```html
313
+ # <label for="password-input">Password:</label>
314
+ # <input id="password-input">
315
+ # ```
316
+ def get_by_label(text, exact: nil)
317
+ wrap_impl(@impl.get_by_label(unwrap_impl(text), exact: unwrap_impl(exact)))
318
+ end
319
+
320
+ # Allows locating input elements by the placeholder text. For example, this method will find the input by placeholder
321
+ # "Country":
322
+ #
323
+ # ```html
324
+ # <input placeholder="Country">
325
+ # ```
326
+ def get_by_placeholder(text, exact: nil)
327
+ wrap_impl(@impl.get_by_placeholder(unwrap_impl(text), exact: unwrap_impl(exact)))
328
+ end
329
+
330
+ # Allows locating elements by their [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles),
331
+ # [ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and
332
+ # [accessible name](https://w3c.github.io/accname/#dfn-accessible-name). Note that role selector **does not replace**
333
+ # accessibility audits and conformance tests, but rather gives early feedback about the ARIA guidelines.
334
+ #
335
+ # Note that many html elements have an implicitly
336
+ # [defined role](https://w3c.github.io/html-aam/#html-element-role-mappings) that is recognized by the role selector. You
337
+ # can find all the [supported roles here](https://www.w3.org/TR/wai-aria-1.2/#role_definitions). ARIA guidelines **do not
338
+ # recommend** duplicating implicit roles and attributes by setting `role` and/or `aria-*` attributes to default values.
339
+ def get_by_role(
340
+ role,
341
+ checked: nil,
342
+ disabled: nil,
343
+ exact: nil,
344
+ expanded: nil,
345
+ includeHidden: nil,
346
+ level: nil,
347
+ name: nil,
348
+ pressed: nil,
349
+ selected: nil)
350
+ wrap_impl(@impl.get_by_role(unwrap_impl(role), checked: unwrap_impl(checked), disabled: unwrap_impl(disabled), exact: unwrap_impl(exact), expanded: unwrap_impl(expanded), includeHidden: unwrap_impl(includeHidden), level: unwrap_impl(level), name: unwrap_impl(name), pressed: unwrap_impl(pressed), selected: unwrap_impl(selected)))
351
+ end
352
+
353
+ # Locate element by the test id. By default, the `data-testid` attribute is used as a test id. Use
354
+ # [`method: Selectors.setTestIdAttribute`] to configure a different test id attribute if necessary.
355
+ def get_by_test_id(testId)
356
+ wrap_impl(@impl.get_by_test_id(unwrap_impl(testId)))
357
+ end
358
+
359
+ # Allows locating elements that contain given text. Consider the following DOM structure:
360
+ #
361
+ # ```html
362
+ # <div>Hello <span>world</span></div>
363
+ # <div>Hello</div>
364
+ # ```
365
+ #
366
+ # You can locate by text substring, exact string, or a regular expression:
367
+ #
368
+ # ```python sync
369
+ # # Matches <span>
370
+ # page.get_by_text("world")
371
+ #
372
+ # # Matches first <div>
373
+ # page.get_by_text("Hello world")
374
+ #
375
+ # # Matches second <div>
376
+ # page.get_by_text("Hello", exact=True)
377
+ #
378
+ # # Matches both <div>s
379
+ # page.get_by_text(re.compile("Hello"))
380
+ #
381
+ # # Matches second <div>
382
+ # page.get_by_text(re.compile("^hello$", re.IGNORECASE))
383
+ # ```
384
+ #
385
+ # See also [`method: Locator.filter`] that allows to match by another criteria, like an accessible role, and then filter
386
+ # by the text content.
387
+ #
388
+ # > NOTE: Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into
389
+ # one, turns line breaks into spaces and ignores leading and trailing whitespace.
390
+ # > NOTE: Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For
391
+ # example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
392
+ def get_by_text(text, exact: nil)
393
+ wrap_impl(@impl.get_by_text(unwrap_impl(text), exact: unwrap_impl(exact)))
394
+ end
395
+
396
+ # Allows locating elements by their title. For example, this method will find the button by its title "Place the order":
397
+ #
398
+ # ```html
399
+ # <button title='Place the order'>Order Now</button>
400
+ # ```
401
+ def get_by_title(text, exact: nil)
402
+ wrap_impl(@impl.get_by_title(unwrap_impl(text), exact: unwrap_impl(exact)))
403
+ end
404
+
269
405
  # Highlight the corresponding element(s) on the screen. Useful for debugging, don't commit the code that uses
270
406
  # [`method: Locator.highlight`].
271
407
  def highlight
@@ -285,10 +421,11 @@ module Playwright
285
421
  def hover(
286
422
  force: nil,
287
423
  modifiers: nil,
424
+ noWaitAfter: nil,
288
425
  position: nil,
289
426
  timeout: nil,
290
427
  trial: nil)
291
- wrap_impl(@impl.hover(force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), position: unwrap_impl(position), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
428
+ wrap_impl(@impl.hover(force: unwrap_impl(force), modifiers: unwrap_impl(modifiers), noWaitAfter: unwrap_impl(noWaitAfter), position: unwrap_impl(position), timeout: unwrap_impl(timeout), trial: unwrap_impl(trial)))
292
429
  end
293
430
 
294
431
  # Returns the `element.innerHTML`.
@@ -344,8 +481,10 @@ module Playwright
344
481
  wrap_impl(@impl.last)
345
482
  end
346
483
 
347
- # The method finds an element matching the specified selector in the `Locator`'s subtree. It also accepts filter options,
484
+ # The method finds an element matching the specified selector in the locator's subtree. It also accepts filter options,
348
485
  # similar to [`method: Locator.filter`] method.
486
+ #
487
+ # [Learn more about locators](../locators.md).
349
488
  def locator(selector, has: nil, hasText: nil)
350
489
  wrap_impl(@impl.locator(unwrap_impl(selector), has: unwrap_impl(has), hasText: unwrap_impl(hasText)))
351
490
  end
@@ -524,8 +663,8 @@ module Playwright
524
663
  # An example of typing into a text field and then submitting the form:
525
664
  #
526
665
  # ```python sync
527
- # element = page.locator("input")
528
- # element.type("some text")
666
+ # element = page.get_by_label("Password")
667
+ # element.type("my password")
529
668
  # element.press("Enter")
530
669
  # ```
531
670
  def type(text, delay: nil, noWaitAfter: nil, timeout: nil)
@@ -250,6 +250,19 @@ module Playwright
250
250
  wrap_impl(@impl.dispatch_event(unwrap_impl(selector), unwrap_impl(type), eventInit: unwrap_impl(eventInit), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
251
251
  end
252
252
 
253
+ # This method drags the source element to the target element. It will first move to the source element, perform a
254
+ # `mousedown`, then move to the target element and perform a `mouseup`.
255
+ #
256
+ # ```python sync
257
+ # page.drag_and_drop("#source", "#target")
258
+ # # or specify exact positions relative to the top-left corners of the elements:
259
+ # page.drag_and_drop(
260
+ # "#source",
261
+ # "#target",
262
+ # source_position={"x": 34, "y": 7},
263
+ # target_position={"x": 10, "y": 20}
264
+ # )
265
+ # ```
253
266
  def drag_and_drop(
254
267
  source,
255
268
  target,
@@ -553,7 +566,7 @@ module Playwright
553
566
  # id="my-frame">`:
554
567
  #
555
568
  # ```python sync
556
- # locator = page.frame_locator("#my-iframe").locator("text=Submit")
569
+ # locator = page.frame_locator("#my-iframe").get_by_text("Submit")
557
570
  # locator.click()
558
571
  # ```
559
572
  def frame_locator(selector)
@@ -570,6 +583,111 @@ module Playwright
570
583
  wrap_impl(@impl.get_attribute(unwrap_impl(selector), unwrap_impl(name), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
571
584
  end
572
585
 
586
+ # Allows locating elements by their alt text. For example, this method will find the image by alt text "Castle":
587
+ #
588
+ # ```html
589
+ # <img alt='Castle'>
590
+ # ```
591
+ def get_by_alt_text(text, exact: nil)
592
+ wrap_impl(@impl.get_by_alt_text(unwrap_impl(text), exact: unwrap_impl(exact)))
593
+ end
594
+
595
+ # Allows locating input elements by the text of the associated label. For example, this method will find the input by
596
+ # label text "Password" in the following DOM:
597
+ #
598
+ # ```html
599
+ # <label for="password-input">Password:</label>
600
+ # <input id="password-input">
601
+ # ```
602
+ def get_by_label(text, exact: nil)
603
+ wrap_impl(@impl.get_by_label(unwrap_impl(text), exact: unwrap_impl(exact)))
604
+ end
605
+
606
+ # Allows locating input elements by the placeholder text. For example, this method will find the input by placeholder
607
+ # "Country":
608
+ #
609
+ # ```html
610
+ # <input placeholder="Country">
611
+ # ```
612
+ def get_by_placeholder(text, exact: nil)
613
+ wrap_impl(@impl.get_by_placeholder(unwrap_impl(text), exact: unwrap_impl(exact)))
614
+ end
615
+
616
+ # Allows locating elements by their [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles),
617
+ # [ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and
618
+ # [accessible name](https://w3c.github.io/accname/#dfn-accessible-name). Note that role selector **does not replace**
619
+ # accessibility audits and conformance tests, but rather gives early feedback about the ARIA guidelines.
620
+ #
621
+ # Note that many html elements have an implicitly
622
+ # [defined role](https://w3c.github.io/html-aam/#html-element-role-mappings) that is recognized by the role selector. You
623
+ # can find all the [supported roles here](https://www.w3.org/TR/wai-aria-1.2/#role_definitions). ARIA guidelines **do not
624
+ # recommend** duplicating implicit roles and attributes by setting `role` and/or `aria-*` attributes to default values.
625
+ def get_by_role(
626
+ role,
627
+ checked: nil,
628
+ disabled: nil,
629
+ exact: nil,
630
+ expanded: nil,
631
+ includeHidden: nil,
632
+ level: nil,
633
+ name: nil,
634
+ pressed: nil,
635
+ selected: nil)
636
+ wrap_impl(@impl.get_by_role(unwrap_impl(role), checked: unwrap_impl(checked), disabled: unwrap_impl(disabled), exact: unwrap_impl(exact), expanded: unwrap_impl(expanded), includeHidden: unwrap_impl(includeHidden), level: unwrap_impl(level), name: unwrap_impl(name), pressed: unwrap_impl(pressed), selected: unwrap_impl(selected)))
637
+ end
638
+
639
+ # Locate element by the test id. By default, the `data-testid` attribute is used as a test id. Use
640
+ # [`method: Selectors.setTestIdAttribute`] to configure a different test id attribute if necessary.
641
+ def get_by_test_id(testId)
642
+ wrap_impl(@impl.get_by_test_id(unwrap_impl(testId)))
643
+ end
644
+
645
+ # Allows locating elements that contain given text. Consider the following DOM structure:
646
+ #
647
+ # ```html
648
+ # <div>Hello <span>world</span></div>
649
+ # <div>Hello</div>
650
+ # ```
651
+ #
652
+ # You can locate by text substring, exact string, or a regular expression:
653
+ #
654
+ # ```python sync
655
+ # # Matches <span>
656
+ # page.get_by_text("world")
657
+ #
658
+ # # Matches first <div>
659
+ # page.get_by_text("Hello world")
660
+ #
661
+ # # Matches second <div>
662
+ # page.get_by_text("Hello", exact=True)
663
+ #
664
+ # # Matches both <div>s
665
+ # page.get_by_text(re.compile("Hello"))
666
+ #
667
+ # # Matches second <div>
668
+ # page.get_by_text(re.compile("^hello$", re.IGNORECASE))
669
+ # ```
670
+ #
671
+ # See also [`method: Locator.filter`] that allows to match by another criteria, like an accessible role, and then filter
672
+ # by the text content.
673
+ #
674
+ # > NOTE: Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into
675
+ # one, turns line breaks into spaces and ignores leading and trailing whitespace.
676
+ # > NOTE: Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For
677
+ # example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
678
+ def get_by_text(text, exact: nil)
679
+ wrap_impl(@impl.get_by_text(unwrap_impl(text), exact: unwrap_impl(exact)))
680
+ end
681
+
682
+ # Allows locating elements by their title. For example, this method will find the button by its title "Place the order":
683
+ #
684
+ # ```html
685
+ # <button title='Place the order'>Order Now</button>
686
+ # ```
687
+ def get_by_title(text, exact: nil)
688
+ wrap_impl(@impl.get_by_title(unwrap_impl(text), exact: unwrap_impl(exact)))
689
+ end
690
+
573
691
  # Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
574
692
  # last redirect. If can not go back, returns `null`.
575
693
  #
@@ -626,11 +744,12 @@ module Playwright
626
744
  selector,
627
745
  force: nil,
628
746
  modifiers: nil,
747
+ noWaitAfter: nil,
629
748
  position: nil,
630
749
  strict: nil,
631
750
  timeout: nil,
632
751
  trial: nil)
633
- 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)))
752
+ wrap_impl(@impl.hover(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)))
634
753
  end
635
754
 
636
755
  # Returns `element.innerHTML`.
@@ -688,13 +807,11 @@ module Playwright
688
807
  wrap_impl(@impl.visible?(unwrap_impl(selector), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
689
808
  end
690
809
 
691
- # The method returns an element locator that can be used to perform actions on the page. Locator is resolved to the
692
- # element immediately before performing an action, so a series of actions on the same locator can in fact be performed on
693
- # different DOM elements. That would happen if the DOM structure between those actions has changed.
810
+ # The method returns an element locator that can be used to perform actions on this page / frame. Locator is resolved to
811
+ # the element immediately before performing an action, so a series of actions on the same locator can in fact be performed
812
+ # on different DOM elements. That would happen if the DOM structure between those actions has changed.
694
813
  #
695
814
  # [Learn more about locators](../locators.md).
696
- #
697
- # Shortcut for main frame's [`method: Frame.locator`].
698
815
  def locator(selector, has: nil, hasText: nil)
699
816
  wrap_impl(@impl.locator(unwrap_impl(selector), has: unwrap_impl(has), hasText: unwrap_impl(hasText)))
700
817
  end
@@ -1177,7 +1294,7 @@ module Playwright
1177
1294
  #
1178
1295
  # ```python sync
1179
1296
  # with page.expect_event("framenavigated") as event_info:
1180
- # page.click("button")
1297
+ # page.get_by_role("button")
1181
1298
  # frame = event_info.value
1182
1299
  # ```
1183
1300
  def expect_event(event, predicate: nil, timeout: nil, &block)
@@ -1228,13 +1345,13 @@ module Playwright
1228
1345
  # when this method is called. If current document has already reached the required state, resolves immediately.
1229
1346
  #
1230
1347
  # ```python sync
1231
- # page.click("button") # click triggers navigation.
1348
+ # page.get_by_role("button").click() # click triggers navigation.
1232
1349
  # page.wait_for_load_state() # the promise resolves after "load" event.
1233
1350
  # ```
1234
1351
  #
1235
1352
  # ```python sync
1236
1353
  # with page.expect_popup() as page_info:
1237
- # page.click("button") # click triggers a popup.
1354
+ # page.get_by_role("button").click() # click triggers a popup.
1238
1355
  # popup = page_info.value
1239
1356
  # # Following resolves after "domcontentloaded" event.
1240
1357
  # popup.wait_for_load_state("domcontentloaded")
@@ -1437,12 +1554,6 @@ module Playwright
1437
1554
  wrap_impl(@impl.stop_css_coverage)
1438
1555
  end
1439
1556
 
1440
- # -- inherited from EventEmitter --
1441
- # @nodoc
1442
- def off(event, callback)
1443
- event_emitter_proxy.off(event, callback)
1444
- end
1445
-
1446
1557
  # -- inherited from EventEmitter --
1447
1558
  # @nodoc
1448
1559
  def once(event, callback)
@@ -1455,6 +1566,12 @@ module Playwright
1455
1566
  event_emitter_proxy.on(event, callback)
1456
1567
  end
1457
1568
 
1569
+ # -- inherited from EventEmitter --
1570
+ # @nodoc
1571
+ def off(event, callback)
1572
+ event_emitter_proxy.off(event, callback)
1573
+ end
1574
+
1458
1575
  private def event_emitter_proxy
1459
1576
  @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
1460
1577
  end
@@ -96,12 +96,6 @@ module Playwright
96
96
  wrap_impl(@impl.electron)
97
97
  end
98
98
 
99
- # -- inherited from EventEmitter --
100
- # @nodoc
101
- def off(event, callback)
102
- event_emitter_proxy.off(event, callback)
103
- end
104
-
105
99
  # -- inherited from EventEmitter --
106
100
  # @nodoc
107
101
  def once(event, callback)
@@ -114,6 +108,12 @@ module Playwright
114
108
  event_emitter_proxy.on(event, callback)
115
109
  end
116
110
 
111
+ # -- inherited from EventEmitter --
112
+ # @nodoc
113
+ def off(event, callback)
114
+ event_emitter_proxy.off(event, callback)
115
+ end
116
+
117
117
  private def event_emitter_proxy
118
118
  @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
119
119
  end