playwright-ruby-client 1.16.1 → 1.17.beta1
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.
- checksums.yaml +4 -4
- data/documentation/docs/api/element_handle.md +2 -3
- data/documentation/docs/api/frame.md +30 -0
- data/documentation/docs/api/frame_locator.md +70 -0
- data/documentation/docs/api/locator.md +17 -2
- data/documentation/docs/api/page.md +33 -3
- data/documentation/docs/api/selectors.md +1 -1
- data/documentation/docs/api/tracing.md +2 -2
- data/documentation/docs/include/api_coverage.md +13 -0
- data/lib/playwright/channel_owners/artifact.rb +1 -6
- data/lib/playwright/channel_owners/browser.rb +6 -8
- data/lib/playwright/channel_owners/browser_context.rb +0 -3
- data/lib/playwright/channel_owners/browser_type.rb +0 -1
- data/lib/playwright/channel_owners/frame.rb +10 -6
- data/lib/playwright/channel_owners/page.rb +13 -10
- data/lib/playwright/connection.rb +9 -0
- data/lib/playwright/frame_locator_impl.rb +49 -0
- data/lib/playwright/locator_impl.rb +13 -5
- data/lib/playwright/tracing_impl.rb +6 -9
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright/video.rb +3 -0
- data/lib/playwright.rb +2 -1
- data/lib/playwright_api/api_request_context.rb +3 -0
- data/lib/playwright_api/browser_context.rb +5 -0
- data/lib/playwright_api/element_handle.rb +2 -3
- data/lib/playwright_api/frame.rb +26 -1
- data/lib/playwright_api/frame_locator.rb +51 -0
- data/lib/playwright_api/locator.rb +12 -2
- data/lib/playwright_api/page.rb +33 -8
- data/lib/playwright_api/playwright.rb +5 -0
- data/lib/playwright_api/selectors.rb +2 -2
- data/lib/playwright_api/tracing.rb +4 -4
- data/lib/playwright_api/worker.rb +4 -4
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2fe4b12d358a45b087eee4cdfc8aecb03b9e6df7d012158e4a04a042d290d13
|
4
|
+
data.tar.gz: ed57849806349f58419ead4e64164cafb94de892fa5d4be7cbf9f6e67867eb5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4245e2cc937bf4dd85ab98848b4a56149d796d814407598e17258f64154d85f252a3f993e13c8a81bda0f0112ffc5c1fa93e699c7fb691e3bf7592f27cd6133
|
7
|
+
data.tar.gz: 5680b2040b8ff3927b952e9f5321355137c298c697b0ba5ecde686eb89545f8b3444e191da3fe8ba22315df6fc982e452bdff73d71774419ee32a08e9a0281ef
|
@@ -9,6 +9,8 @@ sidebar_position: 10
|
|
9
9
|
ElementHandle represents an in-page DOM element. ElementHandles can be created with the [Page#query_selector](./page#query_selector)
|
10
10
|
method.
|
11
11
|
|
12
|
+
> NOTE: The use of ElementHandle is discouraged, use [Locator](./locator) objects and web-first assertions instead.
|
13
|
+
|
12
14
|
```ruby
|
13
15
|
href_element = page.query_selector("a")
|
14
16
|
href_element.click
|
@@ -20,9 +22,6 @@ ElementHandle prevents DOM element from garbage collection unless the handle is
|
|
20
22
|
ElementHandle instances can be used as an argument in [Page#eval_on_selector](./page#eval_on_selector) and [Page#evaluate](./page#evaluate)
|
21
23
|
methods.
|
22
24
|
|
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
25
|
The difference between the [Locator](./locator) and ElementHandle is that the ElementHandle points to a particular element, while
|
27
26
|
[Locator](./locator) captures the logic of how to retrieve an element.
|
28
27
|
|
@@ -218,6 +218,9 @@ def eval_on_selector(selector, expression, arg: nil, strict: nil)
|
|
218
218
|
|
219
219
|
Returns the return value of `expression`.
|
220
220
|
|
221
|
+
> NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
|
222
|
+
tests. Use [Locator#evaluate](./locator#evaluate), other [Locator](./locator) helper methods or web-first assertions instead.
|
223
|
+
|
221
224
|
The method finds an element matching the specified selector within the frame and passes it as a first argument to
|
222
225
|
`expression`. See [Working with selectors](https://playwright.dev/python/docs/selectors) for more details. If no elements match the selector, the
|
223
226
|
method throws an error.
|
@@ -243,6 +246,9 @@ def eval_on_selector_all(selector, expression, arg: nil)
|
|
243
246
|
|
244
247
|
Returns the return value of `expression`.
|
245
248
|
|
249
|
+
> NOTE: In most cases, [Locator#evaluate_all](./locator#evaluate_all), other [Locator](./locator) helper methods and web-first assertions do a
|
250
|
+
better job.
|
251
|
+
|
246
252
|
The method finds all elements matching the specified selector within the frame and passes an array of matched elements
|
247
253
|
as a first argument to `expression`. See [Working with selectors](https://playwright.dev/python/docs/selectors) for more details.
|
248
254
|
|
@@ -384,6 +390,23 @@ puts frame == content_frame # => true
|
|
384
390
|
|
385
391
|
|
386
392
|
|
393
|
+
## frame_locator
|
394
|
+
|
395
|
+
```
|
396
|
+
def frame_locator(selector)
|
397
|
+
```
|
398
|
+
|
399
|
+
When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
|
400
|
+
that iframe. Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe
|
401
|
+
id="my-frame">`:
|
402
|
+
|
403
|
+
```ruby
|
404
|
+
locator = frame.frame_locator("#my-iframe").locator("text=Submit")
|
405
|
+
locator.click
|
406
|
+
```
|
407
|
+
|
408
|
+
|
409
|
+
|
387
410
|
## get_attribute
|
388
411
|
|
389
412
|
```
|
@@ -598,6 +621,8 @@ def query_selector(selector, strict: nil)
|
|
598
621
|
|
599
622
|
Returns the ElementHandle pointing to the frame element.
|
600
623
|
|
624
|
+
> NOTE: The use of [ElementHandle](./element_handle) is discouraged, use [Locator](./locator) objects and web-first assertions instead.
|
625
|
+
|
601
626
|
The method finds an element matching the specified selector within the frame. See
|
602
627
|
[Working with selectors](https://playwright.dev/python/docs/selectors) for more details. If no elements match the selector, returns `null`.
|
603
628
|
|
@@ -609,6 +634,8 @@ def query_selector_all(selector)
|
|
609
634
|
|
610
635
|
Returns the ElementHandles pointing to the frame elements.
|
611
636
|
|
637
|
+
> NOTE: The use of [ElementHandle](./element_handle) is discouraged, use [Locator](./locator) objects instead.
|
638
|
+
|
612
639
|
The method finds all elements matching the specified selector within the frame. See
|
613
640
|
[Working with selectors](https://playwright.dev/python/docs/selectors) for more details. If no elements match the selector, returns empty array.
|
614
641
|
|
@@ -878,6 +905,9 @@ def wait_for_selector(selector, state: nil, strict: nil, timeout: nil)
|
|
878
905
|
Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
|
879
906
|
`detached`.
|
880
907
|
|
908
|
+
> NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator](./locator) objects and
|
909
|
+
web-first assertions make the code wait-for-selector-free.
|
910
|
+
|
881
911
|
Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
|
882
912
|
the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
|
883
913
|
selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
|
@@ -0,0 +1,70 @@
|
|
1
|
+
---
|
2
|
+
sidebar_position: 10
|
3
|
+
---
|
4
|
+
|
5
|
+
# FrameLocator
|
6
|
+
|
7
|
+
FrameLocator represents a view to the `iframe` on the page. It captures the logic sufficient to retrieve the `iframe`
|
8
|
+
and locate elements in that iframe. FrameLocator can be created with either [Page#frame_locator](./page#frame_locator) or
|
9
|
+
[Locator#frame_locator](./locator#frame_locator) method.
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
locator = page.frame_locator("my-frame").locator("text=Submit")
|
13
|
+
locator.click
|
14
|
+
```
|
15
|
+
|
16
|
+
**Strictness**
|
17
|
+
|
18
|
+
Frame locators are strict. This means that all operations on frame locators will throw if more than one element matches
|
19
|
+
given selector.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
# Throws if there are several frames in DOM:
|
23
|
+
page.frame_locator('.result-frame').locator('button').click
|
24
|
+
|
25
|
+
# Works because we explicitly tell locator to pick the first frame:
|
26
|
+
page.frame_locator('.result-frame').first.locator('button').click
|
27
|
+
```
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
## first
|
32
|
+
|
33
|
+
```
|
34
|
+
def first
|
35
|
+
```
|
36
|
+
|
37
|
+
Returns locator to the first matching frame.
|
38
|
+
|
39
|
+
## frame_locator
|
40
|
+
|
41
|
+
```
|
42
|
+
def frame_locator(selector)
|
43
|
+
```
|
44
|
+
|
45
|
+
When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
|
46
|
+
that iframe.
|
47
|
+
|
48
|
+
## last
|
49
|
+
|
50
|
+
```
|
51
|
+
def last
|
52
|
+
```
|
53
|
+
|
54
|
+
Returns locator to the last matching frame.
|
55
|
+
|
56
|
+
## locator
|
57
|
+
|
58
|
+
```
|
59
|
+
def locator(selector)
|
60
|
+
```
|
61
|
+
|
62
|
+
The method finds an element matching the specified selector in the FrameLocator's subtree.
|
63
|
+
|
64
|
+
## nth
|
65
|
+
|
66
|
+
```
|
67
|
+
def nth(index)
|
68
|
+
```
|
69
|
+
|
70
|
+
Returns locator to the n-th matching frame.
|
@@ -329,6 +329,22 @@ def focus(timeout: nil)
|
|
329
329
|
|
330
330
|
Calls [focus](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on the element.
|
331
331
|
|
332
|
+
## frame_locator
|
333
|
+
|
334
|
+
```
|
335
|
+
def frame_locator(selector)
|
336
|
+
```
|
337
|
+
|
338
|
+
When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
|
339
|
+
that iframe:
|
340
|
+
|
341
|
+
```ruby
|
342
|
+
locator = page.frame_locator("text=Submit").locator("text=Submit")
|
343
|
+
locator.click
|
344
|
+
```
|
345
|
+
|
346
|
+
|
347
|
+
|
332
348
|
## get_attribute
|
333
349
|
|
334
350
|
```
|
@@ -445,8 +461,7 @@ Returns locator to the last matching element.
|
|
445
461
|
def locator(selector)
|
446
462
|
```
|
447
463
|
|
448
|
-
The method finds an element matching the specified selector in the [Locator](./locator)'s subtree.
|
449
|
-
[Working with selectors](https://playwright.dev/python/docs/selectors) for more details.
|
464
|
+
The method finds an element matching the specified selector in the [Locator](./locator)'s subtree.
|
450
465
|
|
451
466
|
## nth
|
452
467
|
|
@@ -315,6 +315,9 @@ page.evaluate("matchMedia('(prefers-color-scheme: no-preference)').matches") # =
|
|
315
315
|
def eval_on_selector(selector, expression, arg: nil, strict: nil)
|
316
316
|
```
|
317
317
|
|
318
|
+
> NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
|
319
|
+
tests. Use [Locator#evaluate](./locator#evaluate), other [Locator](./locator) helper methods or web-first assertions instead.
|
320
|
+
|
318
321
|
The method finds an element matching the specified selector within the page and passes it as a first argument to
|
319
322
|
`expression`. If no elements match the selector, the method throws an error. Returns the value of `expression`.
|
320
323
|
|
@@ -337,6 +340,9 @@ Shortcut for main frame's [Frame#eval_on_selector](./frame#eval_on_selector).
|
|
337
340
|
def eval_on_selector_all(selector, expression, arg: nil)
|
338
341
|
```
|
339
342
|
|
343
|
+
> NOTE: In most cases, [Locator#evaluate_all](./locator#evaluate_all), other [Locator](./locator) helper methods and web-first assertions do a
|
344
|
+
better job.
|
345
|
+
|
340
346
|
The method finds all elements matching the specified selector within the page and passes an array of matched elements as
|
341
347
|
a first argument to `expression`. Returns the result of `expression` invocation.
|
342
348
|
|
@@ -575,6 +581,23 @@ frame = page.frame(url: /.*domain.*/)
|
|
575
581
|
|
576
582
|
|
577
583
|
|
584
|
+
## frame_locator
|
585
|
+
|
586
|
+
```
|
587
|
+
def frame_locator(selector)
|
588
|
+
```
|
589
|
+
|
590
|
+
When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
|
591
|
+
that iframe. Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe
|
592
|
+
id="my-frame">`:
|
593
|
+
|
594
|
+
```ruby
|
595
|
+
locator = page.frame_locator("#my-iframe").locator("text=Submit")
|
596
|
+
locator.click
|
597
|
+
```
|
598
|
+
|
599
|
+
|
600
|
+
|
578
601
|
## frames
|
579
602
|
|
580
603
|
```
|
@@ -905,8 +928,10 @@ page.screenshot(path: "o.png")
|
|
905
928
|
def query_selector(selector, strict: nil)
|
906
929
|
```
|
907
930
|
|
931
|
+
> NOTE: The use of [ElementHandle](./element_handle) is discouraged, use [Locator](./locator) objects and web-first assertions instead.
|
932
|
+
|
908
933
|
The method finds an element matching the specified selector within the page. If no elements match the selector, the
|
909
|
-
return value resolves to `null`. To wait for an element on the page, use [
|
934
|
+
return value resolves to `null`. To wait for an element on the page, use [Locator#wait_for](./locator#wait_for).
|
910
935
|
|
911
936
|
Shortcut for main frame's [Frame#query_selector](./frame#query_selector).
|
912
937
|
|
@@ -916,6 +941,8 @@ Shortcut for main frame's [Frame#query_selector](./frame#query_selector).
|
|
916
941
|
def query_selector_all(selector)
|
917
942
|
```
|
918
943
|
|
944
|
+
> NOTE: The use of [ElementHandle](./element_handle) is discouraged, use [Locator](./locator) objects and web-first assertions instead.
|
945
|
+
|
919
946
|
The method finds all elements matching the specified selector within the page. If no elements match the selector, the
|
920
947
|
return value resolves to `[]`.
|
921
948
|
|
@@ -927,8 +954,8 @@ Shortcut for main frame's [Frame#query_selector_all](./frame#query_selector_all)
|
|
927
954
|
def reload(timeout: nil, waitUntil: nil)
|
928
955
|
```
|
929
956
|
|
930
|
-
|
931
|
-
last redirect.
|
957
|
+
This method reloads the current page, in the same way as if the user had triggered a browser refresh. Returns the main
|
958
|
+
resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
|
932
959
|
|
933
960
|
## route
|
934
961
|
|
@@ -1484,6 +1511,9 @@ def wait_for_selector(selector, state: nil, strict: nil, timeout: nil)
|
|
1484
1511
|
Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
|
1485
1512
|
`detached`.
|
1486
1513
|
|
1514
|
+
> NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator](./locator) objects and
|
1515
|
+
web-first assertions make the code wait-for-selector-free.
|
1516
|
+
|
1487
1517
|
Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
|
1488
1518
|
the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
|
1489
1519
|
selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
|
@@ -41,7 +41,7 @@ playwright.chromium.launch do |browser|
|
|
41
41
|
page.click('tag=div >> text="Click me"')
|
42
42
|
|
43
43
|
# Can use it in any methods supporting selectors.
|
44
|
-
button_count = page.
|
44
|
+
button_count = page.locator('tag=button').count
|
45
45
|
button_count # => 1
|
46
46
|
end
|
47
47
|
```
|
@@ -23,7 +23,7 @@ end
|
|
23
23
|
## start
|
24
24
|
|
25
25
|
```
|
26
|
-
def start(name: nil, screenshots: nil, snapshots: nil)
|
26
|
+
def start(name: nil, screenshots: nil, snapshots: nil, title: nil)
|
27
27
|
```
|
28
28
|
|
29
29
|
Start tracing.
|
@@ -40,7 +40,7 @@ context.tracing.stop(path: 'trace.zip')
|
|
40
40
|
## start_chunk
|
41
41
|
|
42
42
|
```
|
43
|
-
def start_chunk
|
43
|
+
def start_chunk(title: nil)
|
44
44
|
```
|
45
45
|
|
46
46
|
Start a new trace chunk. If you'd like to record multiple traces on the same [BrowserContext](./browser_context), use
|
@@ -167,6 +167,7 @@
|
|
167
167
|
* fill
|
168
168
|
* focus
|
169
169
|
* frame_element
|
170
|
+
* frame_locator
|
170
171
|
* get_attribute
|
171
172
|
* goto
|
172
173
|
* hover
|
@@ -264,6 +265,7 @@
|
|
264
265
|
* fill
|
265
266
|
* focus
|
266
267
|
* frame
|
268
|
+
* frame_locator
|
267
269
|
* frames
|
268
270
|
* get_attribute
|
269
271
|
* go_back
|
@@ -359,6 +361,7 @@
|
|
359
361
|
* expect_event
|
360
362
|
* expect_page
|
361
363
|
* ~~wait_for_event~~
|
364
|
+
* ~~request~~
|
362
365
|
* tracing
|
363
366
|
|
364
367
|
## CDPSession
|
@@ -393,6 +396,7 @@
|
|
393
396
|
* chromium
|
394
397
|
* devices
|
395
398
|
* firefox
|
399
|
+
* ~~request~~
|
396
400
|
* selectors
|
397
401
|
* webkit
|
398
402
|
|
@@ -421,6 +425,7 @@
|
|
421
425
|
* fill
|
422
426
|
* first
|
423
427
|
* focus
|
428
|
+
* frame_locator
|
424
429
|
* get_attribute
|
425
430
|
* hover
|
426
431
|
* inner_html
|
@@ -448,6 +453,14 @@
|
|
448
453
|
* uncheck
|
449
454
|
* wait_for
|
450
455
|
|
456
|
+
## FrameLocator
|
457
|
+
|
458
|
+
* first
|
459
|
+
* frame_locator
|
460
|
+
* last
|
461
|
+
* locator
|
462
|
+
* nth
|
463
|
+
|
451
464
|
## Android
|
452
465
|
|
453
466
|
* devices
|
@@ -1,14 +1,13 @@
|
|
1
1
|
module Playwright
|
2
2
|
define_channel_owner :Artifact do
|
3
3
|
private def after_initialize
|
4
|
-
@remote = false
|
5
4
|
@absolute_path = @initializer['absolutePath']
|
6
5
|
end
|
7
6
|
|
8
7
|
attr_reader :absolute_path
|
9
8
|
|
10
9
|
def path_after_finished
|
11
|
-
if @remote
|
10
|
+
if @connection.remote?
|
12
11
|
raise "Path is not available when using browser_type.connect(). Use save_as() to save a local copy."
|
13
12
|
end
|
14
13
|
@channel.send_message_to_server('pathAfterFinished')
|
@@ -30,9 +29,5 @@ module Playwright
|
|
30
29
|
def cancel
|
31
30
|
@channel.send_message_to_server('cancel')
|
32
31
|
end
|
33
|
-
|
34
|
-
private def update_as_remote
|
35
|
-
@remote = true
|
36
|
-
end
|
37
32
|
end
|
38
33
|
end
|
@@ -7,7 +7,7 @@ module Playwright
|
|
7
7
|
private def after_initialize
|
8
8
|
@connected = true
|
9
9
|
@closed_or_closing = false
|
10
|
-
@
|
10
|
+
@should_close_connection_on_close = false
|
11
11
|
|
12
12
|
@contexts = Set.new
|
13
13
|
@channel.on('close', method(:on_close))
|
@@ -58,6 +58,9 @@ module Playwright
|
|
58
58
|
return if @closed_or_closing
|
59
59
|
@closed_or_closing = true
|
60
60
|
@channel.send_message_to_server('close')
|
61
|
+
if @should_close_connection_on_close
|
62
|
+
@connection.stop
|
63
|
+
end
|
61
64
|
nil
|
62
65
|
rescue => err
|
63
66
|
raise unless safe_close_error?(err)
|
@@ -99,13 +102,8 @@ module Playwright
|
|
99
102
|
@contexts << context
|
100
103
|
end
|
101
104
|
|
102
|
-
|
103
|
-
|
104
|
-
@remote = true
|
105
|
-
end
|
106
|
-
|
107
|
-
private def remote?
|
108
|
-
@remote
|
105
|
+
private def should_close_connection_on_close!
|
106
|
+
@should_close_connection_on_close = true
|
109
107
|
end
|
110
108
|
|
111
109
|
# called from BrowserContext#on_close with send(:remove_context), so keep private.
|
@@ -276,9 +276,6 @@ module Playwright
|
|
276
276
|
def close
|
277
277
|
if @options && @options.key?(:recordHar)
|
278
278
|
har = ChannelOwners::Artifact.from(@channel.send_message_to_server('harExport'))
|
279
|
-
if @browser.send(:remote?)
|
280
|
-
har.update_as_remote
|
281
|
-
end
|
282
279
|
har.save_as(@options[:recordHar][:path])
|
283
280
|
har.delete
|
284
281
|
end
|
@@ -54,7 +54,6 @@ module Playwright
|
|
54
54
|
|
55
55
|
result = @channel.send_message_to_server_result('connectOverCDP', params)
|
56
56
|
browser = ChannelOwners::Browser.from(result['browser'])
|
57
|
-
browser.send(:update_as_remote)
|
58
57
|
|
59
58
|
if result['defaultContext']
|
60
59
|
context = ChannelOwners::BrowserContext.from(result['defaultContext'])
|
@@ -110,8 +110,8 @@ module Playwright
|
|
110
110
|
def wait_for_load_state(state: nil, timeout: nil)
|
111
111
|
option_state = state || 'load'
|
112
112
|
option_timeout = timeout || @page.send(:timeout_settings).navigation_timeout
|
113
|
-
unless %w(load domcontentloaded networkidle).include?(option_state)
|
114
|
-
raise ArgumentError.new('state: expected one of (load|domcontentloaded|networkidle)')
|
113
|
+
unless %w(load domcontentloaded networkidle commit).include?(option_state)
|
114
|
+
raise ArgumentError.new('state: expected one of (load|domcontentloaded|networkidle|commit)')
|
115
115
|
end
|
116
116
|
if @load_states.include?(option_state)
|
117
117
|
return
|
@@ -191,10 +191,6 @@ module Playwright
|
|
191
191
|
@channel.send_message_to_server('isVisible', params)
|
192
192
|
end
|
193
193
|
|
194
|
-
def locator(selector)
|
195
|
-
LocatorImpl.new(frame: self, timeout_settings: @page.send(:timeout_settings), selector: selector)
|
196
|
-
end
|
197
|
-
|
198
194
|
def dispatch_event(selector, type, eventInit: nil, strict: nil, timeout: nil)
|
199
195
|
params = {
|
200
196
|
selector: selector,
|
@@ -404,6 +400,14 @@ module Playwright
|
|
404
400
|
nil
|
405
401
|
end
|
406
402
|
|
403
|
+
def locator(selector)
|
404
|
+
LocatorImpl.new(frame: self, timeout_settings: @page.send(:timeout_settings), selector: selector)
|
405
|
+
end
|
406
|
+
|
407
|
+
def frame_locator(selector)
|
408
|
+
FrameLocatorImpl.new(frame: self, timeout_settings: @page.send(:timeout_settings), frame_selector: selector)
|
409
|
+
end
|
410
|
+
|
407
411
|
def focus(selector, strict: nil, timeout: nil)
|
408
412
|
params = { selector: selector, strict: strict, timeout: timeout }.compact
|
409
413
|
@channel.send_message_to_server('focus', params)
|
@@ -138,9 +138,6 @@ module Playwright
|
|
138
138
|
|
139
139
|
private def on_download(params)
|
140
140
|
artifact = ChannelOwners::Artifact.from(params['artifact'])
|
141
|
-
if @browser_context.browser.send(:remote?)
|
142
|
-
artifact.update_as_remote
|
143
|
-
end
|
144
141
|
download = DownloadImpl.new(
|
145
142
|
page: self,
|
146
143
|
url: params['url'],
|
@@ -152,9 +149,6 @@ module Playwright
|
|
152
149
|
|
153
150
|
private def on_video(params)
|
154
151
|
artifact = ChannelOwners::Artifact.from(params['artifact'])
|
155
|
-
if @browser_context.browser.send(:remote?)
|
156
|
-
artifact.update_as_remote
|
157
|
-
end
|
158
152
|
video.send(:set_artifact, artifact)
|
159
153
|
end
|
160
154
|
|
@@ -261,10 +255,6 @@ module Playwright
|
|
261
255
|
@main_frame.visible?(selector, strict: strict, timeout: timeout)
|
262
256
|
end
|
263
257
|
|
264
|
-
def locator(selector)
|
265
|
-
@main_frame.locator(selector)
|
266
|
-
end
|
267
|
-
|
268
258
|
def dispatch_event(selector, type, eventInit: nil, strict: nil, timeout: nil)
|
269
259
|
@main_frame.dispatch_event(selector, type, eventInit: eventInit, strict: strict, timeout: timeout)
|
270
260
|
end
|
@@ -568,6 +558,14 @@ module Playwright
|
|
568
558
|
timeout: timeout)
|
569
559
|
end
|
570
560
|
|
561
|
+
def locator(selector)
|
562
|
+
@main_frame.locator(selector)
|
563
|
+
end
|
564
|
+
|
565
|
+
def frame_locator(selector)
|
566
|
+
@main_frame.frame_locator(selector)
|
567
|
+
end
|
568
|
+
|
571
569
|
def focus(selector, strict: nil, timeout: nil)
|
572
570
|
@main_frame.focus(selector, strict: strict, timeout: timeout)
|
573
571
|
end
|
@@ -925,6 +923,11 @@ module Playwright
|
|
925
923
|
@workers.delete(worker)
|
926
924
|
end
|
927
925
|
|
926
|
+
# called from Video
|
927
|
+
private def remote_connection?
|
928
|
+
@connection.remote?
|
929
|
+
end
|
930
|
+
|
928
931
|
# Expose guid for library developers.
|
929
932
|
# Not intended to be used by users.
|
930
933
|
def guid
|
@@ -21,6 +21,15 @@ module Playwright
|
|
21
21
|
@waiting_for_object = {} # Hash[ guid => Promise<ChannelOwner> ]
|
22
22
|
@callbacks = {} # Hash [ guid => Promise<ChannelOwner> ]
|
23
23
|
@root_object = RootChannelOwner.new(self)
|
24
|
+
@remote = false
|
25
|
+
end
|
26
|
+
|
27
|
+
def mark_as_remote
|
28
|
+
@remote = true
|
29
|
+
end
|
30
|
+
|
31
|
+
def remote?
|
32
|
+
@remote
|
24
33
|
end
|
25
34
|
|
26
35
|
def async_run
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Playwright
|
2
|
+
define_api_implementation :FrameLocatorImpl do
|
3
|
+
def initialize(frame:, timeout_settings:, frame_selector:)
|
4
|
+
@frame = frame
|
5
|
+
@timeout_settings = timeout_settings
|
6
|
+
@frame_selector = frame_selector
|
7
|
+
end
|
8
|
+
|
9
|
+
def locator(selector)
|
10
|
+
LocatorImpl.new(
|
11
|
+
frame: @frame,
|
12
|
+
timeout_settings: @timeout_settings,
|
13
|
+
selector: "#{@frame_selector} >> control=enter-frame >> #{selector}",
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def frame_locator(selector)
|
18
|
+
FrameLocatorImpl.new(
|
19
|
+
frame: @frame,
|
20
|
+
timeout_settings: @timeout_settings,
|
21
|
+
frame_selector: "#{@frame_selector} >> control=enter-frame >> #{selector}",
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def first
|
26
|
+
FrameLocatorImpl.new(
|
27
|
+
frame: @frame,
|
28
|
+
timeout_settings: @timeout_settings,
|
29
|
+
frame_selector: "#{@frame_selector} >> nth=0",
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def last
|
34
|
+
FrameLocatorImpl.new(
|
35
|
+
frame: @frame,
|
36
|
+
timeout_settings: @timeout_settings,
|
37
|
+
frame_selector: "#{@frame_selector} >> nth=-1",
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def nth(index)
|
42
|
+
FrameLocatorImpl.new(
|
43
|
+
frame: @frame,
|
44
|
+
timeout_settings: @timeout_settings,
|
45
|
+
frame_selector: "#{@frame_selector} >> nth=#{index}",
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -11,17 +11,17 @@ module Playwright
|
|
11
11
|
end
|
12
12
|
|
13
13
|
private def with_element(timeout: nil, &block)
|
14
|
+
timeout_or_default = @timeout_settings.timeout(timeout)
|
14
15
|
start_time = Time.now
|
15
16
|
|
16
|
-
handle = @frame.wait_for_selector(@selector, strict: true, state: 'attached', timeout:
|
17
|
+
handle = @frame.wait_for_selector(@selector, strict: true, state: 'attached', timeout: timeout_or_default)
|
17
18
|
unless handle
|
18
19
|
raise "Could not resolve #{@selector} to DOM Element"
|
19
20
|
end
|
20
21
|
|
21
|
-
call_options = {
|
22
|
-
|
23
|
-
|
24
|
-
end
|
22
|
+
call_options = {
|
23
|
+
timeout: (timeout_or_default - (Time.now - start_time) * 1000).to_i,
|
24
|
+
}
|
25
25
|
|
26
26
|
begin
|
27
27
|
block.call(handle, call_options)
|
@@ -130,6 +130,14 @@ module Playwright
|
|
130
130
|
)
|
131
131
|
end
|
132
132
|
|
133
|
+
def frame_locator(selector)
|
134
|
+
FrameLocatorImpl.new(
|
135
|
+
frame: @frame,
|
136
|
+
timeout_settings: @timeout_settings,
|
137
|
+
frame_selector: "#{@selector} >> #{selector}",
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
133
141
|
def element_handle(timeout: nil)
|
134
142
|
@frame.wait_for_selector(@selector, strict: true, state: 'attached', timeout: timeout)
|
135
143
|
end
|
@@ -5,18 +5,18 @@ module Playwright
|
|
5
5
|
@context = context
|
6
6
|
end
|
7
7
|
|
8
|
-
def start(name: nil, screenshots: nil, snapshots: nil)
|
8
|
+
def start(name: nil, title: nil, screenshots: nil, snapshots: nil)
|
9
9
|
params = {
|
10
10
|
name: name,
|
11
11
|
screenshots: screenshots,
|
12
12
|
snapshots: snapshots,
|
13
13
|
}.compact
|
14
14
|
@channel.send_message_to_server('tracingStart', params)
|
15
|
-
@channel.send_message_to_server('tracingStartChunk')
|
15
|
+
@channel.send_message_to_server('tracingStartChunk', { title: title }.compact)
|
16
16
|
end
|
17
17
|
|
18
|
-
def start_chunk
|
19
|
-
@channel.send_message_to_server('tracingStartChunk')
|
18
|
+
def start_chunk(title: nil)
|
19
|
+
@channel.send_message_to_server('tracingStartChunk', { title: title }.compact)
|
20
20
|
end
|
21
21
|
|
22
22
|
def stop_chunk(path: nil)
|
@@ -29,13 +29,10 @@ module Playwright
|
|
29
29
|
end
|
30
30
|
|
31
31
|
private def do_stop_chunk(path:)
|
32
|
-
|
33
|
-
artifact = ChannelOwners::Artifact.from_nullable(
|
32
|
+
result = @channel.send_message_to_server_result('tracingStopChunk', save: !path.nil?, skipCompress: false)
|
33
|
+
artifact = ChannelOwners::Artifact.from_nullable(result['artifact'])
|
34
34
|
return unless artifact
|
35
35
|
|
36
|
-
if @context.browser.send(:remote?)
|
37
|
-
artifact.update_as_remote
|
38
|
-
end
|
39
36
|
artifact.save_as(path)
|
40
37
|
artifact.delete
|
41
38
|
end
|
data/lib/playwright/version.rb
CHANGED
data/lib/playwright/video.rb
CHANGED
@@ -22,6 +22,9 @@ module Playwright
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def path
|
25
|
+
if @page.send(:remote_connection?)
|
26
|
+
raise 'Path is not available when using browserType.connect(). Use save_as() to save a local copy.'
|
27
|
+
end
|
25
28
|
wait_for_artifact_and do |artifact|
|
26
29
|
artifact.absolute_path
|
27
30
|
end
|
data/lib/playwright.rb
CHANGED
@@ -135,13 +135,14 @@ module Playwright
|
|
135
135
|
|
136
136
|
transport = WebSocketTransport.new(ws_endpoint: ws_endpoint)
|
137
137
|
connection = Connection.new(transport)
|
138
|
+
connection.mark_as_remote
|
138
139
|
connection.async_run
|
139
140
|
|
140
141
|
execution =
|
141
142
|
begin
|
142
143
|
playwright = connection.initialize_playwright
|
143
144
|
browser = playwright.send(:pre_launched_browser)
|
144
|
-
browser.
|
145
|
+
browser.should_close_connection_on_close!
|
145
146
|
Execution.new(connection, PlaywrightApi.wrap(playwright), PlaywrightApi.wrap(browser))
|
146
147
|
rescue
|
147
148
|
connection.stop
|
@@ -10,9 +10,12 @@ module Playwright
|
|
10
10
|
# method will automatically follow redirects.
|
11
11
|
def delete(
|
12
12
|
url,
|
13
|
+
data: nil,
|
13
14
|
failOnStatusCode: nil,
|
15
|
+
form: nil,
|
14
16
|
headers: nil,
|
15
17
|
ignoreHTTPSErrors: nil,
|
18
|
+
multipart: nil,
|
16
19
|
params: nil,
|
17
20
|
timeout: nil)
|
18
21
|
raise NotImplementedError.new('delete is not implemented yet.')
|
@@ -20,6 +20,11 @@ module Playwright
|
|
20
20
|
# ```
|
21
21
|
class BrowserContext < PlaywrightApi
|
22
22
|
|
23
|
+
# API testing helper associated with this context. Requests made with this API will use context cookies.
|
24
|
+
def request # property
|
25
|
+
raise NotImplementedError.new('request is not implemented yet.')
|
26
|
+
end
|
27
|
+
|
23
28
|
def tracing # property
|
24
29
|
wrap_impl(@impl.tracing)
|
25
30
|
end
|
@@ -6,6 +6,8 @@ module Playwright
|
|
6
6
|
# ElementHandle represents an in-page DOM element. ElementHandles can be created with the [`method: Page.querySelector`]
|
7
7
|
# method.
|
8
8
|
#
|
9
|
+
# > NOTE: The use of ElementHandle is discouraged, use `Locator` objects and web-first assertions instead.
|
10
|
+
#
|
9
11
|
# ```python sync
|
10
12
|
# href_element = page.query_selector("a")
|
11
13
|
# href_element.click()
|
@@ -17,9 +19,6 @@ module Playwright
|
|
17
19
|
# ElementHandle instances can be used as an argument in [`method: Page.evalOnSelector`] and [`method: Page.evaluate`]
|
18
20
|
# methods.
|
19
21
|
#
|
20
|
-
# > NOTE: In most cases, you would want to use the `Locator` object instead. You should only use `ElementHandle` if you
|
21
|
-
# want to retain a handle to a particular DOM Node that you intend to pass into [`method: Page.evaluate`] as an argument.
|
22
|
-
#
|
23
22
|
# The difference between the `Locator` and ElementHandle is that the ElementHandle points to a particular element, while
|
24
23
|
# `Locator` captures the logic of how to retrieve an element.
|
25
24
|
#
|
data/lib/playwright_api/frame.rb
CHANGED
@@ -183,6 +183,9 @@ module Playwright
|
|
183
183
|
|
184
184
|
# Returns the return value of `expression`.
|
185
185
|
#
|
186
|
+
# > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
|
187
|
+
# tests. Use [`method: Locator.evaluate`], other `Locator` helper methods or web-first assertions instead.
|
188
|
+
#
|
186
189
|
# The method finds an element matching the specified selector within the frame and passes it as a first argument to
|
187
190
|
# `expression`. See [Working with selectors](./selectors.md) for more details. If no elements match the selector, the
|
188
191
|
# method throws an error.
|
@@ -203,6 +206,9 @@ module Playwright
|
|
203
206
|
|
204
207
|
# Returns the return value of `expression`.
|
205
208
|
#
|
209
|
+
# > NOTE: In most cases, [`method: Locator.evaluateAll`], other `Locator` helper methods and web-first assertions do a
|
210
|
+
# better job.
|
211
|
+
#
|
206
212
|
# The method finds all elements matching the specified selector within the frame and passes an array of matched elements
|
207
213
|
# as a first argument to `expression`. See [Working with selectors](./selectors.md) for more details.
|
208
214
|
#
|
@@ -243,7 +249,7 @@ module Playwright
|
|
243
249
|
# `ElementHandle` instances can be passed as an argument to the [`method: Frame.evaluate`]:
|
244
250
|
#
|
245
251
|
# ```python sync
|
246
|
-
# body_handle = frame.
|
252
|
+
# body_handle = frame.evaluate("document.body")
|
247
253
|
# html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
|
248
254
|
# body_handle.dispose()
|
249
255
|
# ```
|
@@ -324,6 +330,18 @@ module Playwright
|
|
324
330
|
wrap_impl(@impl.frame_element)
|
325
331
|
end
|
326
332
|
|
333
|
+
# When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
|
334
|
+
# that iframe. Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe
|
335
|
+
# id="my-frame">`:
|
336
|
+
#
|
337
|
+
# ```python sync
|
338
|
+
# locator = frame.frame_locator("#my-iframe").locator("text=Submit")
|
339
|
+
# locator.click()
|
340
|
+
# ```
|
341
|
+
def frame_locator(selector)
|
342
|
+
wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
|
343
|
+
end
|
344
|
+
|
327
345
|
# Returns element attribute value.
|
328
346
|
def get_attribute(selector, name, strict: nil, timeout: nil)
|
329
347
|
wrap_impl(@impl.get_attribute(unwrap_impl(selector), unwrap_impl(name), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
@@ -478,6 +496,8 @@ module Playwright
|
|
478
496
|
|
479
497
|
# Returns the ElementHandle pointing to the frame element.
|
480
498
|
#
|
499
|
+
# > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects and web-first assertions instead.
|
500
|
+
#
|
481
501
|
# The method finds an element matching the specified selector within the frame. See
|
482
502
|
# [Working with selectors](./selectors.md) for more details. If no elements match the selector, returns `null`.
|
483
503
|
def query_selector(selector, strict: nil)
|
@@ -486,6 +506,8 @@ module Playwright
|
|
486
506
|
|
487
507
|
# Returns the ElementHandles pointing to the frame elements.
|
488
508
|
#
|
509
|
+
# > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects instead.
|
510
|
+
#
|
489
511
|
# The method finds all elements matching the specified selector within the frame. See
|
490
512
|
# [Working with selectors](./selectors.md) for more details. If no elements match the selector, returns empty array.
|
491
513
|
def query_selector_all(selector)
|
@@ -714,6 +736,9 @@ module Playwright
|
|
714
736
|
# Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
|
715
737
|
# `detached`.
|
716
738
|
#
|
739
|
+
# > NOTE: Playwright automatically waits for element to be ready before performing an action. Using `Locator` objects and
|
740
|
+
# web-first assertions make the code wait-for-selector-free.
|
741
|
+
#
|
717
742
|
# Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
|
718
743
|
# the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
|
719
744
|
# selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Playwright
|
2
|
+
# FrameLocator represents a view to the `iframe` on the page. It captures the logic sufficient to retrieve the `iframe`
|
3
|
+
# and locate elements in that iframe. FrameLocator can be created with either [`method: Page.frameLocator`] or
|
4
|
+
# [`method: Locator.frameLocator`] method.
|
5
|
+
#
|
6
|
+
# ```python sync
|
7
|
+
# locator = page.frame_locator("my-frame").locator("text=Submit")
|
8
|
+
# locator.click()
|
9
|
+
# ```
|
10
|
+
#
|
11
|
+
# **Strictness**
|
12
|
+
#
|
13
|
+
# Frame locators are strict. This means that all operations on frame locators will throw if more than one element matches
|
14
|
+
# given selector.
|
15
|
+
#
|
16
|
+
# ```python sync
|
17
|
+
# # Throws if there are several frames in DOM:
|
18
|
+
# page.frame_locator('.result-frame').locator('button').click()
|
19
|
+
#
|
20
|
+
# # Works because we explicitly tell locator to pick the first frame:
|
21
|
+
# page.frame_locator('.result-frame').first.locator('button').click()
|
22
|
+
# ```
|
23
|
+
class FrameLocator < PlaywrightApi
|
24
|
+
|
25
|
+
# Returns locator to the first matching frame.
|
26
|
+
def first
|
27
|
+
wrap_impl(@impl.first)
|
28
|
+
end
|
29
|
+
|
30
|
+
# When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
|
31
|
+
# that iframe.
|
32
|
+
def frame_locator(selector)
|
33
|
+
wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns locator to the last matching frame.
|
37
|
+
def last
|
38
|
+
wrap_impl(@impl.last)
|
39
|
+
end
|
40
|
+
|
41
|
+
# The method finds an element matching the specified selector in the FrameLocator's subtree.
|
42
|
+
def locator(selector)
|
43
|
+
wrap_impl(@impl.locator(unwrap_impl(selector)))
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns locator to the n-th matching frame.
|
47
|
+
def nth(index)
|
48
|
+
wrap_impl(@impl.nth(unwrap_impl(index)))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -264,6 +264,17 @@ module Playwright
|
|
264
264
|
wrap_impl(@impl.focus(timeout: unwrap_impl(timeout)))
|
265
265
|
end
|
266
266
|
|
267
|
+
# When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
|
268
|
+
# that iframe:
|
269
|
+
#
|
270
|
+
# ```python sync
|
271
|
+
# locator = page.frame_locator("text=Submit").locator("text=Submit")
|
272
|
+
# locator.click()
|
273
|
+
# ```
|
274
|
+
def frame_locator(selector)
|
275
|
+
wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
|
276
|
+
end
|
277
|
+
|
267
278
|
# Returns element attribute value.
|
268
279
|
def get_attribute(name, timeout: nil)
|
269
280
|
wrap_impl(@impl.get_attribute(unwrap_impl(name), timeout: unwrap_impl(timeout)))
|
@@ -338,8 +349,7 @@ module Playwright
|
|
338
349
|
wrap_impl(@impl.last)
|
339
350
|
end
|
340
351
|
|
341
|
-
# The method finds an element matching the specified selector in the `Locator`'s subtree.
|
342
|
-
# [Working with selectors](./selectors.md) for more details.
|
352
|
+
# The method finds an element matching the specified selector in the `Locator`'s subtree.
|
343
353
|
def locator(selector)
|
344
354
|
wrap_impl(@impl.locator(unwrap_impl(selector)))
|
345
355
|
end
|
data/lib/playwright_api/page.rb
CHANGED
@@ -288,6 +288,9 @@ module Playwright
|
|
288
288
|
wrap_impl(@impl.emulate_media(colorScheme: unwrap_impl(colorScheme), forcedColors: unwrap_impl(forcedColors), media: unwrap_impl(media), reducedMotion: unwrap_impl(reducedMotion)))
|
289
289
|
end
|
290
290
|
|
291
|
+
# > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
|
292
|
+
# tests. Use [`method: Locator.evaluate`], other `Locator` helper methods or web-first assertions instead.
|
293
|
+
#
|
291
294
|
# The method finds an element matching the specified selector within the page and passes it as a first argument to
|
292
295
|
# `expression`. If no elements match the selector, the method throws an error. Returns the value of `expression`.
|
293
296
|
#
|
@@ -307,6 +310,9 @@ module Playwright
|
|
307
310
|
wrap_impl(@impl.eval_on_selector(unwrap_impl(selector), unwrap_impl(expression), arg: unwrap_impl(arg), strict: unwrap_impl(strict)))
|
308
311
|
end
|
309
312
|
|
313
|
+
# > NOTE: In most cases, [`method: Locator.evaluateAll`], other `Locator` helper methods and web-first assertions do a
|
314
|
+
# better job.
|
315
|
+
#
|
310
316
|
# The method finds all elements matching the specified selector within the page and passes an array of matched elements as
|
311
317
|
# a first argument to `expression`. Returns the result of `expression` invocation.
|
312
318
|
#
|
@@ -349,7 +355,7 @@ module Playwright
|
|
349
355
|
# `ElementHandle` instances can be passed as an argument to the [`method: Page.evaluate`]:
|
350
356
|
#
|
351
357
|
# ```python sync
|
352
|
-
# body_handle = page.
|
358
|
+
# body_handle = page.evaluate("document.body")
|
353
359
|
# html = page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
|
354
360
|
# body_handle.dispose()
|
355
361
|
# ```
|
@@ -533,6 +539,18 @@ module Playwright
|
|
533
539
|
wrap_impl(@impl.frame(name: unwrap_impl(name), url: unwrap_impl(url)))
|
534
540
|
end
|
535
541
|
|
542
|
+
# When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
|
543
|
+
# that iframe. Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe
|
544
|
+
# id="my-frame">`:
|
545
|
+
#
|
546
|
+
# ```python sync
|
547
|
+
# locator = page.frame_locator("#my-iframe").locator("text=Submit")
|
548
|
+
# locator.click()
|
549
|
+
# ```
|
550
|
+
def frame_locator(selector)
|
551
|
+
wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
|
552
|
+
end
|
553
|
+
|
536
554
|
# An array of all frames attached to the page.
|
537
555
|
def frames
|
538
556
|
wrap_impl(@impl.frames)
|
@@ -791,14 +809,18 @@ module Playwright
|
|
791
809
|
wrap_impl(@impl.press(unwrap_impl(selector), unwrap_impl(key), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
|
792
810
|
end
|
793
811
|
|
812
|
+
# > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects and web-first assertions instead.
|
813
|
+
#
|
794
814
|
# The method finds an element matching the specified selector within the page. If no elements match the selector, the
|
795
|
-
# return value resolves to `null`. To wait for an element on the page, use [`method:
|
815
|
+
# return value resolves to `null`. To wait for an element on the page, use [`method: Locator.waitFor`].
|
796
816
|
#
|
797
817
|
# Shortcut for main frame's [`method: Frame.querySelector`].
|
798
818
|
def query_selector(selector, strict: nil)
|
799
819
|
wrap_impl(@impl.query_selector(unwrap_impl(selector), strict: unwrap_impl(strict)))
|
800
820
|
end
|
801
821
|
|
822
|
+
# > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects and web-first assertions instead.
|
823
|
+
#
|
802
824
|
# The method finds all elements matching the specified selector within the page. If no elements match the selector, the
|
803
825
|
# return value resolves to `[]`.
|
804
826
|
#
|
@@ -807,8 +829,8 @@ module Playwright
|
|
807
829
|
wrap_impl(@impl.query_selector_all(unwrap_impl(selector)))
|
808
830
|
end
|
809
831
|
|
810
|
-
#
|
811
|
-
# last redirect.
|
832
|
+
# This method reloads the current page, in the same way as if the user had triggered a browser refresh. Returns the main
|
833
|
+
# resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
|
812
834
|
def reload(timeout: nil, waitUntil: nil)
|
813
835
|
wrap_impl(@impl.reload(timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
|
814
836
|
end
|
@@ -1267,6 +1289,9 @@ module Playwright
|
|
1267
1289
|
# Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
|
1268
1290
|
# `detached`.
|
1269
1291
|
#
|
1292
|
+
# > NOTE: Playwright automatically waits for element to be ready before performing an action. Using `Locator` objects and
|
1293
|
+
# web-first assertions make the code wait-for-selector-free.
|
1294
|
+
#
|
1270
1295
|
# Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
|
1271
1296
|
# the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
|
1272
1297
|
# selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
|
@@ -1367,13 +1392,13 @@ module Playwright
|
|
1367
1392
|
end
|
1368
1393
|
|
1369
1394
|
# @nodoc
|
1370
|
-
def
|
1371
|
-
wrap_impl(@impl.
|
1395
|
+
def stop_css_coverage
|
1396
|
+
wrap_impl(@impl.stop_css_coverage)
|
1372
1397
|
end
|
1373
1398
|
|
1374
1399
|
# @nodoc
|
1375
|
-
def
|
1376
|
-
wrap_impl(@impl.
|
1400
|
+
def start_css_coverage(resetOnNavigation: nil, reportAnonymousScripts: nil)
|
1401
|
+
wrap_impl(@impl.start_css_coverage(resetOnNavigation: unwrap_impl(resetOnNavigation), reportAnonymousScripts: unwrap_impl(reportAnonymousScripts)))
|
1377
1402
|
end
|
1378
1403
|
|
1379
1404
|
# @nodoc
|
@@ -50,6 +50,11 @@ module Playwright
|
|
50
50
|
wrap_impl(@impl.firefox)
|
51
51
|
end
|
52
52
|
|
53
|
+
# Exposes API that can be used for the Web API testing.
|
54
|
+
def request # property
|
55
|
+
raise NotImplementedError.new('request is not implemented yet.')
|
56
|
+
end
|
57
|
+
|
53
58
|
# Selectors can be used to install custom selector engines. See [Working with selectors](./selectors.md) for more
|
54
59
|
# information.
|
55
60
|
def selectors # property
|
@@ -28,11 +28,11 @@ module Playwright
|
|
28
28
|
# page.set_content('<div><button>Click me</button></div>')
|
29
29
|
#
|
30
30
|
# # Use the selector prefixed with its name.
|
31
|
-
# button = page.
|
31
|
+
# button = page.locator('tag=button')
|
32
32
|
# # Combine it with other selector engines.
|
33
33
|
# page.click('tag=div >> text="Click me"')
|
34
34
|
# # Can use it in any methods supporting selectors.
|
35
|
-
# button_count = page.
|
35
|
+
# button_count = page.locator('tag=button').count()
|
36
36
|
# print(button_count)
|
37
37
|
# browser.close()
|
38
38
|
#
|
@@ -22,8 +22,8 @@ module Playwright
|
|
22
22
|
# page.goto("https://playwright.dev")
|
23
23
|
# context.tracing.stop(path = "trace.zip")
|
24
24
|
# ```
|
25
|
-
def start(name: nil, screenshots: nil, snapshots: nil)
|
26
|
-
wrap_impl(@impl.start(name: unwrap_impl(name), screenshots: unwrap_impl(screenshots), snapshots: unwrap_impl(snapshots)))
|
25
|
+
def start(name: nil, screenshots: nil, snapshots: nil, title: nil)
|
26
|
+
wrap_impl(@impl.start(name: unwrap_impl(name), screenshots: unwrap_impl(screenshots), snapshots: unwrap_impl(snapshots), title: unwrap_impl(title)))
|
27
27
|
end
|
28
28
|
|
29
29
|
# Start a new trace chunk. If you'd like to record multiple traces on the same `BrowserContext`, use
|
@@ -45,8 +45,8 @@ module Playwright
|
|
45
45
|
# # Save a second trace file with different actions.
|
46
46
|
# context.tracing.stop_chunk(path = "trace2.zip")
|
47
47
|
# ```
|
48
|
-
def start_chunk
|
49
|
-
wrap_impl(@impl.start_chunk)
|
48
|
+
def start_chunk(title: nil)
|
49
|
+
wrap_impl(@impl.start_chunk(title: unwrap_impl(title)))
|
50
50
|
end
|
51
51
|
|
52
52
|
# Stop tracing.
|
@@ -44,13 +44,13 @@ module Playwright
|
|
44
44
|
end
|
45
45
|
|
46
46
|
# @nodoc
|
47
|
-
def
|
48
|
-
wrap_impl(@impl.
|
47
|
+
def page=(req)
|
48
|
+
wrap_impl(@impl.page=(unwrap_impl(req)))
|
49
49
|
end
|
50
50
|
|
51
51
|
# @nodoc
|
52
|
-
def
|
53
|
-
wrap_impl(@impl.
|
52
|
+
def context=(req)
|
53
|
+
wrap_impl(@impl.context=(unwrap_impl(req)))
|
54
54
|
end
|
55
55
|
|
56
56
|
# -- inherited from EventEmitter --
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: playwright-ruby-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.17.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- YusukeIwaki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-11-
|
11
|
+
date: 2021-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -227,6 +227,7 @@ files:
|
|
227
227
|
- documentation/docs/api/experimental/android_web_view.md
|
228
228
|
- documentation/docs/api/file_chooser.md
|
229
229
|
- documentation/docs/api/frame.md
|
230
|
+
- documentation/docs/api/frame_locator.md
|
230
231
|
- documentation/docs/api/js_handle.md
|
231
232
|
- documentation/docs/api/keyboard.md
|
232
233
|
- documentation/docs/api/locator.md
|
@@ -308,6 +309,7 @@ files:
|
|
308
309
|
- lib/playwright/event_emitter_proxy.rb
|
309
310
|
- lib/playwright/events.rb
|
310
311
|
- lib/playwright/file_chooser_impl.rb
|
312
|
+
- lib/playwright/frame_locator_impl.rb
|
311
313
|
- lib/playwright/http_headers.rb
|
312
314
|
- lib/playwright/input_files.rb
|
313
315
|
- lib/playwright/javascript.rb
|
@@ -349,6 +351,7 @@ files:
|
|
349
351
|
- lib/playwright_api/element_handle.rb
|
350
352
|
- lib/playwright_api/file_chooser.rb
|
351
353
|
- lib/playwright_api/frame.rb
|
354
|
+
- lib/playwright_api/frame_locator.rb
|
352
355
|
- lib/playwright_api/js_handle.rb
|
353
356
|
- lib/playwright_api/keyboard.rb
|
354
357
|
- lib/playwright_api/locator.rb
|
@@ -379,12 +382,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
379
382
|
version: '2.4'
|
380
383
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
381
384
|
requirements:
|
382
|
-
- - "
|
385
|
+
- - ">"
|
383
386
|
- !ruby/object:Gem::Version
|
384
|
-
version:
|
387
|
+
version: 1.3.1
|
385
388
|
requirements: []
|
386
389
|
rubygems_version: 3.2.22
|
387
390
|
signing_key:
|
388
391
|
specification_version: 4
|
389
|
-
summary: The Ruby binding of playwright driver 1.
|
392
|
+
summary: The Ruby binding of playwright driver 1.17.0
|
390
393
|
test_files: []
|