playwright-ruby-client 0.8.1 → 0.9.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/download.md +97 -0
  3. data/documentation/docs/api/element_handle.md +27 -2
  4. data/documentation/docs/api/frame.md +50 -17
  5. data/documentation/docs/api/locator.md +650 -0
  6. data/documentation/docs/api/page.md +68 -18
  7. data/documentation/docs/article/guides/inspector.md +31 -0
  8. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +1 -1
  9. data/documentation/docs/article/guides/semi_automation.md +1 -1
  10. data/documentation/docs/include/api_coverage.md +57 -1
  11. data/lib/playwright.rb +0 -1
  12. data/lib/playwright/channel_owners/browser_context.rb +25 -0
  13. data/lib/playwright/channel_owners/frame.rb +70 -33
  14. data/lib/playwright/channel_owners/page.rb +102 -40
  15. data/lib/playwright/{download.rb → download_impl.rb} +1 -1
  16. data/lib/playwright/javascript/expression.rb +5 -4
  17. data/lib/playwright/locator_impl.rb +314 -0
  18. data/lib/playwright/timeout_settings.rb +4 -4
  19. data/lib/playwright/version.rb +2 -2
  20. data/lib/playwright_api/android.rb +6 -6
  21. data/lib/playwright_api/android_device.rb +6 -6
  22. data/lib/playwright_api/browser.rb +6 -6
  23. data/lib/playwright_api/browser_context.rb +16 -11
  24. data/lib/playwright_api/browser_type.rb +6 -6
  25. data/lib/playwright_api/cdp_session.rb +6 -6
  26. data/lib/playwright_api/console_message.rb +6 -6
  27. data/lib/playwright_api/dialog.rb +6 -6
  28. data/lib/playwright_api/download.rb +70 -0
  29. data/lib/playwright_api/element_handle.rb +33 -19
  30. data/lib/playwright_api/frame.rb +81 -51
  31. data/lib/playwright_api/js_handle.rb +6 -6
  32. data/lib/playwright_api/locator.rb +509 -0
  33. data/lib/playwright_api/page.rb +84 -52
  34. data/lib/playwright_api/playwright.rb +6 -6
  35. data/lib/playwright_api/request.rb +6 -6
  36. data/lib/playwright_api/response.rb +6 -6
  37. data/lib/playwright_api/route.rb +6 -6
  38. data/lib/playwright_api/selectors.rb +6 -6
  39. data/lib/playwright_api/web_socket.rb +6 -6
  40. data/lib/playwright_api/worker.rb +6 -6
  41. metadata +10 -4
@@ -104,6 +104,7 @@ def check(
104
104
  force: nil,
105
105
  noWaitAfter: nil,
106
106
  position: nil,
107
+ strict: nil,
107
108
  timeout: nil,
108
109
  trial: nil)
109
110
  ```
@@ -136,6 +137,7 @@ def click(
136
137
  modifiers: nil,
137
138
  noWaitAfter: nil,
138
139
  position: nil,
140
+ strict: nil,
139
141
  timeout: nil,
140
142
  trial: nil)
141
143
  ```
@@ -194,6 +196,7 @@ def dblclick(
194
196
  modifiers: nil,
195
197
  noWaitAfter: nil,
196
198
  position: nil,
199
+ strict: nil,
197
200
  timeout: nil,
198
201
  trial: nil)
199
202
  ```
@@ -217,7 +220,12 @@ Shortcut for main frame's [Frame#dblclick](./frame#dblclick).
217
220
  ## dispatch_event
218
221
 
219
222
  ```
220
- def dispatch_event(selector, type, eventInit: nil, timeout: nil)
223
+ def dispatch_event(
224
+ selector,
225
+ type,
226
+ eventInit: nil,
227
+ strict: nil,
228
+ timeout: nil)
221
229
  ```
222
230
 
223
231
  The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the element,
@@ -261,6 +269,7 @@ def drag_and_drop(
261
269
  target,
262
270
  force: nil,
263
271
  noWaitAfter: nil,
272
+ strict: nil,
264
273
  timeout: nil,
265
274
  trial: nil)
266
275
  ```
@@ -301,7 +310,7 @@ page.evaluate("matchMedia('(prefers-color-scheme: no-preference)').matches") # =
301
310
  ## eval_on_selector
302
311
 
303
312
  ```
304
- def eval_on_selector(selector, expression, arg: nil)
313
+ def eval_on_selector(selector, expression, arg: nil, strict: nil)
305
314
  ```
306
315
 
307
316
  The method finds an element matching the specified selector within the page and passes it as a first argument to
@@ -518,6 +527,7 @@ def fill(
518
527
  value,
519
528
  force: nil,
520
529
  noWaitAfter: nil,
530
+ strict: nil,
521
531
  timeout: nil)
522
532
  ```
523
533
 
@@ -537,7 +547,7 @@ Shortcut for main frame's [Frame#fill](./frame#fill).
537
547
  ## focus
538
548
 
539
549
  ```
540
- def focus(selector, timeout: nil)
550
+ def focus(selector, strict: nil, timeout: nil)
541
551
  ```
542
552
 
543
553
  This method fetches an element with `selector` and focuses it. If there's no element matching `selector`, the method
@@ -574,7 +584,7 @@ An array of all frames attached to the page.
574
584
  ## get_attribute
575
585
 
576
586
  ```
577
- def get_attribute(selector, name, timeout: nil)
587
+ def get_attribute(selector, name, strict: nil, timeout: nil)
578
588
  ```
579
589
 
580
590
  Returns element attribute value.
@@ -636,6 +646,7 @@ def hover(
636
646
  force: nil,
637
647
  modifiers: nil,
638
648
  position: nil,
649
+ strict: nil,
639
650
  timeout: nil,
640
651
  trial: nil)
641
652
  ```
@@ -656,7 +667,7 @@ Shortcut for main frame's [Frame#hover](./frame#hover).
656
667
  ## inner_html
657
668
 
658
669
  ```
659
- def inner_html(selector, timeout: nil)
670
+ def inner_html(selector, strict: nil, timeout: nil)
660
671
  ```
661
672
 
662
673
  Returns `element.innerHTML`.
@@ -664,7 +675,7 @@ Returns `element.innerHTML`.
664
675
  ## inner_text
665
676
 
666
677
  ```
667
- def inner_text(selector, timeout: nil)
678
+ def inner_text(selector, strict: nil, timeout: nil)
668
679
  ```
669
680
 
670
681
  Returns `element.innerText`.
@@ -672,7 +683,7 @@ Returns `element.innerText`.
672
683
  ## input_value
673
684
 
674
685
  ```
675
- def input_value(selector, timeout: nil)
686
+ def input_value(selector, strict: nil, timeout: nil)
676
687
  ```
677
688
 
678
689
  Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
@@ -680,7 +691,7 @@ Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws
680
691
  ## checked?
681
692
 
682
693
  ```
683
- def checked?(selector, timeout: nil)
694
+ def checked?(selector, strict: nil, timeout: nil)
684
695
  ```
685
696
 
686
697
  Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
@@ -696,7 +707,7 @@ Indicates that the page has been closed.
696
707
  ## disabled?
697
708
 
698
709
  ```
699
- def disabled?(selector, timeout: nil)
710
+ def disabled?(selector, strict: nil, timeout: nil)
700
711
  ```
701
712
 
702
713
  Returns whether the element is disabled, the opposite of [enabled](https://playwright.dev/python/docs/actionability).
@@ -704,7 +715,7 @@ Returns whether the element is disabled, the opposite of [enabled](https://playw
704
715
  ## editable?
705
716
 
706
717
  ```
707
- def editable?(selector, timeout: nil)
718
+ def editable?(selector, strict: nil, timeout: nil)
708
719
  ```
709
720
 
710
721
  Returns whether the element is [editable](https://playwright.dev/python/docs/actionability).
@@ -712,7 +723,7 @@ Returns whether the element is [editable](https://playwright.dev/python/docs/act
712
723
  ## enabled?
713
724
 
714
725
  ```
715
- def enabled?(selector, timeout: nil)
726
+ def enabled?(selector, strict: nil, timeout: nil)
716
727
  ```
717
728
 
718
729
  Returns whether the element is [enabled](https://playwright.dev/python/docs/actionability).
@@ -720,7 +731,7 @@ Returns whether the element is [enabled](https://playwright.dev/python/docs/acti
720
731
  ## hidden?
721
732
 
722
733
  ```
723
- def hidden?(selector, timeout: nil)
734
+ def hidden?(selector, strict: nil, timeout: nil)
724
735
  ```
725
736
 
726
737
  Returns whether the element is hidden, the opposite of [visible](https://playwright.dev/python/docs/actionability). `selector` that does not
@@ -729,12 +740,26 @@ match any elements is considered hidden.
729
740
  ## visible?
730
741
 
731
742
  ```
732
- def visible?(selector, timeout: nil)
743
+ def visible?(selector, strict: nil, timeout: nil)
733
744
  ```
734
745
 
735
746
  Returns whether the element is [visible](https://playwright.dev/python/docs/actionability). `selector` that does not match any elements is
736
747
  considered not visible.
737
748
 
749
+ ## locator
750
+
751
+ ```
752
+ def locator(selector)
753
+ ```
754
+
755
+ The method returns an element locator that can be used to perform actions on the page. Locator is resolved to the
756
+ element immediately before performing an action, so a series of actions on the same locator can in fact be performed on
757
+ different DOM elements. That would happen if the DOM structure between those actions has changed.
758
+
759
+ Note that locator always implies visibility, so it will always be locating visible elements.
760
+
761
+ Shortcut for main frame's [Frame#locator](./frame#locator).
762
+
738
763
  ## main_frame
739
764
 
740
765
  ```
@@ -751,6 +776,21 @@ def opener
751
776
 
752
777
  Returns the opener for popup pages and `null` for others. If the opener has been closed already the returns `null`.
753
778
 
779
+ ## pause
780
+
781
+ ```
782
+ def pause
783
+ ```
784
+
785
+ Pauses script execution. Playwright will stop executing the script and wait for the user to either press 'Resume' button
786
+ in the page overlay or to call `playwright.resume()` in the DevTools console.
787
+
788
+ User can inspect selectors or perform manual steps while paused. Resume will continue running the original script from
789
+ the place it was paused.
790
+
791
+ > NOTE: This method requires Playwright to be started in a headed mode, with a falsy `headless` value in the
792
+ [BrowserType#launch](./browser_type#launch).
793
+
754
794
  ## pdf
755
795
 
756
796
  ```
@@ -824,6 +864,7 @@ def press(
824
864
  key,
825
865
  delay: nil,
826
866
  noWaitAfter: nil,
867
+ strict: nil,
827
868
  timeout: nil)
828
869
  ```
829
870
 
@@ -861,7 +902,7 @@ page.screenshot(path: "o.png")
861
902
  ## query_selector
862
903
 
863
904
  ```
864
- def query_selector(selector)
905
+ def query_selector(selector, strict: nil)
865
906
  ```
866
907
 
867
908
  The method finds an element matching the specified selector within the page. If no elements match the selector, the
@@ -963,6 +1004,7 @@ def select_option(
963
1004
  label: nil,
964
1005
  force: nil,
965
1006
  noWaitAfter: nil,
1007
+ strict: nil,
966
1008
  timeout: nil)
967
1009
  ```
968
1010
 
@@ -1041,7 +1083,12 @@ The extra HTTP headers will be sent with every request the page initiates.
1041
1083
  ## set_input_files
1042
1084
 
1043
1085
  ```
1044
- def set_input_files(selector, files, noWaitAfter: nil, timeout: nil)
1086
+ def set_input_files(
1087
+ selector,
1088
+ files,
1089
+ noWaitAfter: nil,
1090
+ strict: nil,
1091
+ timeout: nil)
1045
1092
  ```
1046
1093
 
1047
1094
  This method expects `selector` to point to an
@@ -1079,6 +1126,7 @@ def tap_point(
1079
1126
  modifiers: nil,
1080
1127
  noWaitAfter: nil,
1081
1128
  position: nil,
1129
+ strict: nil,
1082
1130
  timeout: nil,
1083
1131
  trial: nil)
1084
1132
  ```
@@ -1101,7 +1149,7 @@ Shortcut for main frame's [Frame#tap_point](./frame#tap_point).
1101
1149
  ## text_content
1102
1150
 
1103
1151
  ```
1104
- def text_content(selector, timeout: nil)
1152
+ def text_content(selector, strict: nil, timeout: nil)
1105
1153
  ```
1106
1154
 
1107
1155
  Returns `element.textContent`.
@@ -1122,6 +1170,7 @@ def type(
1122
1170
  text,
1123
1171
  delay: nil,
1124
1172
  noWaitAfter: nil,
1173
+ strict: nil,
1125
1174
  timeout: nil)
1126
1175
  ```
1127
1176
 
@@ -1145,6 +1194,7 @@ def uncheck(
1145
1194
  force: nil,
1146
1195
  noWaitAfter: nil,
1147
1196
  position: nil,
1197
+ strict: nil,
1148
1198
  timeout: nil,
1149
1199
  trial: nil)
1150
1200
  ```
@@ -1213,7 +1263,7 @@ throw an error if the page is closed before the [`event: Page.console`] event is
1213
1263
  def expect_download(predicate: nil, timeout: nil, &block)
1214
1264
  ```
1215
1265
 
1216
- Performs action and waits for a new `Download`. If predicate is provided, it passes `Download` value into the
1266
+ Performs action and waits for a new [Download](./download). If predicate is provided, it passes [Download](./download) value into the
1217
1267
  `predicate` function and waits for `predicate(download)` to return a truthy value. Will throw an error if the page is
1218
1268
  closed before the download event is fired.
1219
1269
 
@@ -1394,7 +1444,7 @@ puts response.body
1394
1444
  ## wait_for_selector
1395
1445
 
1396
1446
  ```
1397
- def wait_for_selector(selector, state: nil, timeout: nil)
1447
+ def wait_for_selector(selector, state: nil, strict: nil, timeout: nil)
1398
1448
  ```
1399
1449
 
1400
1450
  Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
@@ -0,0 +1,31 @@
1
+ ---
2
+ sidebar_position: 6
3
+ ---
4
+
5
+ # Playwright inspector
6
+
7
+ Playwright provides an useful inspector.
8
+ https://playwright.dev/docs/inspector/
9
+
10
+ ## Overview
11
+
12
+ ```ruby {4,8}
13
+ playwright.chromium.launch(headless: false) do |browser|
14
+ browser.new_context do |context|
15
+ # This method call should be put just after creating BrowserContext.
16
+ context.enable_debug_console!
17
+
18
+ page = context.new_pagè
19
+ page.goto('http://example.com/')
20
+ page.pause
21
+ end
22
+ end
23
+ ```
24
+
25
+ `page.pause` requires Playwright debug session, and it can be enabled by calling `BrowserContext#enable_debug_console!` in advance.
26
+
27
+ Note that since Ruby is not officially supported in Playwright, many limitations exist. We CANNOT
28
+
29
+ * Launch inspector via `PWDEBUG=1`
30
+ * Debug without inspector UI (`PWDEBUG=console` is not working well)
31
+ * Show Ruby code in inspector
@@ -1,5 +1,5 @@
1
1
  ---
2
- sidebar_position: 6
2
+ sidebar_position: 7
3
3
  ---
4
4
 
5
5
  # Playwright on Alpine Linux
@@ -14,7 +14,7 @@ Keep in mind repeatedly that persistent browser context is NOT RECOMMENDED for m
14
14
 
15
15
  ## Pause automation for manual operation
16
16
 
17
- `Page#pause` is not implemented yet, however we can use `binding.pry` (with `pry-byebug` installed) instead.
17
+ We can simply use `binding.pry` (with `pry-byebug` installed).
18
18
 
19
19
  ```ruby {4}
20
20
  playwright.chromium.launch_persistent_context('./data/', headless: false) do |context|
@@ -158,6 +158,7 @@
158
158
  * enabled?
159
159
  * hidden?
160
160
  * visible?
161
+ * locator
161
162
  * name
162
163
  * page
163
164
  * parent_frame
@@ -205,6 +206,17 @@
205
206
  * message
206
207
  * type
207
208
 
209
+ ## Download
210
+
211
+ * cancel
212
+ * delete
213
+ * failure
214
+ * page
215
+ * path
216
+ * save_as
217
+ * suggested_filename
218
+ * url
219
+
208
220
  ## Page
209
221
 
210
222
  * add_init_script
@@ -245,9 +257,10 @@
245
257
  * enabled?
246
258
  * hidden?
247
259
  * visible?
260
+ * locator
248
261
  * main_frame
249
262
  * opener
250
- * ~~pause~~
263
+ * pause
251
264
  * pdf
252
265
  * press
253
266
  * query_selector
@@ -364,6 +377,49 @@
364
377
  * start
365
378
  * stop
366
379
 
380
+ ## Locator
381
+
382
+ * all_inner_texts
383
+ * all_text_contents
384
+ * bounding_box
385
+ * check
386
+ * click
387
+ * count
388
+ * dblclick
389
+ * dispatch_event
390
+ * element_handle
391
+ * element_handles
392
+ * evaluate
393
+ * evaluate_all
394
+ * evaluate_handle
395
+ * fill
396
+ * first
397
+ * focus
398
+ * get_attribute
399
+ * hover
400
+ * inner_html
401
+ * inner_text
402
+ * input_value
403
+ * checked?
404
+ * disabled?
405
+ * editable?
406
+ * enabled?
407
+ * hidden?
408
+ * visible?
409
+ * last
410
+ * locator
411
+ * nth
412
+ * press
413
+ * screenshot
414
+ * scroll_into_view_if_needed
415
+ * select_option
416
+ * select_text
417
+ * set_input_files
418
+ * tap_point
419
+ * text_content
420
+ * type
421
+ * uncheck
422
+
367
423
  ## Android
368
424
 
369
425
  * devices
data/lib/playwright.rb CHANGED
@@ -17,7 +17,6 @@ require 'playwright/utils'
17
17
  require 'playwright/api_implementation'
18
18
  require 'playwright/channel'
19
19
  require 'playwright/channel_owner'
20
- require 'playwright/download'
21
20
  require 'playwright/http_headers'
22
21
  require 'playwright/input_files'
23
22
  require 'playwright/connection'
@@ -250,7 +250,32 @@ module Playwright
250
250
  raise unless safe_close_error?(err)
251
251
  end
252
252
 
253
+ # REMARK: enable_debug_console is playwright-ruby-client specific method.
254
+ def enable_debug_console!
255
+ # Ruby is not supported in Playwright officially,
256
+ # and causes error:
257
+ #
258
+ # Error:
259
+ # ===============================
260
+ # Unsupported language: 'ruby'
261
+ # ===============================
262
+ #
263
+ # So, launch inspector as Python app.
264
+ # NOTE: This should be used only for Page#pause at this moment.
265
+ @channel.send_message_to_server('recorderSupplementEnable', language: :python)
266
+ @debug_console_enabled = true
267
+ end
268
+
269
+ class DebugConsoleNotEnabledError < StandardError
270
+ def initialize
271
+ super('Debug console should be enabled in advance, by calling `browser_context.enable_debug_console!`')
272
+ end
273
+ end
274
+
253
275
  def pause
276
+ unless @debug_console_enabled
277
+ raise DebugConsoleNotEnabledError.new
278
+ end
254
279
  @channel.send_message_to_server('pause')
255
280
  end
256
281