playwright-ruby-client 0.8.1 → 1.14.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) 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/download.md +97 -0
  5. data/documentation/docs/api/element_handle.md +28 -3
  6. data/documentation/docs/api/experimental/android.md +15 -2
  7. data/documentation/docs/api/frame.md +116 -114
  8. data/documentation/docs/api/locator.md +650 -0
  9. data/documentation/docs/api/mouse.md +3 -4
  10. data/documentation/docs/api/page.md +109 -19
  11. data/documentation/docs/api/request.md +15 -19
  12. data/documentation/docs/api/touchscreen.md +8 -0
  13. data/documentation/docs/api/tracing.md +13 -12
  14. data/documentation/docs/api/worker.md +37 -0
  15. data/documentation/docs/article/guides/inspector.md +31 -0
  16. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +1 -1
  17. data/documentation/docs/article/guides/semi_automation.md +1 -1
  18. data/documentation/docs/include/api_coverage.md +70 -14
  19. data/lib/playwright.rb +0 -1
  20. data/lib/playwright/accessibility_impl.rb +50 -0
  21. data/lib/playwright/channel_owners/browser_context.rb +70 -0
  22. data/lib/playwright/channel_owners/frame.rb +79 -33
  23. data/lib/playwright/channel_owners/page.rb +133 -42
  24. data/lib/playwright/channel_owners/request.rb +8 -8
  25. data/lib/playwright/channel_owners/worker.rb +23 -0
  26. data/lib/playwright/{download.rb → download_impl.rb} +1 -1
  27. data/lib/playwright/javascript/expression.rb +5 -4
  28. data/lib/playwright/locator_impl.rb +314 -0
  29. data/lib/playwright/timeout_settings.rb +4 -4
  30. data/lib/playwright/touchscreen_impl.rb +7 -0
  31. data/lib/playwright/tracing_impl.rb +9 -8
  32. data/lib/playwright/version.rb +2 -2
  33. data/lib/playwright_api/accessibility.rb +1 -1
  34. data/lib/playwright_api/android.rb +21 -8
  35. data/lib/playwright_api/android_device.rb +6 -6
  36. data/lib/playwright_api/browser.rb +6 -6
  37. data/lib/playwright_api/browser_context.rb +16 -11
  38. data/lib/playwright_api/browser_type.rb +6 -6
  39. data/lib/playwright_api/cdp_session.rb +6 -6
  40. data/lib/playwright_api/console_message.rb +6 -6
  41. data/lib/playwright_api/dialog.rb +6 -6
  42. data/lib/playwright_api/download.rb +70 -0
  43. data/lib/playwright_api/element_handle.rb +34 -20
  44. data/lib/playwright_api/frame.rb +85 -53
  45. data/lib/playwright_api/js_handle.rb +6 -6
  46. data/lib/playwright_api/locator.rb +509 -0
  47. data/lib/playwright_api/page.rb +91 -57
  48. data/lib/playwright_api/playwright.rb +6 -6
  49. data/lib/playwright_api/request.rb +6 -6
  50. data/lib/playwright_api/response.rb +6 -6
  51. data/lib/playwright_api/route.rb +6 -6
  52. data/lib/playwright_api/selectors.rb +6 -6
  53. data/lib/playwright_api/touchscreen.rb +1 -1
  54. data/lib/playwright_api/web_socket.rb +6 -6
  55. data/lib/playwright_api/worker.rb +16 -6
  56. metadata +13 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e631604c0af31dc184fd1bfe6953be910d4f19be8613e8a2a11c83a3d5e9049
4
- data.tar.gz: b320853082ae065cc09195f09e35f9a5bf18edc3105c729c9bd4a4daeb804948
3
+ metadata.gz: 88c8fbe4451b00ed8eba172f656e0171fb2580d555eefb4d2aa0cc1a13f86fc4
4
+ data.tar.gz: 3d307147cc4a23356d561f9528ef95343984bf4623ad77ebb6e479ce4f4f9462
5
5
  SHA512:
6
- metadata.gz: 1ea608b469db2082b899c3b4c10cbfea703f222a79fb255a0d07d03eb46eacbd0274cb98c1c32a9241f120f5059bdb20fbc82a65a072c05e616bdbd4b76586aa
7
- data.tar.gz: 50ea41552e79e96add337084c9a38961bae124dfcaf04c9fe3ab61ceb2cd5e8738f0ae6fffdb6e04157416593f351bc7177e03e0da75cf51a80e929e1bce3f42
6
+ metadata.gz: 647702705f820c268e5b858a1cd587b0e8f32f16415df2fd7b91505a221cadc20400fc9f2db188964fe4759f4734c8b30bc15c265434d2ac2b78e0683228c192
7
+ data.tar.gz: b4af0552e547d28be8c9390441bb7131d61fcea36fb5d3d293fd6985d6b47d3925e1c3bf27aa5f4e59243fc03ad751355acc20cb4e63b6e7489c47abb55b1864
@@ -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
  ```
@@ -0,0 +1,97 @@
1
+ ---
2
+ sidebar_position: 10
3
+ ---
4
+
5
+ # Download
6
+
7
+ [Download](./download) objects are dispatched by page via the [`event: Page.download`] event.
8
+
9
+ All the downloaded files belonging to the browser context are deleted when the browser context is closed.
10
+
11
+ Download event is emitted once the download starts. Download path becomes available once download completes:
12
+
13
+ ```ruby
14
+ download = page.expect_download do
15
+ page.click('a')
16
+ end
17
+
18
+ # wait for download to complete
19
+ path = download.path
20
+ ```
21
+
22
+ > NOTE: Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the
23
+ downloaded content. If `acceptDownloads` is not set, download events are emitted, but the actual download is not
24
+ performed and user has no access to the downloaded files.
25
+
26
+ ## cancel
27
+
28
+ ```
29
+ def cancel
30
+ ```
31
+
32
+ Cancels a download. Will not fail if the download is already finished or canceled. Upon successful cancellations,
33
+ `download.failure()` would resolve to `'canceled'`.
34
+
35
+ ## delete
36
+
37
+ ```
38
+ def delete
39
+ ```
40
+
41
+ Deletes the downloaded file. Will wait for the download to finish if necessary.
42
+
43
+ ## failure
44
+
45
+ ```
46
+ def failure
47
+ ```
48
+
49
+ Returns download error if any. Will wait for the download to finish if necessary.
50
+
51
+ ## page
52
+
53
+ ```
54
+ def page
55
+ ```
56
+
57
+ Get the page that the download belongs to.
58
+
59
+ ## path
60
+
61
+ ```
62
+ def path
63
+ ```
64
+
65
+ Returns path to the downloaded file in case of successful download. The method will wait for the download to finish if
66
+ necessary. The method throws when connected remotely.
67
+
68
+ Note that the download's file name is a random GUID, use [Download#suggested_filename](./download#suggested_filename) to get suggested file
69
+ name.
70
+
71
+ ## save_as
72
+
73
+ ```
74
+ def save_as(path)
75
+ ```
76
+
77
+ Copy the download to a user-specified path. It is safe to call this method while the download is still in progress. Will
78
+ wait for the download to finish if necessary.
79
+
80
+ ## suggested_filename
81
+
82
+ ```
83
+ def suggested_filename
84
+ ```
85
+
86
+ Returns suggested filename for this download. It is typically computed by the browser from the
87
+ [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) response header
88
+ or the `download` attribute. See the spec on [whatwg](https://html.spec.whatwg.org/#downloading-resources). Different
89
+ browsers can use different logic for computing it.
90
+
91
+ ## url
92
+
93
+ ```
94
+ def url
95
+ ```
96
+
97
+ Returns downloaded url.
@@ -10,10 +10,8 @@ ElementHandle represents an in-page DOM element. ElementHandles can be created w
10
10
  method.
11
11
 
12
12
  ```ruby
13
- page.goto("https://example.com")
14
13
  href_element = page.query_selector("a")
15
14
  href_element.click
16
- # ...
17
15
  ```
18
16
 
19
17
  ElementHandle prevents DOM element from garbage collection unless the handle is disposed with
@@ -22,6 +20,33 @@ ElementHandle prevents DOM element from garbage collection unless the handle is
22
20
  ElementHandle instances can be used as an argument in [Page#eval_on_selector](./page#eval_on_selector) and [Page#evaluate](./page#evaluate)
23
21
  methods.
24
22
 
23
+ > NOTE: In most cases, you would want to use the [Locator](./locator) object instead. You should only use [ElementHandle](./element_handle) if you
24
+ want to retain a handle to a particular DOM Node that you intend to pass into [Page#evaluate](./page#evaluate) as an argument.
25
+
26
+ The difference between the [Locator](./locator) and ElementHandle is that the ElementHandle points to a particular element, while
27
+ [Locator](./locator) captures the logic of how to retrieve an element.
28
+
29
+ In the example below, handle points to a particular DOM element on page. If that element changes text or is used by
30
+ React to render an entirely different component, handle is still pointing to that very DOM element. This can lead to
31
+ unexpected behaviors.
32
+
33
+ ```ruby
34
+ handle = page.query_selector("text=Submit")
35
+ handle.hover
36
+ handle.click
37
+ ```
38
+
39
+ With the locator, every time the `element` is used, up-to-date DOM element is located in the page using the selector. So
40
+ in the snippet below, underlying DOM element is going to be located twice.
41
+
42
+ ```ruby
43
+ locator = page.locator("text=Submit")
44
+ locator.hover
45
+ locator.click
46
+ ```
47
+
48
+
49
+
25
50
  ## bounding_box
26
51
 
27
52
  ```
@@ -306,7 +331,7 @@ Returns the `element.innerText`.
306
331
  def input_value(timeout: nil)
307
332
  ```
308
333
 
309
- 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.
310
335
 
311
336
  ## checked?
312
337
 
@@ -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
 
@@ -68,6 +59,7 @@ def check(
68
59
  force: nil,
69
60
  noWaitAfter: nil,
70
61
  position: nil,
62
+ strict: nil,
71
63
  timeout: nil,
72
64
  trial: nil)
73
65
  ```
@@ -106,6 +98,7 @@ def click(
106
98
  modifiers: nil,
107
99
  noWaitAfter: nil,
108
100
  position: nil,
101
+ strict: nil,
109
102
  timeout: nil,
110
103
  trial: nil)
111
104
  ```
@@ -140,6 +133,7 @@ def dblclick(
140
133
  modifiers: nil,
141
134
  noWaitAfter: nil,
142
135
  position: nil,
136
+ strict: nil,
143
137
  timeout: nil,
144
138
  trial: nil)
145
139
  ```
@@ -161,16 +155,20 @@ zero timeout disables this.
161
155
  ## dispatch_event
162
156
 
163
157
  ```
164
- def dispatch_event(selector, type, eventInit: nil, timeout: nil)
158
+ def dispatch_event(
159
+ selector,
160
+ type,
161
+ eventInit: nil,
162
+ strict: nil,
163
+ timeout: nil)
165
164
  ```
166
165
 
167
166
  The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the element,
168
167
  `click` is dispatched. This is equivalent to calling
169
168
  [element.click()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click).
170
169
 
171
- ```python sync title=example_de439a4f4839a9b1bc72dbe0890d6b989c437620ba1b88a2150faa79f98184fc.py
170
+ ```ruby
172
171
  frame.dispatch_event("button#submit", "click")
173
-
174
172
  ```
175
173
 
176
174
  Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties
@@ -187,11 +185,10 @@ Since `eventInit` is event-specific, please refer to the events documentation fo
187
185
 
188
186
  You can also specify [JSHandle](./js_handle) as the property value if you want live objects to be passed into the event:
189
187
 
190
- ```python sync title=example_5410f49339561b3cc9d91c7548c8195a570c8be704bb62f45d90c68f869d450d.py
188
+ ```ruby
191
189
  # note you can only create data_transfer in chromium and firefox
192
190
  data_transfer = frame.evaluate_handle("new DataTransfer()")
193
- frame.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
194
-
191
+ frame.dispatch_event("#source", "dragstart", eventInit: { dataTransfer: data_transfer })
195
192
  ```
196
193
 
197
194
 
@@ -204,6 +201,9 @@ def drag_and_drop(
204
201
  target,
205
202
  force: nil,
206
203
  noWaitAfter: nil,
204
+ sourcePosition: nil,
205
+ strict: nil,
206
+ targetPosition: nil,
207
207
  timeout: nil,
208
208
  trial: nil)
209
209
  ```
@@ -213,7 +213,7 @@ def drag_and_drop(
213
213
  ## eval_on_selector
214
214
 
215
215
  ```
216
- def eval_on_selector(selector, expression, arg: nil)
216
+ def eval_on_selector(selector, expression, arg: nil, strict: nil)
217
217
  ```
218
218
 
219
219
  Returns the return value of `expression`.
@@ -227,11 +227,10 @@ return its value.
227
227
 
228
228
  Examples:
229
229
 
230
- ```python sync title=example_6814d0e91763f4d27a0d6a380c36d62b551e4c3e902d1157012dde0a49122abe.py
230
+ ```ruby
231
231
  search_value = frame.eval_on_selector("#search", "el => el.value")
232
232
  preload_href = frame.eval_on_selector("link[rel=preload]", "el => el.href")
233
- html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello")
234
-
233
+ html = frame.eval_on_selector(".main-container", "(e, suffix) => e.outerHTML + suffix", arg: "hello")
235
234
  ```
236
235
 
237
236
 
@@ -252,9 +251,8 @@ return its value.
252
251
 
253
252
  Examples:
254
253
 
255
- ```python sync title=example_618e7f8f681d1c4a1c0c9b8d23892e37cbbef013bf3d8906fd4311c51d9819d7.py
256
- divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
257
-
254
+ ```ruby
255
+ divs_counts = frame.eval_on_selector_all("div", "(divs, min) => divs.length >= min", arg: 10)
258
256
  ```
259
257
 
260
258
 
@@ -274,28 +272,25 @@ If the function passed to the [Frame#evaluate](./frame#evaluate) returns a non-[
274
272
  [Frame#evaluate](./frame#evaluate) returns `undefined`. Playwright also supports transferring some additional values that are
275
273
  not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`.
276
274
 
277
- ```python sync title=example_15a235841cd1bc56fad6e3c8aaea2a30e352fedd8238017f22f97fc70e058d2b.py
278
- result = frame.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
279
- print(result) # prints "56"
280
-
275
+ ```ruby
276
+ result = frame.evaluate("([x, y]) => Promise.resolve(x * y)", arg: [7, 8])
277
+ puts result # => "56"
281
278
  ```
282
279
 
283
280
  A string can also be passed in instead of a function.
284
281
 
285
- ```python sync title=example_9c73167b900498bca191abc2ce2627e063f84b0abc8ce3a117416cb734602760.py
286
- print(frame.evaluate("1 + 2")) # prints "3"
282
+ ```ruby
283
+ puts frame.evaluate("1 + 2") # => 3
287
284
  x = 10
288
- print(frame.evaluate(f"1 + {x}")) # prints "11"
289
-
285
+ puts frame.evaluate("1 + #{x}") # => "11"
290
286
  ```
291
287
 
292
288
  [ElementHandle](./element_handle) instances can be passed as an argument to the [Frame#evaluate](./frame#evaluate):
293
289
 
294
- ```python sync title=example_05568c81173717fa6841099571d8a66e14fc0853e01684630d1622baedc25f67.py
290
+ ```ruby
295
291
  body_handle = frame.query_selector("body")
296
- html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
297
- body_handle.dispose()
298
-
292
+ html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", arg: [body_handle, "hello"])
293
+ body_handle.dispose
299
294
  ```
300
295
 
301
296
 
@@ -314,10 +309,9 @@ The only difference between [Frame#evaluate](./frame#evaluate) and [Frame#evalua
314
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
315
310
  [Frame#evaluate_handle](./frame#evaluate_handle) would wait for the promise to resolve and return its value.
316
311
 
317
- ```python sync title=example_a1c8e837e826079359d01d6f7eecc64092a45d8c74280d23ee9039c379132c51.py
312
+ ```ruby
318
313
  a_window_handle = frame.evaluate_handle("Promise.resolve(window)")
319
314
  a_window_handle # handle for the window object.
320
-
321
315
  ```
322
316
 
323
317
  A string can also be passed in instead of a function.
@@ -345,6 +339,7 @@ def fill(
345
339
  value,
346
340
  force: nil,
347
341
  noWaitAfter: nil,
342
+ strict: nil,
348
343
  timeout: nil)
349
344
  ```
350
345
 
@@ -362,7 +357,7 @@ To send fine-grained keyboard events, use [Frame#type](./frame#type).
362
357
  ## focus
363
358
 
364
359
  ```
365
- def focus(selector, timeout: nil)
360
+ def focus(selector, strict: nil, timeout: nil)
366
361
  ```
367
362
 
368
363
  This method fetches an element with `selector` and focuses it. If there's no element matching `selector`, the method
@@ -381,11 +376,10 @@ frame.
381
376
 
382
377
  This method throws an error if the frame has been detached before `frameElement()` returns.
383
378
 
384
- ```python sync title=example_e6b4fdef29a401d84b17acfa319bee08f39e1f28e07c435463622220c6a24747.py
385
- frame_element = frame.frame_element()
386
- content_frame = frame_element.content_frame()
387
- assert frame == content_frame
388
-
379
+ ```ruby
380
+ frame_element = frame.frame_element
381
+ content_frame = frame_element.content_frame
382
+ puts frame == content_frame # => true
389
383
  ```
390
384
 
391
385
 
@@ -393,7 +387,7 @@ assert frame == content_frame
393
387
  ## get_attribute
394
388
 
395
389
  ```
396
- def get_attribute(selector, name, timeout: nil)
390
+ def get_attribute(selector, name, strict: nil, timeout: nil)
397
391
  ```
398
392
 
399
393
  Returns element attribute value.
@@ -431,6 +425,7 @@ def hover(
431
425
  force: nil,
432
426
  modifiers: nil,
433
427
  position: nil,
428
+ strict: nil,
434
429
  timeout: nil,
435
430
  trial: nil)
436
431
  ```
@@ -449,7 +444,7 @@ zero timeout disables this.
449
444
  ## inner_html
450
445
 
451
446
  ```
452
- def inner_html(selector, timeout: nil)
447
+ def inner_html(selector, strict: nil, timeout: nil)
453
448
  ```
454
449
 
455
450
  Returns `element.innerHTML`.
@@ -457,7 +452,7 @@ Returns `element.innerHTML`.
457
452
  ## inner_text
458
453
 
459
454
  ```
460
- def inner_text(selector, timeout: nil)
455
+ def inner_text(selector, strict: nil, timeout: nil)
461
456
  ```
462
457
 
463
458
  Returns `element.innerText`.
@@ -465,15 +460,15 @@ Returns `element.innerText`.
465
460
  ## input_value
466
461
 
467
462
  ```
468
- def input_value(selector, timeout: nil)
463
+ def input_value(selector, strict: nil, timeout: nil)
469
464
  ```
470
465
 
471
- 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.
472
467
 
473
468
  ## checked?
474
469
 
475
470
  ```
476
- def checked?(selector, timeout: nil)
471
+ def checked?(selector, strict: nil, timeout: nil)
477
472
  ```
478
473
 
479
474
  Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
@@ -489,7 +484,7 @@ Returns `true` if the frame has been detached, or `false` otherwise.
489
484
  ## disabled?
490
485
 
491
486
  ```
492
- def disabled?(selector, timeout: nil)
487
+ def disabled?(selector, strict: nil, timeout: nil)
493
488
  ```
494
489
 
495
490
  Returns whether the element is disabled, the opposite of [enabled](https://playwright.dev/python/docs/actionability).
@@ -497,7 +492,7 @@ Returns whether the element is disabled, the opposite of [enabled](https://playw
497
492
  ## editable?
498
493
 
499
494
  ```
500
- def editable?(selector, timeout: nil)
495
+ def editable?(selector, strict: nil, timeout: nil)
501
496
  ```
502
497
 
503
498
  Returns whether the element is [editable](https://playwright.dev/python/docs/actionability).
@@ -505,7 +500,7 @@ Returns whether the element is [editable](https://playwright.dev/python/docs/act
505
500
  ## enabled?
506
501
 
507
502
  ```
508
- def enabled?(selector, timeout: nil)
503
+ def enabled?(selector, strict: nil, timeout: nil)
509
504
  ```
510
505
 
511
506
  Returns whether the element is [enabled](https://playwright.dev/python/docs/actionability).
@@ -513,7 +508,7 @@ Returns whether the element is [enabled](https://playwright.dev/python/docs/acti
513
508
  ## hidden?
514
509
 
515
510
  ```
516
- def hidden?(selector, timeout: nil)
511
+ def hidden?(selector, strict: nil, timeout: nil)
517
512
  ```
518
513
 
519
514
  Returns whether the element is hidden, the opposite of [visible](https://playwright.dev/python/docs/actionability). `selector` that does not
@@ -522,12 +517,24 @@ match any elements is considered hidden.
522
517
  ## visible?
523
518
 
524
519
  ```
525
- def visible?(selector, timeout: nil)
520
+ def visible?(selector, strict: nil, timeout: nil)
526
521
  ```
527
522
 
528
523
  Returns whether the element is [visible](https://playwright.dev/python/docs/actionability). `selector` that does not match any elements is
529
524
  considered not visible.
530
525
 
526
+ ## locator
527
+
528
+ ```
529
+ def locator(selector)
530
+ ```
531
+
532
+ The method returns an element locator that can be used to perform actions in the frame. Locator is resolved to the
533
+ element immediately before performing an action, so a series of actions on the same locator can in fact be performed on
534
+ different DOM elements. That would happen if the DOM structure between those actions has changed.
535
+
536
+ Note that locator always implies visibility, so it will always be locating visible elements.
537
+
531
538
  ## name
532
539
 
533
540
  ```
@@ -564,6 +571,7 @@ def press(
564
571
  key,
565
572
  delay: nil,
566
573
  noWaitAfter: nil,
574
+ strict: nil,
567
575
  timeout: nil)
568
576
  ```
569
577
 
@@ -587,7 +595,7 @@ modifier, modifier is pressed and being held while the subsequent key is being p
587
595
  ## query_selector
588
596
 
589
597
  ```
590
- def query_selector(selector)
598
+ def query_selector(selector, strict: nil)
591
599
  ```
592
600
 
593
601
  Returns the ElementHandle pointing to the frame element.
@@ -617,6 +625,7 @@ def select_option(
617
625
  label: nil,
618
626
  force: nil,
619
627
  noWaitAfter: nil,
628
+ strict: nil,
620
629
  timeout: nil)
621
630
  ```
622
631
 
@@ -631,14 +640,13 @@ Returns the array of option values that have been successfully selected.
631
640
 
632
641
  Triggers a `change` and `input` event once all the provided options have been selected.
633
642
 
634
- ```python sync title=example_230c12044664b222bf35d6163b1e415c011d87d9911a4d39648c7f601b344a31.py
643
+ ```ruby
635
644
  # single selection matching the value
636
- frame.select_option("select#colors", "blue")
645
+ frame.select_option("select#colors", value: "blue")
637
646
  # single selection matching both the label
638
- frame.select_option("select#colors", label="blue")
647
+ frame.select_option("select#colors", label: "blue")
639
648
  # multiple selection
640
- frame.select_option("select#colors", value=["red", "green", "blue"])
641
-
649
+ frame.select_option("select#colors", value: ["red", "green", "blue"])
642
650
  ```
643
651
 
644
652
 
@@ -655,7 +663,12 @@ alias: `content=`
655
663
  ## set_input_files
656
664
 
657
665
  ```
658
- def set_input_files(selector, files, noWaitAfter: nil, timeout: nil)
666
+ def set_input_files(
667
+ selector,
668
+ files,
669
+ noWaitAfter: nil,
670
+ strict: nil,
671
+ timeout: nil)
659
672
  ```
660
673
 
661
674
  This method expects `selector` to point to an
@@ -673,6 +686,7 @@ def tap_point(
673
686
  modifiers: nil,
674
687
  noWaitAfter: nil,
675
688
  position: nil,
689
+ strict: nil,
676
690
  timeout: nil,
677
691
  trial: nil)
678
692
  ```
@@ -693,7 +707,7 @@ zero timeout disables this.
693
707
  ## text_content
694
708
 
695
709
  ```
696
- def text_content(selector, timeout: nil)
710
+ def text_content(selector, strict: nil, timeout: nil)
697
711
  ```
698
712
 
699
713
  Returns `element.textContent`.
@@ -714,6 +728,7 @@ def type(
714
728
  text,
715
729
  delay: nil,
716
730
  noWaitAfter: nil,
731
+ strict: nil,
717
732
  timeout: nil)
718
733
  ```
719
734
 
@@ -722,10 +737,9 @@ send fine-grained keyboard events. To fill values in form fields, use [Frame#fil
722
737
 
723
738
  To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./keyboard#press).
724
739
 
725
- ```python sync title=example_beae7f0d11663c3c98b9d3a8e6ab76b762578cf2856e3b04ad8e42bfb23bb1e1.py
740
+ ```ruby
726
741
  frame.type("#mytextarea", "hello") # types instantly
727
- frame.type("#mytextarea", "world", delay=100) # types slower, like a user
728
-
742
+ frame.type("#mytextarea", "world", delay: 100) # types slower, like a user
729
743
  ```
730
744
 
731
745
 
@@ -738,6 +752,7 @@ def uncheck(
738
752
  force: nil,
739
753
  noWaitAfter: nil,
740
754
  position: nil,
755
+ strict: nil,
741
756
  timeout: nil,
742
757
  trial: nil)
743
758
  ```
@@ -774,28 +789,16 @@ Returns when the `expression` returns a truthy value, returns that value.
774
789
 
775
790
  The [Frame#wait_for_function](./frame#wait_for_function) can be used to observe viewport size change:
776
791
 
777
- ```python sync title=example_2f82dcf15fa9338be87a4faf7fe7de3c542040924db1e1ad1c98468ec0f425ce.py
778
- from playwright.sync_api import sync_playwright
779
-
780
- def run(playwright):
781
- webkit = playwright.webkit
782
- browser = webkit.launch()
783
- page = browser.new_page()
784
- page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
785
- page.main_frame.wait_for_function("() => window.x > 0")
786
- browser.close()
787
-
788
- with sync_playwright() as playwright:
789
- run(playwright)
790
-
792
+ ```ruby
793
+ frame.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);")
794
+ frame.wait_for_function("() => window.x > 0")
791
795
  ```
792
796
 
793
797
  To pass an argument to the predicate of `frame.waitForFunction` function:
794
798
 
795
- ```python sync title=example_8b95be0fb4d149890f7817d9473428a50dc631d3a75baf89846648ca6a157562.py
799
+ ```ruby
796
800
  selector = ".foo"
797
- frame.wait_for_function("selector => !!document.querySelector(selector)", selector)
798
-
801
+ frame.wait_for_function("selector => !!document.querySelector(selector)", arg: selector)
799
802
  ```
800
803
 
801
804
 
@@ -811,10 +814,9 @@ Waits for the required load state to be reached.
811
814
  This returns when the frame reaches a required load state, `load` by default. The navigation must have been committed
812
815
  when this method is called. If current document has already reached the required state, resolves immediately.
813
816
 
814
- ```python sync title=example_fe41b79b58d046cda4673ededd4d216cb97a63204fcba69375ce8a84ea3f6894.py
817
+ ```ruby
815
818
  frame.click("button") # click triggers navigation.
816
- frame.wait_for_load_state() # the promise resolves after "load" event.
817
-
819
+ frame.wait_for_load_state # the promise resolves after "load" event.
818
820
  ```
819
821
 
820
822
 
@@ -832,11 +834,10 @@ History API usage, the navigation will resolve with `null`.
832
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
833
835
  the frame to navigate. Consider this example:
834
836
 
835
- ```python sync title=example_03f0ac17eb6c1ce8780cfa83c4ae15a9ddbfde3f96c96f36fdf3fbf9aac721f7.py
836
- with frame.expect_navigation():
837
- frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
838
- # Resolves after navigation has finished
839
-
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
840
841
  ```
841
842
 
842
843
  > NOTE: Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is
@@ -845,7 +846,7 @@ considered a navigation.
845
846
  ## wait_for_selector
846
847
 
847
848
  ```
848
- def wait_for_selector(selector, state: nil, timeout: nil)
849
+ def wait_for_selector(selector, state: nil, strict: nil, timeout: nil)
849
850
  ```
850
851
 
851
852
  Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
@@ -857,25 +858,27 @@ selector doesn't satisfy the condition for the `timeout` milliseconds, the funct
857
858
 
858
859
  This method works across navigations:
859
860
 
860
- ```python sync title=example_a5b9dd4745d45ac630e5953be1c1815ae8e8ab03399fb35f45ea77c434f17eea.py
861
- 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
+
862
870
 
863
- def run(playwright):
864
- chromium = playwright.chromium
865
- browser = chromium.launch()
866
- page = browser.new_page()
867
- for current_url in ["https://google.com", "https://bbc.com"]:
868
- page.goto(current_url, wait_until="domcontentloaded")
869
- element = page.main_frame.wait_for_selector("img")
870
- print("Loaded image: " + str(element.get_attribute("src")))
871
- browser.close()
872
871
 
873
- with sync_playwright() as playwright:
874
- run(playwright)
872
+ ## wait_for_timeout
875
873
 
874
+ ```
875
+ def wait_for_timeout(timeout)
876
876
  ```
877
877
 
878
+ Waits for the given `timeout` in milliseconds.
878
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.
879
882
 
880
883
  ## wait_for_url
881
884
 
@@ -885,10 +888,9 @@ def wait_for_url(url, timeout: nil, waitUntil: nil)
885
888
 
886
889
  Waits for the frame to navigate to the given URL.
887
890
 
888
- ```python sync title=example_86a9a19ec4c41e1a5ac302fbca9a3d3d6dca3fe3314e065b8062ddf5f75abfbd.py
891
+ ```ruby
889
892
  frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
890
893
  frame.wait_for_url("**/target.html")
891
-
892
894
  ```
893
895
 
894
896