playwright-ruby-client 0.9.0 → 1.14.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/accessibility.md +51 -1
  3. data/documentation/docs/api/browser_context.md +28 -0
  4. data/documentation/docs/api/element_handle.md +4 -5
  5. data/documentation/docs/api/experimental/android.md +15 -2
  6. data/documentation/docs/api/frame.md +66 -97
  7. data/documentation/docs/api/locator.md +28 -41
  8. data/documentation/docs/api/mouse.md +3 -4
  9. data/documentation/docs/api/page.md +41 -1
  10. data/documentation/docs/api/request.md +15 -19
  11. data/documentation/docs/api/touchscreen.md +8 -0
  12. data/documentation/docs/api/tracing.md +13 -12
  13. data/documentation/docs/api/worker.md +46 -8
  14. data/documentation/docs/article/guides/inspector.md +1 -1
  15. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +1 -1
  16. data/documentation/docs/article/guides/semi_automation.md +1 -1
  17. data/documentation/docs/article/guides/use_storage_state.md +78 -0
  18. data/documentation/docs/include/api_coverage.md +13 -13
  19. data/lib/playwright/accessibility_impl.rb +50 -0
  20. data/lib/playwright/channel_owners/browser_context.rb +45 -0
  21. data/lib/playwright/channel_owners/frame.rb +9 -0
  22. data/lib/playwright/channel_owners/page.rb +31 -2
  23. data/lib/playwright/channel_owners/request.rb +8 -8
  24. data/lib/playwright/channel_owners/worker.rb +23 -0
  25. data/lib/playwright/locator_impl.rb +3 -3
  26. data/lib/playwright/touchscreen_impl.rb +7 -0
  27. data/lib/playwright/tracing_impl.rb +9 -8
  28. data/lib/playwright/version.rb +1 -1
  29. data/lib/playwright_api/accessibility.rb +1 -1
  30. data/lib/playwright_api/android.rb +15 -2
  31. data/lib/playwright_api/browser_context.rb +8 -8
  32. data/lib/playwright_api/element_handle.rb +1 -1
  33. data/lib/playwright_api/frame.rb +5 -3
  34. data/lib/playwright_api/locator.rb +3 -3
  35. data/lib/playwright_api/page.rb +8 -6
  36. data/lib/playwright_api/touchscreen.rb +1 -1
  37. data/lib/playwright_api/worker.rb +13 -3
  38. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c0e5286a6e8faaa590ce17ed083f4e6f93c54fb6899571c5edc2a99c4148b15
4
- data.tar.gz: bccd47264ec992c5c901c94faf28ec346a606d75e4636ae80828e5d64a685bf0
3
+ metadata.gz: d6f164b2d4296ab3f30bfb22cd5fbec86ab522df916913ab19731dd452c55efa
4
+ data.tar.gz: 56371e88f29c8a7e7e398582a7cda693f45d8ebbb5bf6ce6e3fa0e748a2175bc
5
5
  SHA512:
6
- metadata.gz: c34792ec1bb838c99b5a540833c7e02c718147738d2b6129eb9ba63f53e6d6d1460e5abc62f9e94fecec2bc9dd07321c9badc1c4e4173ae0548151ebcbc38e12
7
- data.tar.gz: 12b99906a534b8ec3a5eef041824ec4d0357fe70e3a1c696dc4f11a95c1b54edbe8c7a5d67694c7b9dc846bd34fa6e18fbb3d84f241aa345a1d89c8af4ac4a39
6
+ metadata.gz: d97fd45d76a1cf4202be4aae7527974b01d8f90fd1de5e4fb4ed1267d3d3eeb601d5dddc49eb70559688c6bc816df82bc8c667e6aec7d2226ce078a2e0182a25
7
+ data.tar.gz: 602c97a88eb16aab95590391ae26f7ba777904668d4e270e3e24fe05122606d3f23d68901e529bb28b23a91458cdf7ce165de0c87621e0ad4ef9f8a711ccaf5f
@@ -4,4 +4,54 @@ sidebar_position: 10
4
4
 
5
5
  # Accessibility
6
6
 
7
- Not Implemented
7
+ The Accessibility class provides methods for inspecting Chromium's accessibility tree. The accessibility tree is used by
8
+ assistive technology such as [screen readers](https://en.wikipedia.org/wiki/Screen_reader) or
9
+ [switches](https://en.wikipedia.org/wiki/Switch_access).
10
+
11
+ Accessibility is a very platform-specific thing. On different platforms, there are different screen readers that might
12
+ have wildly different output.
13
+
14
+ Rendering engines of Chromium, Firefox and WebKit have a concept of "accessibility tree", which is then translated into
15
+ different platform-specific APIs. Accessibility namespace gives access to this Accessibility Tree.
16
+
17
+ Most of the accessibility tree gets filtered out when converting from internal browser AX Tree to Platform-specific
18
+ AX-Tree or by assistive technologies themselves. By default, Playwright tries to approximate this filtering, exposing
19
+ only the "interesting" nodes of the tree.
20
+
21
+ ## snapshot
22
+
23
+ ```
24
+ def snapshot(interestingOnly: nil, root: nil)
25
+ ```
26
+
27
+ Captures the current state of the accessibility tree. The returned object represents the root accessible node of the
28
+ page.
29
+
30
+ > NOTE: The Chromium accessibility tree contains nodes that go unused on most platforms and by most screen readers.
31
+ Playwright will discard them as well for an easier to process tree, unless `interestingOnly` is set to `false`.
32
+
33
+ An example of dumping the entire accessibility tree:
34
+
35
+ ```ruby
36
+ snapshot = page.accessibility.snapshot
37
+ puts snapshot
38
+ ```
39
+
40
+ An example of logging the focused node's name:
41
+
42
+ ```ruby
43
+ def find_focused_node(node)
44
+ if node['focused']
45
+ node
46
+ else
47
+ node['children']&.find do |child|
48
+ find_focused_node(child)
49
+ end
50
+ end
51
+ end
52
+
53
+ snapshot = page.accessibility.snapshot
54
+ node = find_focused_node(snapshot)
55
+ puts node['name']
56
+ ```
57
+
@@ -67,6 +67,16 @@ browser_context.add_init_script(path: "preload.js")
67
67
  > NOTE: The order of evaluation of multiple scripts installed via [BrowserContext#add_init_script](./browser_context#add_init_script) and
68
68
  [Page#add_init_script](./page#add_init_script) is not defined.
69
69
 
70
+ ## background_pages
71
+
72
+ ```
73
+ def background_pages
74
+ ```
75
+
76
+ > NOTE: Background pages are only supported on Chromium-based browsers.
77
+
78
+ All existing background pages in the context.
79
+
70
80
  ## browser
71
81
 
72
82
  ```
@@ -301,6 +311,16 @@ To remove a route with its handler you can use [BrowserContext#unroute](./browse
301
311
 
302
312
  > NOTE: Enabling routing disables http cache.
303
313
 
314
+ ## service_workers
315
+
316
+ ```
317
+ def service_workers
318
+ ```
319
+
320
+ > NOTE: Service workers are only supported on Chromium-based browsers.
321
+
322
+ All existing service workers in the context.
323
+
304
324
  ## set_default_navigation_timeout
305
325
 
306
326
  ```
@@ -369,6 +389,14 @@ alias: `offline=`
369
389
 
370
390
 
371
391
 
392
+ ## storage_state
393
+
394
+ ```
395
+ def storage_state(path: nil)
396
+ ```
397
+
398
+ Returns storage state for this browser context, contains current cookies and local storage snapshot.
399
+
372
400
  ## unroute
373
401
 
374
402
  ```
@@ -331,7 +331,7 @@ Returns the `element.innerText`.
331
331
  def input_value(timeout: nil)
332
332
  ```
333
333
 
334
- Returns `input.value` for `<input>` or `<textarea>` element. Throws for non-input elements.
334
+ Returns `input.value` for `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
335
335
 
336
336
  ## checked?
337
337
 
@@ -641,12 +641,11 @@ become visible/hidden). If at the moment of calling the method `selector` alread
641
641
  will return immediately. If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will
642
642
  throw.
643
643
 
644
- ```python sync title=example_3b0f6c6573db513b7b707a39d6c5bbf5ce5896b4785466d80f525968cfbd0be7.py
645
- page.set_content("<div><span></span></div>")
644
+ ```ruby
645
+ page.content = "<div><span></span></div>"
646
646
  div = page.query_selector("div")
647
647
  # waiting for the "span" selector relative to the div.
648
- span = div.wait_for_selector("span", state="attached")
649
-
648
+ span = div.wait_for_selector("span", state: "attached")
650
649
  ```
651
650
 
652
651
  > NOTE: This method does not work across navigations, use [Page#wait_for_selector](./page#wait_for_selector) instead.
@@ -4,8 +4,21 @@ sidebar_position: 10
4
4
 
5
5
  # Android
6
6
 
7
- Playwright has **experimental** support for Android automation. See [here](https://playwright.dev/python/docs/mobile) for more information. You can
8
- access android namespace via:
7
+ Playwright has **experimental** support for Android automation. This includes Chrome for Android and Android WebView.
8
+
9
+ *Requirements*
10
+ - Android device or AVD Emulator.
11
+ - [ADB daemon](https://developer.android.com/studio/command-line/adb) running and authenticated with your device.
12
+ Typically running `adb devices` is all you need to do.
13
+ - [`Chrome 87`](https://play.google.com/store/apps/details?id=com.android.chrome) or newer installed on the device
14
+ - "Enable command line on non-rooted devices" enabled in `chrome://flags`.
15
+
16
+ *Known limitations*
17
+ - Raw USB operation is not yet supported, so you need ADB.
18
+ - Device needs to be awake to produce screenshots. Enabling "Stay awake" developer mode will help.
19
+ - We didn't run all the tests against the device, so not everything works.
20
+
21
+ *How to run*
9
22
 
10
23
  An example of the Android automation script would be:
11
24
 
@@ -16,25 +16,16 @@ At every point of time, page exposes its current frame tree via the [Page#main_f
16
16
 
17
17
  An example of dumping frame tree:
18
18
 
19
- ```python sync title=example_a4a9e01d1e0879958d591c4bc9061574f5c035e821a94214e650d15564d77bf4.py
20
- from playwright.sync_api import sync_playwright
21
-
22
- def run(playwright):
23
- firefox = playwright.firefox
24
- browser = firefox.launch()
25
- page = browser.new_page()
26
- page.goto("https://www.theverge.com")
27
- dump_frame_tree(page.main_frame, "")
28
- browser.close()
29
-
30
- def dump_frame_tree(frame, indent):
31
- print(indent + frame.name + '@' + frame.url)
32
- for child in frame.child_frames:
33
- dump_frame_tree(child, indent + " ")
34
-
35
- with sync_playwright() as playwright:
36
- run(playwright)
19
+ ```ruby
20
+ def dump_frame_tree(frame, indent = 0)
21
+ puts "#{' ' * indent}#{frame.name}@#{frame.url}"
22
+ frame.child_frames.each do |child|
23
+ dump_frame_tree(child, indent + 2)
24
+ end
25
+ end
37
26
 
27
+ page.goto("https://www.theverge.com")
28
+ dump_frame_tree(page.main_frame)
38
29
  ```
39
30
 
40
31
 
@@ -176,9 +167,8 @@ The snippet below dispatches the `click` event on the element. Regardless of the
176
167
  `click` is dispatched. This is equivalent to calling
177
168
  [element.click()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click).
178
169
 
179
- ```python sync title=example_de439a4f4839a9b1bc72dbe0890d6b989c437620ba1b88a2150faa79f98184fc.py
170
+ ```ruby
180
171
  frame.dispatch_event("button#submit", "click")
181
-
182
172
  ```
183
173
 
184
174
  Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties
@@ -195,11 +185,10 @@ Since `eventInit` is event-specific, please refer to the events documentation fo
195
185
 
196
186
  You can also specify [JSHandle](./js_handle) as the property value if you want live objects to be passed into the event:
197
187
 
198
- ```python sync title=example_5410f49339561b3cc9d91c7548c8195a570c8be704bb62f45d90c68f869d450d.py
188
+ ```ruby
199
189
  # note you can only create data_transfer in chromium and firefox
200
190
  data_transfer = frame.evaluate_handle("new DataTransfer()")
201
- frame.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
202
-
191
+ frame.dispatch_event("#source", "dragstart", eventInit: { dataTransfer: data_transfer })
203
192
  ```
204
193
 
205
194
 
@@ -212,7 +201,9 @@ def drag_and_drop(
212
201
  target,
213
202
  force: nil,
214
203
  noWaitAfter: nil,
204
+ sourcePosition: nil,
215
205
  strict: nil,
206
+ targetPosition: nil,
216
207
  timeout: nil,
217
208
  trial: nil)
218
209
  ```
@@ -236,11 +227,10 @@ return its value.
236
227
 
237
228
  Examples:
238
229
 
239
- ```python sync title=example_6814d0e91763f4d27a0d6a380c36d62b551e4c3e902d1157012dde0a49122abe.py
230
+ ```ruby
240
231
  search_value = frame.eval_on_selector("#search", "el => el.value")
241
232
  preload_href = frame.eval_on_selector("link[rel=preload]", "el => el.href")
242
- html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
243
-
233
+ html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", arg: "hello")
244
234
  ```
245
235
 
246
236
 
@@ -261,9 +251,8 @@ return its value.
261
251
 
262
252
  Examples:
263
253
 
264
- ```python sync title=example_618e7f8f681d1c4a1c0c9b8d23892e37cbbef013bf3d8906fd4311c51d9819d7.py
265
- divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
266
-
254
+ ```ruby
255
+ divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", arg: 10)
267
256
  ```
268
257
 
269
258
 
@@ -283,28 +272,25 @@ If the function passed to the [Frame#evaluate](./frame#evaluate) returns a non-[
283
272
  [Frame#evaluate](./frame#evaluate) returns `undefined`. Playwright also supports transferring some additional values that are
284
273
  not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`.
285
274
 
286
- ```python sync title=example_15a235841cd1bc56fad6e3c8aaea2a30e352fedd8238017f22f97fc70e058d2b.py
287
- result = frame.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
288
- print(result) # prints "56"
289
-
275
+ ```ruby
276
+ result = frame.evaluate("([x, y]) => Promise.resolve(x * y)", arg: [7, 8])
277
+ puts result # => "56"
290
278
  ```
291
279
 
292
280
  A string can also be passed in instead of a function.
293
281
 
294
- ```python sync title=example_9c73167b900498bca191abc2ce2627e063f84b0abc8ce3a117416cb734602760.py
295
- print(frame.evaluate("1 + 2")) # prints "3"
282
+ ```ruby
283
+ puts frame.evaluate("1 + 2") # => 3
296
284
  x = 10
297
- print(frame.evaluate(f"1 + {x}")) # prints "11"
298
-
285
+ puts frame.evaluate("1 + #{x}") # => "11"
299
286
  ```
300
287
 
301
288
  [ElementHandle](./element_handle) instances can be passed as an argument to the [Frame#evaluate](./frame#evaluate):
302
289
 
303
- ```python sync title=example_05568c81173717fa6841099571d8a66e14fc0853e01684630d1622baedc25f67.py
290
+ ```ruby
304
291
  body_handle = frame.query_selector("body")
305
- html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
306
- body_handle.dispose()
307
-
292
+ html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", arg: [body_handle, "hello"])
293
+ body_handle.dispose
308
294
  ```
309
295
 
310
296
 
@@ -323,10 +309,9 @@ The only difference between [Frame#evaluate](./frame#evaluate) and [Frame#evalua
323
309
  If the function, passed to the [Frame#evaluate_handle](./frame#evaluate_handle), returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), then
324
310
  [Frame#evaluate_handle](./frame#evaluate_handle) would wait for the promise to resolve and return its value.
325
311
 
326
- ```python sync title=example_a1c8e837e826079359d01d6f7eecc64092a45d8c74280d23ee9039c379132c51.py
312
+ ```ruby
327
313
  a_window_handle = frame.evaluate_handle("Promise.resolve(window)")
328
314
  a_window_handle # handle for the window object.
329
-
330
315
  ```
331
316
 
332
317
  A string can also be passed in instead of a function.
@@ -391,11 +376,10 @@ frame.
391
376
 
392
377
  This method throws an error if the frame has been detached before `frameElement()` returns.
393
378
 
394
- ```python sync title=example_e6b4fdef29a401d84b17acfa319bee08f39e1f28e07c435463622220c6a24747.py
395
- frame_element = frame.frame_element()
396
- content_frame = frame_element.content_frame()
397
- assert frame == content_frame
398
-
379
+ ```ruby
380
+ frame_element = frame.frame_element
381
+ content_frame = frame_element.content_frame
382
+ puts frame == content_frame # => true
399
383
  ```
400
384
 
401
385
 
@@ -479,7 +463,7 @@ Returns `element.innerText`.
479
463
  def input_value(selector, strict: nil, timeout: nil)
480
464
  ```
481
465
 
482
- Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
466
+ Returns `input.value` for the selected `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
483
467
 
484
468
  ## checked?
485
469
 
@@ -656,14 +640,13 @@ Returns the array of option values that have been successfully selected.
656
640
 
657
641
  Triggers a `change` and `input` event once all the provided options have been selected.
658
642
 
659
- ```python sync title=example_230c12044664b222bf35d6163b1e415c011d87d9911a4d39648c7f601b344a31.py
643
+ ```ruby
660
644
  # single selection matching the value
661
- frame.select_option("select#colors", "blue")
645
+ frame.select_option("select#colors", value: "blue")
662
646
  # single selection matching both the label
663
- frame.select_option("select#colors", label="blue")
647
+ frame.select_option("select#colors", label: "blue")
664
648
  # multiple selection
665
- frame.select_option("select#colors", value=["red", "green", "blue"])
666
-
649
+ frame.select_option("select#colors", value: ["red", "green", "blue"])
667
650
  ```
668
651
 
669
652
 
@@ -754,10 +737,9 @@ send fine-grained keyboard events. To fill values in form fields, use [Frame#fil
754
737
 
755
738
  To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./keyboard#press).
756
739
 
757
- ```python sync title=example_beae7f0d11663c3c98b9d3a8e6ab76b762578cf2856e3b04ad8e42bfb23bb1e1.py
740
+ ```ruby
758
741
  frame.type("#mytextarea", "hello") # types instantly
759
- frame.type("#mytextarea", "world", delay=100) # types slower, like a user
760
-
742
+ frame.type("#mytextarea", "world", delay: 100) # types slower, like a user
761
743
  ```
762
744
 
763
745
 
@@ -807,28 +789,16 @@ Returns when the `expression` returns a truthy value, returns that value.
807
789
 
808
790
  The [Frame#wait_for_function](./frame#wait_for_function) can be used to observe viewport size change:
809
791
 
810
- ```python sync title=example_2f82dcf15fa9338be87a4faf7fe7de3c542040924db1e1ad1c98468ec0f425ce.py
811
- from playwright.sync_api import sync_playwright
812
-
813
- def run(playwright):
814
- webkit = playwright.webkit
815
- browser = webkit.launch()
816
- page = browser.new_page()
817
- page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
818
- page.main_frame.wait_for_function("() => window.x > 0")
819
- browser.close()
820
-
821
- with sync_playwright() as playwright:
822
- run(playwright)
823
-
792
+ ```ruby
793
+ frame.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
794
+ frame.wait_for_function("() => window.x > 0")
824
795
  ```
825
796
 
826
797
  To pass an argument to the predicate of `frame.waitForFunction` function:
827
798
 
828
- ```python sync title=example_8b95be0fb4d149890f7817d9473428a50dc631d3a75baf89846648ca6a157562.py
799
+ ```ruby
829
800
  selector = ".foo"
830
- frame.wait_for_function("selector => !!document.querySelector(selector)", selector)
831
-
801
+ frame.wait_for_function("selector => !!document.querySelector(selector)", arg: selector)
832
802
  ```
833
803
 
834
804
 
@@ -844,10 +814,9 @@ Waits for the required load state to be reached.
844
814
  This returns when the frame reaches a required load state, `load` by default. The navigation must have been committed
845
815
  when this method is called. If current document has already reached the required state, resolves immediately.
846
816
 
847
- ```python sync title=example_fe41b79b58d046cda4673ededd4d216cb97a63204fcba69375ce8a84ea3f6894.py
817
+ ```ruby
848
818
  frame.click("button") # click triggers navigation.
849
- frame.wait_for_load_state() # the promise resolves after "load" event.
850
-
819
+ frame.wait_for_load_state # the promise resolves after "load" event.
851
820
  ```
852
821
 
853
822
 
@@ -865,11 +834,10 @@ History API usage, the navigation will resolve with `null`.
865
834
  This method waits for the frame to navigate to a new URL. It is useful for when you run code which will indirectly cause
866
835
  the frame to navigate. Consider this example:
867
836
 
868
- ```python sync title=example_03f0ac17eb6c1ce8780cfa83c4ae15a9ddbfde3f96c96f36fdf3fbf9aac721f7.py
869
- with frame.expect_navigation():
870
- frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
871
- # Resolves after navigation has finished
872
-
837
+ ```ruby
838
+ frame.expect_navigation do
839
+ frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
840
+ end # Resolves after navigation has finished
873
841
  ```
874
842
 
875
843
  > NOTE: Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is
@@ -890,25 +858,27 @@ selector doesn't satisfy the condition for the `timeout` milliseconds, the funct
890
858
 
891
859
  This method works across navigations:
892
860
 
893
- ```python sync title=example_a5b9dd4745d45ac630e5953be1c1815ae8e8ab03399fb35f45ea77c434f17eea.py
894
- from playwright.sync_api import sync_playwright
861
+ ```ruby
862
+ %w[https://google.com https://bbc.com].each do |current_url|
863
+ page.goto(current_url, waitUntil: "domcontentloaded")
864
+ frame = page.main_frame
865
+ element = frame.wait_for_selector("img")
866
+ puts "Loaded image: #{element["src"]}"
867
+ end
868
+ ```
869
+
895
870
 
896
- def run(playwright):
897
- chromium = playwright.chromium
898
- browser = chromium.launch()
899
- page = browser.new_page()
900
- for current_url in ["https://google.com", "https://bbc.com"]:
901
- page.goto(current_url, wait_until="domcontentloaded")
902
- element = page.main_frame.wait_for_selector("img")
903
- print("Loaded image: " + str(element.get_attribute("src")))
904
- browser.close()
905
871
 
906
- with sync_playwright() as playwright:
907
- run(playwright)
872
+ ## wait_for_timeout
908
873
 
874
+ ```
875
+ def wait_for_timeout(timeout)
909
876
  ```
910
877
 
878
+ Waits for the given `timeout` in milliseconds.
911
879
 
880
+ Note that `frame.waitForTimeout()` should only be used for debugging. Tests using the timer in production are going to
881
+ be flaky. Use signals such as network events, selectors becoming visible and others instead.
912
882
 
913
883
  ## wait_for_url
914
884
 
@@ -918,10 +888,9 @@ def wait_for_url(url, timeout: nil, waitUntil: nil)
918
888
 
919
889
  Waits for the frame to navigate to the given URL.
920
890
 
921
- ```python sync title=example_86a9a19ec4c41e1a5ac302fbca9a3d3d6dca3fe3314e065b8062ddf5f75abfbd.py
891
+ ```ruby
922
892
  frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
923
893
  frame.wait_for_url("**/target.html")
924
-
925
894
  ```
926
895
 
927
896