playwright-ruby-client 1.37.1 → 1.39.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -7
  3. data/documentation/docs/api/browser.md +13 -9
  4. data/documentation/docs/api/browser_context.md +51 -32
  5. data/documentation/docs/api/browser_type.md +12 -7
  6. data/documentation/docs/api/dialog.md +18 -15
  7. data/documentation/docs/api/download.md +17 -7
  8. data/documentation/docs/api/element_handle.md +7 -19
  9. data/documentation/docs/api/frame.md +55 -30
  10. data/documentation/docs/api/keyboard.md +4 -0
  11. data/documentation/docs/api/locator.md +57 -16
  12. data/documentation/docs/api/page.md +102 -54
  13. data/documentation/docs/api/playwright.md +23 -20
  14. data/documentation/docs/api/request.md +17 -0
  15. data/documentation/docs/api/selectors.md +34 -29
  16. data/documentation/docs/include/api_coverage.md +1 -0
  17. data/lib/playwright/channel.rb +8 -0
  18. data/lib/playwright/channel_owner.rb +7 -2
  19. data/lib/playwright/channel_owners/browser_context.rb +16 -1
  20. data/lib/playwright/channel_owners/local_utils.rb +27 -0
  21. data/lib/playwright/channel_owners/page.rb +2 -0
  22. data/lib/playwright/channel_owners/playwright.rb +1 -24
  23. data/lib/playwright/channel_owners/request.rb +17 -1
  24. data/lib/playwright/channel_owners/route.rb +5 -1
  25. data/lib/playwright/connection.rb +1 -1
  26. data/lib/playwright/console_message_impl.rb +29 -0
  27. data/lib/playwright/errors.rb +13 -2
  28. data/lib/playwright/events.rb +1 -0
  29. data/lib/playwright/javascript/value_parser.rb +8 -0
  30. data/lib/playwright/javascript/value_serializer.rb +10 -4
  31. data/lib/playwright/locator_impl.rb +4 -0
  32. data/lib/playwright/utils.rb +4 -0
  33. data/lib/playwright/version.rb +2 -2
  34. data/lib/playwright_api/browser.rb +2 -2
  35. data/lib/playwright_api/browser_context.rb +4 -4
  36. data/lib/playwright_api/browser_type.rb +2 -2
  37. data/lib/playwright_api/console_message.rb +0 -22
  38. data/lib/playwright_api/dialog.rb +2 -2
  39. data/lib/playwright_api/download.rb +12 -3
  40. data/lib/playwright_api/element_handle.rb +2 -15
  41. data/lib/playwright_api/frame.rb +8 -13
  42. data/lib/playwright_api/keyboard.rb +4 -0
  43. data/lib/playwright_api/locator.rb +52 -16
  44. data/lib/playwright_api/page.rb +24 -29
  45. data/lib/playwright_api/playwright.rb +4 -4
  46. data/lib/playwright_api/request.rb +17 -0
  47. data/lib/playwright_api/selectors.rb +2 -2
  48. data/lib/playwright_api/worker.rb +4 -4
  49. data/sig/playwright.rbs +1 -0
  50. metadata +4 -4
  51. data/lib/playwright/channel_owners/console_message.rb +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00d50bbadac84d3bfa4881ee450991e7e0999c9ca5daab2343bceb885d90522b
4
- data.tar.gz: 16bfdd05cc45587c02a89a9e9098c32a518c3e6b81e254524393e71b47483391
3
+ metadata.gz: a0dedf5c9cce96afd64ad16c45baed1b2c1fe37bb9b2632a741d8b75640bf2ae
4
+ data.tar.gz: 5f056dc5acd7bd5860c3ccaee1d7e5460923e9eb2a985c41ec1e36c8d8c91b7a
5
5
  SHA512:
6
- metadata.gz: 4e936a99c032fb86e7865cc8880c6679a23b2d621624a98b31d528a7c9d9886851b02b6cb9bab43937bf85b85a2d27ee2cbb0d15d25a11f2962066991531eac0
7
- data.tar.gz: 5e3c6c5bf4af0df7129d6c5ed1ebd6b29928ed68b10b698eb3385ac414c3a04a7ec4a96b964feffa6a65e2f96a7821c3dea8e5b841d186312a66ec1ad53ad825
6
+ metadata.gz: 82629797b234ab08abe2c9258605d0d7826eeaf3f4f70274e3f1ced8a5b41560ee1832f7ae98522ce7dfe1a826bd5058c88e9aba7f6d507d16bfa20d20206cea
7
+ data.tar.gz: '0027783e79287ba14021438154229a4de61c041c983a9f6fa582d533524df395bfb9cfaedbabf9e3d6be015a2ebed9a1fa03674bd86965f693bbd12bae9c67ce'
data/README.md CHANGED
@@ -51,18 +51,24 @@ Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwrigh
51
51
  page = browser.new_page
52
52
  page.goto('https://github.com/')
53
53
 
54
- form = page.query_selector("form.js-site-search-form")
55
- search_input = form.query_selector("input.header-search-input")
56
- search_input.click
54
+ page.get_by_placeholder("Search or jump to...").click
55
+ page.locator('input[name="query-builder-test"]').click
56
+
57
+ expect(page.keyboard).to be_a(::Playwright::Keyboard)
58
+
57
59
  page.keyboard.type("playwright")
58
60
  page.expect_navigation {
59
61
  page.keyboard.press("Enter")
60
62
  }
61
63
 
62
- list = page.query_selector("ul.repo-list")
63
- items = list.query_selector_all("div.f4")
64
- items.each do |item|
65
- title = item.eval_on_selector("a", "a => a.innerText")
64
+ list = page.get_by_test_id('results-list').locator('.search-title')
65
+
66
+ # wait for item to appear
67
+ list.first.wait_for
68
+
69
+ # list them
70
+ list.locator('.search-title').all.each do |item|
71
+ title = item.text_content
66
72
  puts("==> #{title}")
67
73
  end
68
74
  end
@@ -8,15 +8,19 @@ sidebar_position: 10
8
8
 
9
9
  A Browser is created via [BrowserType#launch](./browser_type#launch). An example of using a [Browser](./browser) to create a [Page](./page):
10
10
 
11
- ```ruby
12
- firefox = playwright.firefox
13
- browser = firefox.launch
14
- begin
15
- page = browser.new_page
16
- page.goto("https://example.com")
17
- ensure
18
- browser.close
19
- end
11
+ ```python sync title=example_5d31815545511b1d8ce5dfce5b153cb5ea46a1868cee95eb211d77f33026788b.py
12
+ from playwright.sync_api import sync_playwright, Playwright
13
+
14
+ def run(playwright: Playwright):
15
+ firefox = playwright.firefox
16
+ browser = firefox.launch()
17
+ page = browser.new_page()
18
+ page.goto("https://example.com")
19
+ browser.close()
20
+
21
+ with sync_playwright() as playwright:
22
+ run(playwright)
23
+
20
24
  ```
21
25
 
22
26
  ## browser_type
@@ -158,21 +158,29 @@ See [Page#expose_binding](./page#expose_binding) for page-only version.
158
158
 
159
159
  An example of exposing page URL to all frames in all pages in the context:
160
160
 
161
- ```ruby
162
- browser_context.expose_binding("pageURL", ->(source) { source[:page].url })
163
- page = browser_context.new_page
164
-
165
- page.content = <<~HTML
166
- <script>
167
- async function onClick() {
168
- document.querySelector('div').textContent = await window.pageURL();
169
- }
170
- </script>
171
- <button onclick="onClick()">Click me</button>
172
- <div></div>
173
- HTML
161
+ ```python sync title=example_a450852d36dda88564582371af8d87bb58b1a517aac4fa60b7a58a0e41c5ceff.py
162
+ from playwright.sync_api import sync_playwright, Playwright
163
+
164
+ def run(playwright: Playwright):
165
+ webkit = playwright.webkit
166
+ browser = webkit.launch(headless=false)
167
+ context = browser.new_context()
168
+ context.expose_binding("pageURL", lambda source: source["page"].url)
169
+ page = context.new_page()
170
+ page.set_content("""
171
+ <script>
172
+ async function onClick() {
173
+ document.querySelector('div').textContent = await window.pageURL();
174
+ }
175
+ </script>
176
+ <button onclick="onClick()">Click me</button>
177
+ <div></div>
178
+ """)
179
+ page.get_by_role("button").click()
180
+
181
+ with sync_playwright() as playwright:
182
+ run(playwright)
174
183
 
175
- page.get_by_role("button").click
176
184
  ```
177
185
 
178
186
  An example of passing an element handle:
@@ -217,25 +225,36 @@ See [Page#expose_function](./page#expose_function) for page-only version.
217
225
 
218
226
  An example of adding a `sha256` function to all pages in the context:
219
227
 
220
- ```ruby
221
- require 'digest'
222
-
223
- def sha256(text)
224
- Digest::SHA256.hexdigest(text)
225
- end
228
+ ```python sync title=example_714719de9c92e66678257180301c2512f8cd69185f53a5121b6c52194f61a871.py
229
+ import hashlib
230
+ from playwright.sync_api import sync_playwright
231
+
232
+ def sha256(text: str) -> str:
233
+ m = hashlib.sha256()
234
+ m.update(bytes(text, "utf8"))
235
+ return m.hexdigest()
236
+
237
+
238
+ def run(playwright: Playwright):
239
+ webkit = playwright.webkit
240
+ browser = webkit.launch(headless=False)
241
+ context = browser.new_context()
242
+ context.expose_function("sha256", sha256)
243
+ page = context.new_page()
244
+ page.set_content("""
245
+ <script>
246
+ async function onClick() {
247
+ document.querySelector('div').textContent = await window.sha256('PLAYWRIGHT');
248
+ }
249
+ </script>
250
+ <button onclick="onClick()">Click me</button>
251
+ <div></div>
252
+ """)
253
+ page.get_by_role("button").click()
254
+
255
+ with sync_playwright() as playwright:
256
+ run(playwright)
226
257
 
227
- browser_context.expose_function("sha256", method(:sha256))
228
- page = browser_context.new_page()
229
- page.content = <<~HTML
230
- <script>
231
- async function onClick() {
232
- document.querySelector('div').textContent = await window.sha256('PLAYWRIGHT');
233
- }
234
- </script>
235
- <button onclick="onClick()">Click me</button>
236
- <div></div>
237
- HTML
238
- page.get_by_role("button").click
239
258
  ```
240
259
 
241
260
  ## grant_permissions
@@ -8,15 +8,20 @@ sidebar_position: 10
8
8
  BrowserType provides methods to launch a specific browser instance or connect to an existing one. The following is a
9
9
  typical example of using Playwright to drive automation:
10
10
 
11
- ```ruby
12
- chromium = playwright.chromium
13
- chromium.launch do |browser|
14
- page = browser.new_page
15
- page.goto('https://example.com/')
11
+ ```python sync title=example_2f9fbff87f35af4b76a27f54efeca3201696bbfa94ce03fee5a3df2639cc27d3.py
12
+ from playwright.sync_api import sync_playwright, Playwright
13
+
14
+ def run(playwright: Playwright):
15
+ chromium = playwright.chromium
16
+ browser = chromium.launch()
17
+ page = browser.new_page()
18
+ page.goto("https://example.com")
19
+ # other actions...
20
+ browser.close()
16
21
 
17
- # other actions
22
+ with sync_playwright() as playwright:
23
+ run(playwright)
18
24
 
19
- end
20
25
  ```
21
26
 
22
27
  ## connect_over_cdp
@@ -9,21 +9,24 @@ sidebar_position: 10
9
9
 
10
10
  An example of using [Dialog](./dialog) class:
11
11
 
12
- ```ruby
13
- def handle_dialog(dialog)
14
- puts "[#{dialog.type}] #{dialog.message}"
15
- if dialog.message =~ /foo/
16
- dialog.accept
17
- else
18
- dialog.dismiss
19
- end
20
- end
21
-
22
- page.on("dialog", method(:handle_dialog))
23
- page.evaluate("confirm('foo')") # will be accepted
24
- # => [confirm] foo
25
- page.evaluate("alert('bar')") # will be dismissed
26
- # => [alert] bar
12
+ ```python sync title=example_a7dcc75b7aa5544237ac3a964e9196d0445308864d3ce820f8cb8396f687b04a.py
13
+ from playwright.sync_api import sync_playwright, Playwright
14
+
15
+ def handle_dialog(dialog):
16
+ print(dialog.message)
17
+ dialog.dismiss()
18
+
19
+ def run(playwright: Playwright):
20
+ chromium = playwright.chromium
21
+ browser = chromium.launch()
22
+ page = browser.new_page()
23
+ page.on("dialog", handle_dialog)
24
+ page.evaluate("alert('1')")
25
+ browser.close()
26
+
27
+ with sync_playwright() as playwright:
28
+ run(playwright)
29
+
27
30
  ```
28
31
 
29
32
  **NOTE**: Dialogs are dismissed automatically, unless there is a [`event: Page.dialog`] listener.
@@ -10,15 +10,18 @@ sidebar_position: 10
10
10
  All the downloaded files belonging to the browser context are deleted when the
11
11
  browser context is closed.
12
12
 
13
- Download event is emitted once the download starts. Download path becomes available once download completes:
13
+ Download event is emitted once the download starts. Download path becomes available once download completes.
14
14
 
15
- ```ruby
16
- download = page.expect_download do
17
- page.get_by_text("Download file").click
18
- end
15
+ ```python sync title=example_c247767083cf193df26a39a61a3a8bc19d63ed5c24db91b88c50b7d37975005d.py
16
+ # Start waiting for the download
17
+ with page.expect_download() as download_info:
18
+ # Perform the action that initiates download
19
+ page.get_by_text("Download file").click()
20
+ download = download_info.value
21
+
22
+ # Wait for the download process to complete and save the downloaded file somewhere
23
+ download.save_as("/path/to/save/at/" + download.suggested_filename)
19
24
 
20
- # wait for download to complete
21
- path = download.path
22
25
  ```
23
26
 
24
27
  ## cancel
@@ -81,6 +84,13 @@ def save_as(path)
81
84
  Copy the download to a user-specified path. It is safe to call this method while the download
82
85
  is still in progress. Will wait for the download to finish if necessary.
83
86
 
87
+ **Usage**
88
+
89
+ ```python sync title=example_66ffd4ef7286957e4294d84b8f660ff852c87af27a56b3e4dd9f84562b5ece02.py
90
+ download.save_as("/path/to/save/at/" + download.suggested_filename)
91
+
92
+ ```
93
+
84
94
  ## suggested_filename
85
95
 
86
96
  ```
@@ -259,7 +259,7 @@ This method waits for [actionability](https://playwright.dev/python/docs/actiona
259
259
 
260
260
  If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
261
261
 
262
- To send fine-grained keyboard events, use [ElementHandle#type](./element_handle#type).
262
+ To send fine-grained keyboard events, use [Locator#press_sequentially](./locator#press_sequentially).
263
263
 
264
264
  ## focus
265
265
 
@@ -505,13 +505,14 @@ Triggers a `change` and `input` event once all the provided options have been se
505
505
 
506
506
  **Usage**
507
507
 
508
- ```ruby
509
- # single selection matching the value
510
- element_handle.select_option(value: "blue")
508
+ ```python sync title=example_e6bbc99e34c9f6ee73aa7d4265d34af456e6c67d185530f0a77f8064050a3ec4.py
509
+ # Single selection matching the value or label
510
+ handle.select_option("blue")
511
511
  # single selection matching both the label
512
- element_handle.select_option(label: "blue")
512
+ handle.select_option(label="blue")
513
513
  # multiple selection
514
- element_handle.select_option(value: ["red", "green", "blue"])
514
+ handle.select_option(value=["red", "green", "blue"])
515
+
515
516
  ```
516
517
 
517
518
  ## select_text
@@ -614,19 +615,6 @@ To press a special key, like `Control` or `ArrowDown`, use [ElementHandle#press]
614
615
 
615
616
  **Usage**
616
617
 
617
- ```ruby
618
- element_handle.type("hello") # types instantly
619
- element_handle.type("world", delay: 100) # types slower, like a user
620
- ```
621
-
622
- An example of typing into a text field and then submitting the form:
623
-
624
- ```ruby
625
- element_handle = page.query_selector("input")
626
- element_handle.type("some text")
627
- element_handle.press("Enter")
628
- ```
629
-
630
618
  ## uncheck
631
619
 
632
620
  ```
@@ -15,16 +15,25 @@ At every point of time, page exposes its current frame tree via the [Page#main_f
15
15
 
16
16
  An example of dumping frame tree:
17
17
 
18
- ```ruby
19
- def dump_frame_tree(frame, indent = 0)
20
- puts "#{' ' * indent}#{frame.name}@#{frame.url}"
21
- frame.child_frames.each do |child|
22
- dump_frame_tree(child, indent + 2)
23
- end
24
- end
18
+ ```python sync title=example_2bc8a0187190738d8dc7b29c66ad5f9f2187fd1827455e9ceb1e9ace26aaf534.py
19
+ from playwright.sync_api import sync_playwright, Playwright
20
+
21
+ def run(playwright: Playwright):
22
+ firefox = playwright.firefox
23
+ browser = firefox.launch()
24
+ page = browser.new_page()
25
+ page.goto("https://www.theverge.com")
26
+ dump_frame_tree(page.main_frame, "")
27
+ browser.close()
28
+
29
+ def dump_frame_tree(frame, indent):
30
+ print(indent + frame.name + '@' + frame.url)
31
+ for child in frame.child_frames:
32
+ dump_frame_tree(child, indent + " ")
33
+
34
+ with sync_playwright() as playwright:
35
+ run(playwright)
25
36
 
26
- page.goto("https://www.theverge.com")
27
- dump_frame_tree(page.main_frame)
28
37
  ```
29
38
 
30
39
  ## add_script_tag
@@ -349,7 +358,7 @@ This method waits for an element matching `selector`, waits for [actionability](
349
358
 
350
359
  If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
351
360
 
352
- To send fine-grained keyboard events, use [Frame#type](./frame#type).
361
+ To send fine-grained keyboard events, use [Locator#press_sequentially](./locator#press_sequentially).
353
362
 
354
363
  ## focus
355
364
 
@@ -911,13 +920,14 @@ Triggers a `change` and `input` event once all the provided options have been se
911
920
 
912
921
  **Usage**
913
922
 
914
- ```ruby
915
- # single selection matching the value
916
- frame.select_option("select#colors", value: "blue")
923
+ ```python sync title=example_3f390f340c78c42dd0c88a09b2f56575b02b163786e8cdee33581217afced6b2.py
924
+ # Single selection matching the value or label
925
+ frame.select_option("select#colors", "blue")
917
926
  # single selection matching both the label
918
- frame.select_option("select#colors", label: "blue")
927
+ frame.select_option("select#colors", label="blue")
919
928
  # multiple selection
920
- frame.select_option("select#colors", value: ["red", "green", "blue"])
929
+ frame.select_option("select#colors", value=["red", "green", "blue"])
930
+
921
931
  ```
922
932
 
923
933
  ## set_checked
@@ -1041,11 +1051,6 @@ To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./ke
1041
1051
 
1042
1052
  **Usage**
1043
1053
 
1044
- ```ruby
1045
- frame.type("#mytextarea", "hello") # types instantly
1046
- frame.type("#mytextarea", "world", delay: 100) # types slower, like a user
1047
- ```
1048
-
1049
1054
  ## uncheck
1050
1055
 
1051
1056
  ```
@@ -1094,9 +1099,20 @@ Returns when the `expression` returns a truthy value, returns that value.
1094
1099
 
1095
1100
  The [Frame#wait_for_function](./frame#wait_for_function) can be used to observe viewport size change:
1096
1101
 
1097
- ```ruby
1098
- frame.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
1099
- frame.wait_for_function("() => window.x > 0")
1102
+ ```python sync title=example_e6a8c279eb09e58e3522cb6237f5d62165b164cad0c1916720af299ffcb8dc8a.py
1103
+ from playwright.sync_api import sync_playwright, Playwright
1104
+
1105
+ def run(playwright: Playwright):
1106
+ webkit = playwright.webkit
1107
+ browser = webkit.launch()
1108
+ page = browser.new_page()
1109
+ page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
1110
+ page.main_frame.wait_for_function("() => window.x > 0")
1111
+ browser.close()
1112
+
1113
+ with sync_playwright() as playwright:
1114
+ run(playwright)
1115
+
1100
1116
  ```
1101
1117
 
1102
1118
  To pass an argument to the predicate of `frame.waitForFunction` function:
@@ -1172,13 +1188,22 @@ function will throw.
1172
1188
 
1173
1189
  This method works across navigations:
1174
1190
 
1175
- ```ruby
1176
- %w[https://google.com https://bbc.com].each do |current_url|
1177
- page.goto(current_url, waitUntil: "domcontentloaded")
1178
- frame = page.main_frame
1179
- element = frame.wait_for_selector("img")
1180
- puts "Loaded image: #{element["src"]}"
1181
- end
1191
+ ```python sync title=example_6e2a71807566cf008382d4c163ff6e71e34d7f10ef6706ad7fcaa9b70c256a66.py
1192
+ from playwright.sync_api import sync_playwright, Playwright
1193
+
1194
+ def run(playwright: Playwright):
1195
+ chromium = playwright.chromium
1196
+ browser = chromium.launch()
1197
+ page = browser.new_page()
1198
+ for current_url in ["https://google.com", "https://bbc.com"]:
1199
+ page.goto(current_url, wait_until="domcontentloaded")
1200
+ element = page.main_frame.wait_for_selector("img")
1201
+ print("Loaded image: " + str(element.get_attribute("src")))
1202
+ browser.close()
1203
+
1204
+ with sync_playwright() as playwright:
1205
+ run(playwright)
1206
+
1182
1207
  ```
1183
1208
 
1184
1209
  ## wait_for_timeout
@@ -97,6 +97,8 @@ def press(key, delay: nil)
97
97
  ```
98
98
 
99
99
 
100
+ **NOTE**: In most cases, you should use [Locator#press](./locator#press) instead.
101
+
100
102
  `key` can specify the intended
101
103
  [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to
102
104
  generate the text for. A superset of the `key` values can be found
@@ -136,6 +138,8 @@ def type(text, delay: nil)
136
138
  ```
137
139
 
138
140
 
141
+ **NOTE**: In most cases, you should use [Locator#fill](./locator#fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [Locator#press_sequentially](./locator#press_sequentially).
142
+
139
143
  Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
140
144
 
141
145
  To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./keyboard#press).
@@ -42,6 +42,8 @@ def all_inner_texts
42
42
 
43
43
  Returns an array of `node.innerText` values for all matching nodes.
44
44
 
45
+ **NOTE**: If you need to assert text on the page, prefer [`method: LocatorAssertions.toHaveText`] with `useInnerText` option to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
46
+
45
47
  **Usage**
46
48
 
47
49
  ```ruby
@@ -57,6 +59,8 @@ def all_text_contents
57
59
 
58
60
  Returns an array of `node.textContent` values for all matching nodes.
59
61
 
62
+ **NOTE**: If you need to assert text on the page, prefer [`method: LocatorAssertions.toHaveText`] to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
63
+
60
64
  **Usage**
61
65
 
62
66
  ```ruby
@@ -232,6 +236,8 @@ def count
232
236
 
233
237
  Returns the number of elements matching the locator.
234
238
 
239
+ **NOTE**: If you need to assert the number of elements on the page, prefer [`method: LocatorAssertions.toHaveCount`] to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
240
+
235
241
  **Usage**
236
242
 
237
243
  ```ruby
@@ -458,7 +464,7 @@ This method waits for [actionability](https://playwright.dev/python/docs/actiona
458
464
 
459
465
  If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
460
466
 
461
- To send fine-grained keyboard events, use [Locator#type](./locator#type).
467
+ To send fine-grained keyboard events, use [Locator#press_sequentially](./locator#press_sequentially).
462
468
 
463
469
  ## filter
464
470
 
@@ -526,6 +532,8 @@ alias: `[]`
526
532
 
527
533
  Returns the matching element's attribute value.
528
534
 
535
+ **NOTE**: If you need to assert an element's attribute, prefer [`method: LocatorAssertions.toHaveAttribute`] to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
536
+
529
537
  ## get_by_alt_text
530
538
 
531
539
  ```
@@ -808,6 +816,8 @@ def inner_text(timeout: nil)
808
816
 
809
817
  Returns the [`element.innerText`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText).
810
818
 
819
+ **NOTE**: If you need to assert text on the page, prefer [`method: LocatorAssertions.toHaveText`] with `useInnerText` option to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
820
+
811
821
  ## input_value
812
822
 
813
823
  ```
@@ -817,6 +827,8 @@ def input_value(timeout: nil)
817
827
 
818
828
  Returns the value for the matching `<input>` or `<textarea>` or `<select>` element.
819
829
 
830
+ **NOTE**: If you need to assert input value, prefer [`method: LocatorAssertions.toHaveValue`] to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
831
+
820
832
  **Usage**
821
833
 
822
834
  ```ruby
@@ -836,6 +848,8 @@ def checked?(timeout: nil)
836
848
 
837
849
  Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
838
850
 
851
+ **NOTE**: If you need to assert that checkbox is checked, prefer [`method: LocatorAssertions.toBeChecked`] to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
852
+
839
853
  **Usage**
840
854
 
841
855
  ```ruby
@@ -851,6 +865,8 @@ def disabled?(timeout: nil)
851
865
 
852
866
  Returns whether the element is disabled, the opposite of [enabled](https://playwright.dev/python/docs/actionability#enabled).
853
867
 
868
+ **NOTE**: If you need to assert that an element is disabled, prefer [`method: LocatorAssertions.toBeDisabled`] to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
869
+
854
870
  **Usage**
855
871
 
856
872
  ```ruby
@@ -866,6 +882,8 @@ def editable?(timeout: nil)
866
882
 
867
883
  Returns whether the element is [editable](https://playwright.dev/python/docs/actionability#editable).
868
884
 
885
+ **NOTE**: If you need to assert that an element is editable, prefer [`method: LocatorAssertions.toBeEditable`] to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
886
+
869
887
  **Usage**
870
888
 
871
889
  ```ruby
@@ -881,6 +899,8 @@ def enabled?(timeout: nil)
881
899
 
882
900
  Returns whether the element is [enabled](https://playwright.dev/python/docs/actionability#enabled).
883
901
 
902
+ **NOTE**: If you need to assert that an element is enabled, prefer [`method: LocatorAssertions.toBeEnabled`] to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
903
+
884
904
  **Usage**
885
905
 
886
906
  ```ruby
@@ -896,6 +916,8 @@ def hidden?(timeout: nil)
896
916
 
897
917
  Returns whether the element is hidden, the opposite of [visible](https://playwright.dev/python/docs/actionability#visible).
898
918
 
919
+ **NOTE**: If you need to assert that element is hidden, prefer [`method: LocatorAssertions.toBeHidden`] to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
920
+
899
921
  **Usage**
900
922
 
901
923
  ```ruby
@@ -911,6 +933,8 @@ def visible?(timeout: nil)
911
933
 
912
934
  Returns whether the element is [visible](https://playwright.dev/python/docs/actionability#visible).
913
935
 
936
+ **NOTE**: If you need to assert that element is visible, prefer [`method: LocatorAssertions.toBeVisible`] to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
937
+
914
938
  **Usage**
915
939
 
916
940
  ```ruby
@@ -1032,6 +1056,36 @@ respective texts.
1032
1056
  Shortcuts such as `key: "Control+o"` or `key: "Control+Shift+T"` are supported as well. When specified with the
1033
1057
  modifier, modifier is pressed and being held while the subsequent key is being pressed.
1034
1058
 
1059
+ ## press_sequentially
1060
+
1061
+ ```
1062
+ def press_sequentially(text, delay: nil, noWaitAfter: nil, timeout: nil)
1063
+ ```
1064
+
1065
+
1066
+ **NOTE**: In most cases, you should use [Locator#fill](./locator#fill) instead. You only need to press keys one by one if there is special keyboard handling on the page.
1067
+
1068
+ Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
1069
+
1070
+ To press a special key, like `Control` or `ArrowDown`, use [Locator#press](./locator#press).
1071
+
1072
+ **Usage**
1073
+
1074
+ ```python sync title=example_1b7781d5527574a18d4b9812e3461203d2acc9ba7e09cbfd0ffbc4154e3f5971.py
1075
+ locator.press_sequentially("hello") # types instantly
1076
+ locator.press_sequentially("world", delay=100) # types slower, like a user
1077
+
1078
+ ```
1079
+
1080
+ An example of typing into a text field and then submitting the form:
1081
+
1082
+ ```python sync title=example_cc0a6b9aa95b97e5c17c4b114da10a29c7f6f793e99aee1ea2703636af6e24f9.py
1083
+ locator = page.get_by_label("Password")
1084
+ locator.press_sequentially("my password")
1085
+ locator.press("Enter")
1086
+
1087
+ ```
1088
+
1035
1089
  ## screenshot
1036
1090
 
1037
1091
  ```
@@ -1247,6 +1301,8 @@ def text_content(timeout: nil)
1247
1301
 
1248
1302
  Returns the [`node.textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent).
1249
1303
 
1304
+ **NOTE**: If you need to assert text on the page, prefer [`method: LocatorAssertions.toHaveText`] to avoid flakiness. See [assertions guide](https://playwright.dev/python/docs/test-assertions) for more details.
1305
+
1250
1306
  ## type
1251
1307
 
1252
1308
  ```
@@ -1254,27 +1310,12 @@ def type(text, delay: nil, noWaitAfter: nil, timeout: nil)
1254
1310
  ```
1255
1311
 
1256
1312
 
1257
- **NOTE**: In most cases, you should use [Locator#fill](./locator#fill) instead. You only need to type characters if there is special keyboard handling on the page.
1258
-
1259
1313
  Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
1260
1314
 
1261
1315
  To press a special key, like `Control` or `ArrowDown`, use [Locator#press](./locator#press).
1262
1316
 
1263
1317
  **Usage**
1264
1318
 
1265
- ```ruby
1266
- element.type("hello") # types instantly
1267
- element.type("world", delay: 100) # types slower, like a user
1268
- ```
1269
-
1270
- An example of typing into a text field and then submitting the form:
1271
-
1272
- ```ruby
1273
- element = page.get_by_label("Password")
1274
- element.type("my password")
1275
- element.press("Enter")
1276
- ```
1277
-
1278
1319
  ## uncheck
1279
1320
 
1280
1321
  ```