playwright-ruby-client 0.9.0 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
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