playwright-ruby-client 1.26.0 → 1.28.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 (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
@@ -25,6 +25,14 @@ def all_text_contents
25
25
 
26
26
  Returns an array of `node.textContent` values for all matching nodes.
27
27
 
28
+ ## blur
29
+
30
+ ```
31
+ def blur(timeout: nil)
32
+ ```
33
+
34
+ Calls [blur](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur) on the element.
35
+
28
36
  ## bounding_box
29
37
 
30
38
  ```
@@ -79,6 +87,20 @@ If the element is detached from the DOM at any moment during the action, this me
79
87
  When all steps combined have not finished during the specified `timeout`, this method throws a `TimeoutError`. Passing
80
88
  zero timeout disables this.
81
89
 
90
+ ## clear
91
+
92
+ ```
93
+ def clear(force: nil, noWaitAfter: nil, timeout: nil)
94
+ ```
95
+
96
+ This method waits for [actionability](https://playwright.dev/python/docs/actionability) checks, focuses the element, clears it and triggers an
97
+ `input` event after clearing.
98
+
99
+ If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error.
100
+ However, if the element is inside the `<label>` element that has an associated
101
+ [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be cleared
102
+ instead.
103
+
82
104
  ## click
83
105
 
84
106
  ```
@@ -190,6 +212,22 @@ def drag_to(
190
212
  trial: nil)
191
213
  ```
192
214
 
215
+ This method drags the locator to another target locator or target position. It will first move to the source element,
216
+ perform a `mousedown`, then move to the target element or position and perform a `mouseup`.
217
+
218
+ ```ruby
219
+ source = page.locator("#source")
220
+ target = page.locator("#target")
221
+
222
+ source.drag_to(target)
223
+ # or specify exact positions relative to the top-left corners of the elements:
224
+ source.drag_to(
225
+ target,
226
+ sourcePosition: { x: 34, y: 7 },
227
+ targetPosition: { x: 10, y: 20 },
228
+ )
229
+ ```
230
+
193
231
 
194
232
 
195
233
  ## element_handle
@@ -298,8 +336,8 @@ multiple times.
298
336
  row_locator = page.locator("tr")
299
337
  # ...
300
338
  row_locator.
301
- filter(has_text="text in column 1").
302
- filter(has=page.locator("tr", has_text="column 2 button")).
339
+ filter(hasText: "text in column 1").
340
+ filter(has: page.get_by_role("button", name: "column 2 button")).
303
341
  screenshot
304
342
  ```
305
343
 
@@ -331,7 +369,7 @@ When working with iframes, you can create a frame locator that will enter the if
331
369
  that iframe:
332
370
 
333
371
  ```ruby
334
- locator = page.frame_locator("iframe").locator("text=Submit")
372
+ locator = page.frame_locator("iframe").get_by_text("Submit")
335
373
  locator.click
336
374
  ```
337
375
 
@@ -346,6 +384,150 @@ alias: `[]`
346
384
 
347
385
  Returns element attribute value.
348
386
 
387
+ ## get_by_alt_text
388
+
389
+ ```
390
+ def get_by_alt_text(text, exact: nil)
391
+ ```
392
+
393
+ Allows locating elements by their alt text. For example, this method will find the image by alt text "Castle":
394
+
395
+ ```html
396
+ <img alt='Castle'>
397
+ ```
398
+
399
+
400
+ ## get_by_label
401
+
402
+ ```
403
+ def get_by_label(text, exact: nil)
404
+ ```
405
+
406
+ Allows locating input elements by the text of the associated label. For example, this method will find the input by
407
+ label text "Password" in the following DOM:
408
+
409
+ ```html
410
+ <label for="password-input">Password:</label>
411
+ <input id="password-input">
412
+ ```
413
+
414
+
415
+ ## get_by_placeholder
416
+
417
+ ```
418
+ def get_by_placeholder(text, exact: nil)
419
+ ```
420
+
421
+ Allows locating input elements by the placeholder text. For example, this method will find the input by placeholder
422
+ "Country":
423
+
424
+ ```html
425
+ <input placeholder="Country">
426
+ ```
427
+
428
+
429
+ ## get_by_role
430
+
431
+ ```
432
+ def get_by_role(
433
+ role,
434
+ checked: nil,
435
+ disabled: nil,
436
+ exact: nil,
437
+ expanded: nil,
438
+ includeHidden: nil,
439
+ level: nil,
440
+ name: nil,
441
+ pressed: nil,
442
+ selected: nil)
443
+ ```
444
+
445
+ Allows locating elements by their [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles),
446
+ [ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and
447
+ [accessible name](https://w3c.github.io/accname/#dfn-accessible-name). Note that role selector **does not replace**
448
+ accessibility audits and conformance tests, but rather gives early feedback about the ARIA guidelines.
449
+
450
+ Note that many html elements have an implicitly
451
+ [defined role](https://w3c.github.io/html-aam/#html-element-role-mappings) that is recognized by the role selector. You
452
+ can find all the [supported roles here](https://www.w3.org/TR/wai-aria-1.2/#role_definitions). ARIA guidelines **do not
453
+ recommend** duplicating implicit roles and attributes by setting `role` and/or `aria-*` attributes to default values.
454
+
455
+ ## get_by_test_id
456
+
457
+ ```
458
+ def get_by_test_id(testId)
459
+ ```
460
+
461
+ Locate element by the test id. By default, the `data-testid` attribute is used as a test id. Use
462
+ [Selectors#set_test_id_attribute](./selectors#set_test_id_attribute) to configure a different test id attribute if necessary.
463
+
464
+
465
+
466
+ ## get_by_text
467
+
468
+ ```
469
+ def get_by_text(text, exact: nil)
470
+ ```
471
+
472
+ Allows locating elements that contain given text. Consider the following DOM structure:
473
+
474
+ ```html
475
+ <div>Hello <span>world</span></div>
476
+ <div>Hello</div>
477
+ ```
478
+
479
+ You can locate by text substring, exact string, or a regular expression:
480
+
481
+ ```ruby
482
+ page.content = <<~HTML
483
+ <div>Hello <span>world</span></div>
484
+ <div>Hello</div>
485
+ HTML
486
+
487
+ # Matches <span>
488
+ locator = page.get_by_text("world")
489
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<span>world</span>')
490
+
491
+ # Matches first <div>
492
+ locator = page.get_by_text("Hello world")
493
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello <span>world</span></div>')
494
+
495
+ # Matches second <div>
496
+ locator = page.get_by_text("Hello", exact: true)
497
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
498
+
499
+ # Matches both <div>s
500
+ locator = page.get_by_text(/Hello/)
501
+ expect(locator.count).to eq(2)
502
+ expect(locator.first.evaluate('e => e.outerHTML')).to eq('<div>Hello <span>world</span></div>')
503
+ expect(locator.last.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
504
+
505
+ # Matches second <div>
506
+ locator = page.get_by_text(/^hello$/i)
507
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
508
+ ```
509
+
510
+ See also [Locator#filter](./locator#filter) that allows to match by another criteria, like an accessible role, and then filter
511
+ by the text content.
512
+
513
+ > NOTE: Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into
514
+ one, turns line breaks into spaces and ignores leading and trailing whitespace.
515
+ > NOTE: Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For
516
+ example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
517
+
518
+ ## get_by_title
519
+
520
+ ```
521
+ def get_by_title(text, exact: nil)
522
+ ```
523
+
524
+ Allows locating elements by their title. For example, this method will find the button by its title "Place the order":
525
+
526
+ ```html
527
+ <button title='Place the order'>Order Now</button>
528
+ ```
529
+
530
+
349
531
  ## highlight
350
532
 
351
533
  ```
@@ -361,6 +543,7 @@ Highlight the corresponding element(s) on the screen. Useful for debugging, don'
361
543
  def hover(
362
544
  force: nil,
363
545
  modifiers: nil,
546
+ noWaitAfter: nil,
364
547
  position: nil,
365
548
  timeout: nil,
366
549
  trial: nil)
@@ -466,9 +649,11 @@ Returns locator to the last matching element.
466
649
  def locator(selector, has: nil, hasText: nil)
467
650
  ```
468
651
 
469
- The method finds an element matching the specified selector in the [Locator](./locator)'s subtree. It also accepts filter options,
652
+ The method finds an element matching the specified selector in the locator's subtree. It also accepts filter options,
470
653
  similar to [Locator#filter](./locator#filter) method.
471
654
 
655
+ [Learn more about locators](https://playwright.dev/python/docs/locators).
656
+
472
657
  ## nth
473
658
 
474
659
  ```
@@ -684,8 +869,8 @@ element.type("world", delay: 100) # types slower, like a user
684
869
  An example of typing into a text field and then submitting the form:
685
870
 
686
871
  ```ruby
687
- element = page.locator("input")
688
- element.type("some text")
872
+ element = page.get_by_label("Password")
873
+ element.type("my password")
689
874
  element.press("Enter")
690
875
  ```
691
876
 
@@ -276,6 +276,20 @@ def drag_and_drop(
276
276
  trial: nil)
277
277
  ```
278
278
 
279
+ This method drags the source element to the target element. It will first move to the source element, perform a
280
+ `mousedown`, then move to the target element and perform a `mouseup`.
281
+
282
+ ```ruby
283
+ page.drag_and_drop("#source", "#target")
284
+ # or specify exact positions relative to the top-left corners of the elements:
285
+ page.drag_and_drop(
286
+ "#source",
287
+ "#target",
288
+ sourcePosition: { x: 34, y: 7 },
289
+ targetPosition: { x: 10, y: 20 },
290
+ )
291
+ ```
292
+
279
293
 
280
294
 
281
295
  ## emulate_media
@@ -592,7 +606,7 @@ that iframe. Following snippet locates element with text "Submit" in the iframe
592
606
  id="my-frame">`:
593
607
 
594
608
  ```ruby
595
- locator = page.frame_locator("#my-iframe").locator("text=Submit")
609
+ locator = page.frame_locator("#my-iframe").get_by_text("Submit")
596
610
  locator.click
597
611
  ```
598
612
 
@@ -614,6 +628,150 @@ def get_attribute(selector, name, strict: nil, timeout: nil)
614
628
 
615
629
  Returns element attribute value.
616
630
 
631
+ ## get_by_alt_text
632
+
633
+ ```
634
+ def get_by_alt_text(text, exact: nil)
635
+ ```
636
+
637
+ Allows locating elements by their alt text. For example, this method will find the image by alt text "Castle":
638
+
639
+ ```html
640
+ <img alt='Castle'>
641
+ ```
642
+
643
+
644
+ ## get_by_label
645
+
646
+ ```
647
+ def get_by_label(text, exact: nil)
648
+ ```
649
+
650
+ Allows locating input elements by the text of the associated label. For example, this method will find the input by
651
+ label text "Password" in the following DOM:
652
+
653
+ ```html
654
+ <label for="password-input">Password:</label>
655
+ <input id="password-input">
656
+ ```
657
+
658
+
659
+ ## get_by_placeholder
660
+
661
+ ```
662
+ def get_by_placeholder(text, exact: nil)
663
+ ```
664
+
665
+ Allows locating input elements by the placeholder text. For example, this method will find the input by placeholder
666
+ "Country":
667
+
668
+ ```html
669
+ <input placeholder="Country">
670
+ ```
671
+
672
+
673
+ ## get_by_role
674
+
675
+ ```
676
+ def get_by_role(
677
+ role,
678
+ checked: nil,
679
+ disabled: nil,
680
+ exact: nil,
681
+ expanded: nil,
682
+ includeHidden: nil,
683
+ level: nil,
684
+ name: nil,
685
+ pressed: nil,
686
+ selected: nil)
687
+ ```
688
+
689
+ Allows locating elements by their [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles),
690
+ [ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and
691
+ [accessible name](https://w3c.github.io/accname/#dfn-accessible-name). Note that role selector **does not replace**
692
+ accessibility audits and conformance tests, but rather gives early feedback about the ARIA guidelines.
693
+
694
+ Note that many html elements have an implicitly
695
+ [defined role](https://w3c.github.io/html-aam/#html-element-role-mappings) that is recognized by the role selector. You
696
+ can find all the [supported roles here](https://www.w3.org/TR/wai-aria-1.2/#role_definitions). ARIA guidelines **do not
697
+ recommend** duplicating implicit roles and attributes by setting `role` and/or `aria-*` attributes to default values.
698
+
699
+ ## get_by_test_id
700
+
701
+ ```
702
+ def get_by_test_id(testId)
703
+ ```
704
+
705
+ Locate element by the test id. By default, the `data-testid` attribute is used as a test id. Use
706
+ [Selectors#set_test_id_attribute](./selectors#set_test_id_attribute) to configure a different test id attribute if necessary.
707
+
708
+
709
+
710
+ ## get_by_text
711
+
712
+ ```
713
+ def get_by_text(text, exact: nil)
714
+ ```
715
+
716
+ Allows locating elements that contain given text. Consider the following DOM structure:
717
+
718
+ ```html
719
+ <div>Hello <span>world</span></div>
720
+ <div>Hello</div>
721
+ ```
722
+
723
+ You can locate by text substring, exact string, or a regular expression:
724
+
725
+ ```ruby
726
+ page.content = <<~HTML
727
+ <div>Hello <span>world</span></div>
728
+ <div>Hello</div>
729
+ HTML
730
+
731
+ # Matches <span>
732
+ locator = page.get_by_text("world")
733
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<span>world</span>')
734
+
735
+ # Matches first <div>
736
+ locator = page.get_by_text("Hello world")
737
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello <span>world</span></div>')
738
+
739
+ # Matches second <div>
740
+ locator = page.get_by_text("Hello", exact: true)
741
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
742
+
743
+ # Matches both <div>s
744
+ locator = page.get_by_text(/Hello/)
745
+ expect(locator.count).to eq(2)
746
+ expect(locator.first.evaluate('e => e.outerHTML')).to eq('<div>Hello <span>world</span></div>')
747
+ expect(locator.last.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
748
+
749
+ # Matches second <div>
750
+ locator = page.get_by_text(/^hello$/i)
751
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
752
+ ```
753
+
754
+ See also [Locator#filter](./locator#filter) that allows to match by another criteria, like an accessible role, and then filter
755
+ by the text content.
756
+
757
+ > NOTE: Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into
758
+ one, turns line breaks into spaces and ignores leading and trailing whitespace.
759
+ > NOTE: Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For
760
+ example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
761
+
762
+ ## get_by_title
763
+
764
+ ```
765
+ def get_by_title(text, exact: nil)
766
+ ```
767
+
768
+ Allows locating elements by their title. For example, this method will find the button by its title "Place the order":
769
+
770
+ ```html
771
+ <button title='Place the order'>Order Now</button>
772
+ ```
773
+
774
+
617
775
  ## go_back
618
776
 
619
777
  ```
@@ -670,6 +828,7 @@ def hover(
670
828
  selector,
671
829
  force: nil,
672
830
  modifiers: nil,
831
+ noWaitAfter: nil,
673
832
  position: nil,
674
833
  strict: nil,
675
834
  timeout: nil,
@@ -780,14 +939,12 @@ considered not visible.
780
939
  def locator(selector, has: nil, hasText: nil)
781
940
  ```
782
941
 
783
- The method returns an element locator that can be used to perform actions on the page. Locator is resolved to the
784
- element immediately before performing an action, so a series of actions on the same locator can in fact be performed on
785
- different DOM elements. That would happen if the DOM structure between those actions has changed.
942
+ The method returns an element locator that can be used to perform actions on this page / frame. Locator is resolved to
943
+ the element immediately before performing an action, so a series of actions on the same locator can in fact be performed
944
+ on different DOM elements. That would happen if the DOM structure between those actions has changed.
786
945
 
787
946
  [Learn more about locators](https://playwright.dev/python/docs/locators).
788
947
 
789
- Shortcut for main frame's [Frame#locator](./frame#locator).
790
-
791
948
  ## main_frame
792
949
 
793
950
  ```
@@ -1364,7 +1521,7 @@ value. Will throw an error if the page is closed before the event is fired. Retu
1364
1521
 
1365
1522
  ```ruby
1366
1523
  frame = page.expect_event("framenavigated") do
1367
- page.click("button")
1524
+ page.get_by_role("button")
1368
1525
  end
1369
1526
  ```
1370
1527
 
@@ -1415,13 +1572,13 @@ This resolves when the page reaches a required load state, `load` by default. Th
1415
1572
  when this method is called. If current document has already reached the required state, resolves immediately.
1416
1573
 
1417
1574
  ```ruby
1418
- page.click("button") # click triggers navigation.
1575
+ page.get_by_role("button").click # click triggers navigation.
1419
1576
  page.wait_for_load_state # the promise resolves after "load" event.
1420
1577
  ```
1421
1578
 
1422
1579
  ```ruby
1423
1580
  popup = page.expect_popup do
1424
- page.click("button") # click triggers a popup.
1581
+ page.get_by_role("button").click # click triggers a popup.
1425
1582
  end
1426
1583
 
1427
1584
  # Following resolves after "domcontentloaded" event.
@@ -15,7 +15,7 @@ the [`event: Page.requestFailed`] event is emitted.
15
15
  > NOTE: HTTP Error responses, such as 404 or 503, are still successful responses from HTTP standpoint, so request will
16
16
  complete with `'requestfinished'` event.
17
17
 
18
- If request gets a 'redirect' response, the request is successfully finished with the 'requestfinished' event, and a new
18
+ If request gets a 'redirect' response, the request is successfully finished with the `requestfinished` event, and a new
19
19
  request is issued to a redirected url.
20
20
 
21
21
  ## all_headers
@@ -58,7 +58,7 @@ page = context.new_page
58
58
  page.goto("https://playwright.dev")
59
59
 
60
60
  context.tracing.start_chunk
61
- page.locator("text=Get Started").click
61
+ page.get_by_text("Get Started").click
62
62
  # Everything between start_chunk and stop_chunk will be recorded in the trace.
63
63
  context.tracing.stop_chunk(path: "trace1.zip")
64
64
 
@@ -95,6 +95,7 @@ These parameters can be passed into `Capybara::Playwright::Driver.new`
95
95
  * record_video_dir
96
96
  * record_video_size
97
97
  * screen
98
+ * serviceWorkers
98
99
  * storageState
99
100
  * timezoneId
100
101
  * userAgent
@@ -84,3 +84,62 @@ describe 'example', driver: :null do
84
84
  end
85
85
  end
86
86
  ```
87
+
88
+ ## Minitest Usage
89
+
90
+ We can do something similar with the default Rails setup using Minitest. Here's the same example written with Minitest:
91
+
92
+ ```rb
93
+ # test/application_system_test_case.rb
94
+
95
+ require 'playwright'
96
+
97
+ class CapybaraNullDriver < Capybara::Driver::Base
98
+ def needs_server?
99
+ true
100
+ end
101
+ end
102
+
103
+ Capybara.register_driver(:null) { CapybaraNullDriver.new }
104
+
105
+ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
106
+ driven_by :null
107
+
108
+ def self.playwright
109
+ @playwright ||= Playwright.create(playwright_cli_executable_path: Rails.root.join("node_modules/.bin/playwright"))
110
+ end
111
+
112
+ def before_setup
113
+ super
114
+ base_url = Capybara.current_session.server.base_url
115
+ @playwright_browser = self.class.playwright.playwright.chromium.launch(headless: false)
116
+ @playwright_page = @playwright_browser.new_page(baseURL: base_url)
117
+ end
118
+
119
+ def after_teardown
120
+ super
121
+ @browser.close
122
+ end
123
+ end
124
+ ```
125
+
126
+ And here is the same test:
127
+
128
+ ```rb
129
+ require "application_system_test_case"
130
+
131
+ class ExampleTest < ApplicationSystemTestCase
132
+ def setup
133
+ @user = User.create!
134
+ @page = @playwright_page
135
+ end
136
+
137
+ test 'can browse' do
138
+ @page.goto("/tests/#{user.id}")
139
+ @page.wait_for_selector('input').type('hoge')
140
+ @page.keyboard.press('Enter')
141
+
142
+ assert @page.text_content('#content').include?('hoge')
143
+ end
144
+ end
145
+ ```
@@ -159,6 +159,13 @@
159
159
  * frame_element
160
160
  * frame_locator
161
161
  * get_attribute
162
+ * get_by_alt_text
163
+ * get_by_label
164
+ * get_by_placeholder
165
+ * get_by_role
166
+ * get_by_test_id
167
+ * get_by_text
168
+ * get_by_title
162
169
  * goto
163
170
  * hover
164
171
  * inner_html
@@ -204,6 +211,7 @@
204
211
  ## Selectors
205
212
 
206
213
  * register
214
+ * ~~set_test_id_attribute~~
207
215
 
208
216
  ## ConsoleMessage
209
217
 
@@ -258,6 +266,13 @@
258
266
  * frame_locator
259
267
  * frames
260
268
  * get_attribute
269
+ * get_by_alt_text
270
+ * get_by_label
271
+ * get_by_placeholder
272
+ * get_by_role
273
+ * get_by_test_id
274
+ * get_by_text
275
+ * get_by_title
261
276
  * go_back
262
277
  * go_forward
263
278
  * goto
@@ -405,8 +420,10 @@
405
420
 
406
421
  * all_inner_texts
407
422
  * all_text_contents
423
+ * blur
408
424
  * bounding_box
409
425
  * check
426
+ * clear
410
427
  * click
411
428
  * count
412
429
  * dblclick
@@ -423,6 +440,13 @@
423
440
  * focus
424
441
  * frame_locator
425
442
  * get_attribute
443
+ * get_by_alt_text
444
+ * get_by_label
445
+ * get_by_placeholder
446
+ * get_by_role
447
+ * get_by_test_id
448
+ * get_by_text
449
+ * get_by_title
426
450
  * highlight
427
451
  * hover
428
452
  * inner_html
@@ -455,6 +479,13 @@
455
479
 
456
480
  * first
457
481
  * frame_locator
482
+ * get_by_alt_text
483
+ * get_by_label
484
+ * get_by_placeholder
485
+ * get_by_role
486
+ * get_by_test_id
487
+ * get_by_text
488
+ * get_by_title
458
489
  * last
459
490
  * locator
460
491
  * nth
@@ -490,6 +521,7 @@
490
521
 
491
522
  ## Android
492
523
 
524
+ * ~~connect~~
493
525
  * devices
494
526
  * ~~set_default_timeout~~
495
527