playwright-ruby-client 0.8.1 → 0.9.0

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