playwright-ruby-client 1.25.0 → 1.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/documentation/docs/api/api_request_context.md +93 -0
- data/documentation/docs/api/browser_context.md +3 -3
- data/documentation/docs/api/browser_type.md +8 -0
- data/documentation/docs/api/download.md +1 -1
- data/documentation/docs/api/element_handle.md +1 -1
- data/documentation/docs/api/file_chooser.md +1 -1
- data/documentation/docs/api/frame.md +103 -4
- data/documentation/docs/api/frame_locator.md +105 -5
- data/documentation/docs/api/locator.md +121 -6
- data/documentation/docs/api/page.md +119 -10
- data/documentation/docs/api/tracing.md +1 -1
- data/documentation/docs/article/guides/rails_integration_with_null_driver.md +59 -0
- data/documentation/docs/include/api_coverage.md +29 -0
- data/documentation/src/components/HomepageFeatures.js +1 -1
- data/lib/playwright/channel_owners/api_request_context.rb +23 -120
- data/lib/playwright/channel_owners/browser_context.rb +4 -5
- data/lib/playwright/channel_owners/dialog.rb +1 -1
- data/lib/playwright/channel_owners/frame.rb +4 -0
- data/lib/playwright/channel_owners/page.rb +7 -6
- data/lib/playwright/channel_owners/selectors.rb +4 -0
- data/lib/playwright/frame_locator_impl.rb +6 -2
- data/lib/playwright/locator_impl.rb +7 -31
- data/lib/playwright/locator_utils.rb +142 -0
- data/lib/playwright/route_handler.rb +2 -2
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright_api/api_request_context.rb +92 -7
- data/lib/playwright_api/browser_context.rb +3 -3
- data/lib/playwright_api/browser_type.rb +6 -0
- data/lib/playwright_api/download.rb +1 -1
- data/lib/playwright_api/element_handle.rb +1 -1
- data/lib/playwright_api/file_chooser.rb +1 -1
- data/lib/playwright_api/frame.rb +78 -4
- data/lib/playwright_api/frame_locator.rb +79 -4
- data/lib/playwright_api/locator.rb +94 -5
- data/lib/playwright_api/page.rb +93 -10
- data/lib/playwright_api/request.rb +4 -4
- data/lib/playwright_api/response.rb +4 -4
- data/lib/playwright_api/selectors.rb +11 -0
- data/lib/playwright_api/tracing.rb +1 -1
- data/lib/playwright_api/worker.rb +4 -4
- metadata +4 -3
@@ -276,6 +276,20 @@ def drag_and_drop(
|
|
276
276
|
trial: nil)
|
277
277
|
```
|
278
278
|
|
279
|
+
This method drags the source element to the target element. It will first move to the source element, perform a
|
280
|
+
`mousedown`, then move to the target element and perform a `mouseup`.
|
281
|
+
|
282
|
+
```ruby
|
283
|
+
page.drag_and_drop("#source", "#target")
|
284
|
+
# or specify exact positions relative to the top-left corners of the elements:
|
285
|
+
page.drag_and_drop(
|
286
|
+
"#source",
|
287
|
+
"#target",
|
288
|
+
sourcePosition: { x: 34, y: 7 },
|
289
|
+
targetPosition: { x: 10, y: 20 },
|
290
|
+
)
|
291
|
+
```
|
292
|
+
|
279
293
|
|
280
294
|
|
281
295
|
## emulate_media
|
@@ -592,7 +606,7 @@ that iframe. Following snippet locates element with text "Submit" in the iframe
|
|
592
606
|
id="my-frame">`:
|
593
607
|
|
594
608
|
```ruby
|
595
|
-
locator = page.frame_locator("#my-iframe").
|
609
|
+
locator = page.frame_locator("#my-iframe").get_by_text("Submit")
|
596
610
|
locator.click
|
597
611
|
```
|
598
612
|
|
@@ -614,6 +628,103 @@ def get_attribute(selector, name, strict: nil, timeout: nil)
|
|
614
628
|
|
615
629
|
Returns element attribute value.
|
616
630
|
|
631
|
+
## get_by_alt_text
|
632
|
+
|
633
|
+
```
|
634
|
+
def get_by_alt_text(text, exact: nil)
|
635
|
+
```
|
636
|
+
|
637
|
+
Allows locating elements by their alt text. For example, this method will find the image by alt text "Castle":
|
638
|
+
|
639
|
+
```html
|
640
|
+
<img alt='Castle'>
|
641
|
+
```
|
642
|
+
|
643
|
+
|
644
|
+
## get_by_label
|
645
|
+
|
646
|
+
```
|
647
|
+
def get_by_label(text, exact: nil)
|
648
|
+
```
|
649
|
+
|
650
|
+
Allows locating input elements by the text of the associated label. For example, this method will find the input by
|
651
|
+
label text Password in the following DOM:
|
652
|
+
|
653
|
+
```html
|
654
|
+
<label for="password-input">Password:</label>
|
655
|
+
<input id="password-input">
|
656
|
+
```
|
657
|
+
|
658
|
+
|
659
|
+
## get_by_placeholder
|
660
|
+
|
661
|
+
```
|
662
|
+
def get_by_placeholder(text, exact: nil)
|
663
|
+
```
|
664
|
+
|
665
|
+
Allows locating input elements by the placeholder text. For example, this method will find the input by placeholder
|
666
|
+
"Country":
|
667
|
+
|
668
|
+
```html
|
669
|
+
<input placeholder="Country">
|
670
|
+
```
|
671
|
+
|
672
|
+
|
673
|
+
## get_by_role
|
674
|
+
|
675
|
+
```
|
676
|
+
def get_by_role(
|
677
|
+
role,
|
678
|
+
checked: nil,
|
679
|
+
disabled: nil,
|
680
|
+
expanded: nil,
|
681
|
+
includeHidden: nil,
|
682
|
+
level: nil,
|
683
|
+
name: nil,
|
684
|
+
pressed: nil,
|
685
|
+
selected: nil)
|
686
|
+
```
|
687
|
+
|
688
|
+
Allows locating elements by their [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles),
|
689
|
+
[ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and
|
690
|
+
[accessible name](https://w3c.github.io/accname/#dfn-accessible-name). Note that role selector **does not replace**
|
691
|
+
accessibility audits and conformance tests, but rather gives early feedback about the ARIA guidelines.
|
692
|
+
|
693
|
+
Note that many html elements have an implicitly
|
694
|
+
[defined role](https://w3c.github.io/html-aam/#html-element-role-mappings) that is recognized by the role selector. You
|
695
|
+
can find all the [supported roles here](https://www.w3.org/TR/wai-aria-1.2/#role_definitions). ARIA guidelines **do not
|
696
|
+
recommend** duplicating implicit roles and attributes by setting `role` and/or `aria-*` attributes to default values.
|
697
|
+
|
698
|
+
## get_by_test_id
|
699
|
+
|
700
|
+
```
|
701
|
+
def get_by_test_id(testId)
|
702
|
+
```
|
703
|
+
|
704
|
+
Locate element by the test id. By default, the `data-testid` attribute is used as a test id. Use
|
705
|
+
[Selectors#set_test_id_attribute](./selectors#set_test_id_attribute) to configure a different test id attribute if necessary.
|
706
|
+
|
707
|
+
## get_by_text
|
708
|
+
|
709
|
+
```
|
710
|
+
def get_by_text(text, exact: nil)
|
711
|
+
```
|
712
|
+
|
713
|
+
Allows locating elements that contain given text.
|
714
|
+
|
715
|
+
## get_by_title
|
716
|
+
|
717
|
+
```
|
718
|
+
def get_by_title(text, exact: nil)
|
719
|
+
```
|
720
|
+
|
721
|
+
Allows locating elements by their title. For example, this method will find the button by its title "Submit":
|
722
|
+
|
723
|
+
```html
|
724
|
+
<button title='Place the order'>Order Now</button>
|
725
|
+
```
|
726
|
+
|
727
|
+
|
617
728
|
## go_back
|
618
729
|
|
619
730
|
```
|
@@ -780,14 +891,12 @@ considered not visible.
|
|
780
891
|
def locator(selector, has: nil, hasText: nil)
|
781
892
|
```
|
782
893
|
|
783
|
-
The method returns an element locator that can be used to perform actions on
|
784
|
-
element immediately before performing an action, so a series of actions on the same locator can in fact be performed
|
785
|
-
different DOM elements. That would happen if the DOM structure between those actions has changed.
|
894
|
+
The method returns an element locator that can be used to perform actions on this page / frame. Locator is resolved to
|
895
|
+
the element immediately before performing an action, so a series of actions on the same locator can in fact be performed
|
896
|
+
on different DOM elements. That would happen if the DOM structure between those actions has changed.
|
786
897
|
|
787
898
|
[Learn more about locators](https://playwright.dev/python/docs/locators).
|
788
899
|
|
789
|
-
Shortcut for main frame's [Frame#locator](./frame#locator).
|
790
|
-
|
791
900
|
## main_frame
|
792
901
|
|
793
902
|
```
|
@@ -1364,7 +1473,7 @@ value. Will throw an error if the page is closed before the event is fired. Retu
|
|
1364
1473
|
|
1365
1474
|
```ruby
|
1366
1475
|
frame = page.expect_event("framenavigated") do
|
1367
|
-
page.
|
1476
|
+
page.get_by_role("button")
|
1368
1477
|
end
|
1369
1478
|
```
|
1370
1479
|
|
@@ -1415,13 +1524,13 @@ This resolves when the page reaches a required load state, `load` by default. Th
|
|
1415
1524
|
when this method is called. If current document has already reached the required state, resolves immediately.
|
1416
1525
|
|
1417
1526
|
```ruby
|
1418
|
-
page.
|
1527
|
+
page.get_by_role("button").click # click triggers navigation.
|
1419
1528
|
page.wait_for_load_state # the promise resolves after "load" event.
|
1420
1529
|
```
|
1421
1530
|
|
1422
1531
|
```ruby
|
1423
1532
|
popup = page.expect_popup do
|
1424
|
-
page.
|
1533
|
+
page.get_by_role("button").click # click triggers a popup.
|
1425
1534
|
end
|
1426
1535
|
|
1427
1536
|
# Following resolves after "domcontentloaded" event.
|
@@ -1541,7 +1650,7 @@ Returns when element specified by selector satisfies `state` option. Returns `nu
|
|
1541
1650
|
`detached`.
|
1542
1651
|
|
1543
1652
|
> NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator](./locator) objects and
|
1544
|
-
web-first assertions
|
1653
|
+
web-first assertions makes the code wait-for-selector-free.
|
1545
1654
|
|
1546
1655
|
Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
|
1547
1656
|
the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
|
@@ -58,7 +58,7 @@ page = context.new_page
|
|
58
58
|
page.goto("https://playwright.dev")
|
59
59
|
|
60
60
|
context.tracing.start_chunk
|
61
|
-
page.
|
61
|
+
page.get_by_text("Get Started").click
|
62
62
|
# Everything between start_chunk and stop_chunk will be recorded in the trace.
|
63
63
|
context.tracing.stop_chunk(path: "trace1.zip")
|
64
64
|
|
@@ -84,3 +84,62 @@ describe 'example', driver: :null do
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
```
|
87
|
+
|
88
|
+
## Minitest Usage
|
89
|
+
|
90
|
+
We can do something similar with the default Rails setup using Minitest. Here's the same example written with Minitest:
|
91
|
+
|
92
|
+
```rb
|
93
|
+
# test/application_system_test_case.rb
|
94
|
+
|
95
|
+
require 'playwright'
|
96
|
+
|
97
|
+
class CapybaraNullDriver < Capybara::Driver::Base
|
98
|
+
def needs_server?
|
99
|
+
true
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
Capybara.register_driver(:null) { CapybaraNullDriver.new }
|
104
|
+
|
105
|
+
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
106
|
+
driven_by :null
|
107
|
+
|
108
|
+
def self.playwright
|
109
|
+
@playwright ||= Playwright.create(playwright_cli_executable_path: Rails.root.join("node_modules/.bin/playwright"))
|
110
|
+
end
|
111
|
+
|
112
|
+
def before_setup
|
113
|
+
super
|
114
|
+
base_url = Capybara.current_session.server.base_url
|
115
|
+
@playwright_browser = self.class.playwright.playwright.chromium.launch(headless: false)
|
116
|
+
@playwright_page = @playwright_browser.new_page(baseURL: base_url)
|
117
|
+
end
|
118
|
+
|
119
|
+
def after_teardown
|
120
|
+
super
|
121
|
+
@browser.close
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
And here is the same test:
|
127
|
+
|
128
|
+
```rb
|
129
|
+
require "application_system_test_case"
|
130
|
+
|
131
|
+
class ExampleTest < ApplicationSystemTestCase
|
132
|
+
def setup
|
133
|
+
@user = User.create!
|
134
|
+
@page = @playwright_page
|
135
|
+
end
|
136
|
+
|
137
|
+
test 'can browse' do
|
138
|
+
@page.goto("/tests/#{user.id}")
|
139
|
+
@page.wait_for_selector('input').type('hoge')
|
140
|
+
@page.keyboard.press('Enter')
|
141
|
+
|
142
|
+
assert @page.text_content('#content').include?('hoge')
|
143
|
+
end
|
144
|
+
end
|
145
|
+
```
|
@@ -159,6 +159,13 @@
|
|
159
159
|
* frame_element
|
160
160
|
* frame_locator
|
161
161
|
* get_attribute
|
162
|
+
* get_by_alt_text
|
163
|
+
* get_by_label
|
164
|
+
* get_by_placeholder
|
165
|
+
* get_by_role
|
166
|
+
* get_by_test_id
|
167
|
+
* get_by_text
|
168
|
+
* get_by_title
|
162
169
|
* goto
|
163
170
|
* hover
|
164
171
|
* inner_html
|
@@ -204,6 +211,7 @@
|
|
204
211
|
## Selectors
|
205
212
|
|
206
213
|
* register
|
214
|
+
* ~~set_test_id_attribute~~
|
207
215
|
|
208
216
|
## ConsoleMessage
|
209
217
|
|
@@ -258,6 +266,13 @@
|
|
258
266
|
* frame_locator
|
259
267
|
* frames
|
260
268
|
* get_attribute
|
269
|
+
* get_by_alt_text
|
270
|
+
* get_by_label
|
271
|
+
* get_by_placeholder
|
272
|
+
* get_by_role
|
273
|
+
* get_by_test_id
|
274
|
+
* get_by_text
|
275
|
+
* get_by_title
|
261
276
|
* go_back
|
262
277
|
* go_forward
|
263
278
|
* goto
|
@@ -423,6 +438,13 @@
|
|
423
438
|
* focus
|
424
439
|
* frame_locator
|
425
440
|
* get_attribute
|
441
|
+
* get_by_alt_text
|
442
|
+
* get_by_label
|
443
|
+
* get_by_placeholder
|
444
|
+
* get_by_role
|
445
|
+
* get_by_test_id
|
446
|
+
* get_by_text
|
447
|
+
* get_by_title
|
426
448
|
* highlight
|
427
449
|
* hover
|
428
450
|
* inner_html
|
@@ -455,6 +477,13 @@
|
|
455
477
|
|
456
478
|
* first
|
457
479
|
* frame_locator
|
480
|
+
* get_by_alt_text
|
481
|
+
* get_by_label
|
482
|
+
* get_by_placeholder
|
483
|
+
* get_by_role
|
484
|
+
* get_by_test_id
|
485
|
+
* get_by_text
|
486
|
+
* get_by_title
|
458
487
|
* last
|
459
488
|
* locator
|
460
489
|
* nth
|
@@ -10,136 +10,34 @@ module Playwright
|
|
10
10
|
@channel.send_message_to_server('dispose')
|
11
11
|
end
|
12
12
|
|
13
|
-
def delete(
|
14
|
-
|
15
|
-
|
16
|
-
failOnStatusCode: nil,
|
17
|
-
form: nil,
|
18
|
-
headers: nil,
|
19
|
-
ignoreHTTPSErrors: nil,
|
20
|
-
multipart: nil,
|
21
|
-
params: nil,
|
22
|
-
timeout: nil)
|
23
|
-
fetch(
|
24
|
-
url,
|
25
|
-
method: 'DELETE',
|
26
|
-
data: data,
|
27
|
-
failOnStatusCode: failOnStatusCode,
|
28
|
-
form: form,
|
29
|
-
headers: headers,
|
30
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
31
|
-
multipart: multipart,
|
32
|
-
params: params,
|
33
|
-
timeout: timeout,
|
34
|
-
)
|
13
|
+
def delete(url, **options)
|
14
|
+
fetch_options = options.merge(method: 'DELETE')
|
15
|
+
fetch(url, **fetch_options)
|
35
16
|
end
|
36
17
|
|
37
|
-
def head(
|
38
|
-
|
39
|
-
|
40
|
-
headers: nil,
|
41
|
-
ignoreHTTPSErrors: nil,
|
42
|
-
params: nil,
|
43
|
-
timeout: nil)
|
44
|
-
fetch(
|
45
|
-
url,
|
46
|
-
method: 'HEAD',
|
47
|
-
failOnStatusCode: failOnStatusCode,
|
48
|
-
headers: headers,
|
49
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
50
|
-
params: params,
|
51
|
-
timeout: timeout,
|
52
|
-
)
|
18
|
+
def head(url, **options)
|
19
|
+
fetch_options = options.merge(method: 'HEAD')
|
20
|
+
fetch(url, **fetch_options)
|
53
21
|
end
|
54
22
|
|
55
|
-
def get(
|
56
|
-
|
57
|
-
|
58
|
-
headers: nil,
|
59
|
-
ignoreHTTPSErrors: nil,
|
60
|
-
params: nil,
|
61
|
-
timeout: nil)
|
62
|
-
fetch(
|
63
|
-
url,
|
64
|
-
method: 'GET',
|
65
|
-
failOnStatusCode: failOnStatusCode,
|
66
|
-
headers: headers,
|
67
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
68
|
-
params: params,
|
69
|
-
timeout: timeout,
|
70
|
-
)
|
23
|
+
def get(url, **options)
|
24
|
+
fetch_options = options.merge(method: 'GET')
|
25
|
+
fetch(url, **fetch_options)
|
71
26
|
end
|
72
27
|
|
73
|
-
def patch(
|
74
|
-
|
75
|
-
|
76
|
-
failOnStatusCode: nil,
|
77
|
-
form: nil,
|
78
|
-
headers: nil,
|
79
|
-
ignoreHTTPSErrors: nil,
|
80
|
-
multipart: nil,
|
81
|
-
params: nil,
|
82
|
-
timeout: nil)
|
83
|
-
fetch(
|
84
|
-
url,
|
85
|
-
method: 'PATCH',
|
86
|
-
data: data,
|
87
|
-
failOnStatusCode: failOnStatusCode,
|
88
|
-
form: form,
|
89
|
-
headers: headers,
|
90
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
91
|
-
multipart: multipart,
|
92
|
-
params: params,
|
93
|
-
timeout: timeout,
|
94
|
-
)
|
28
|
+
def patch(url, **options)
|
29
|
+
fetch_options = options.merge(method: 'PATCH')
|
30
|
+
fetch(url, **fetch_options)
|
95
31
|
end
|
96
32
|
|
97
|
-
def put(
|
98
|
-
|
99
|
-
|
100
|
-
failOnStatusCode: nil,
|
101
|
-
form: nil,
|
102
|
-
headers: nil,
|
103
|
-
ignoreHTTPSErrors: nil,
|
104
|
-
multipart: nil,
|
105
|
-
params: nil,
|
106
|
-
timeout: nil)
|
107
|
-
fetch(
|
108
|
-
url,
|
109
|
-
method: 'PUT',
|
110
|
-
data: data,
|
111
|
-
failOnStatusCode: failOnStatusCode,
|
112
|
-
form: form,
|
113
|
-
headers: headers,
|
114
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
115
|
-
multipart: multipart,
|
116
|
-
params: params,
|
117
|
-
timeout: timeout,
|
118
|
-
)
|
33
|
+
def put(url, **options)
|
34
|
+
fetch_options = options.merge(method: 'PUT')
|
35
|
+
fetch(url, **fetch_options)
|
119
36
|
end
|
120
37
|
|
121
|
-
def post(
|
122
|
-
|
123
|
-
|
124
|
-
failOnStatusCode: nil,
|
125
|
-
form: nil,
|
126
|
-
headers: nil,
|
127
|
-
ignoreHTTPSErrors: nil,
|
128
|
-
multipart: nil,
|
129
|
-
params: nil,
|
130
|
-
timeout: nil)
|
131
|
-
fetch(
|
132
|
-
url,
|
133
|
-
method: 'POST',
|
134
|
-
data: data,
|
135
|
-
failOnStatusCode: failOnStatusCode,
|
136
|
-
form: form,
|
137
|
-
headers: headers,
|
138
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
139
|
-
multipart: multipart,
|
140
|
-
params: params,
|
141
|
-
timeout: timeout,
|
142
|
-
)
|
38
|
+
def post(url, **options)
|
39
|
+
fetch_options = options.merge(method: 'POST')
|
40
|
+
fetch(url, **fetch_options)
|
143
41
|
end
|
144
42
|
|
145
43
|
def fetch(
|
@@ -149,6 +47,7 @@ module Playwright
|
|
149
47
|
form: nil,
|
150
48
|
headers: nil,
|
151
49
|
ignoreHTTPSErrors: nil,
|
50
|
+
maxRedirects: nil,
|
152
51
|
method: nil,
|
153
52
|
multipart: nil,
|
154
53
|
params: nil,
|
@@ -160,6 +59,9 @@ module Playwright
|
|
160
59
|
if [data, form, multipart].compact.count > 1
|
161
60
|
raise ArgumentError.new("Only one of 'data', 'form' or 'multipart' can be specified")
|
162
61
|
end
|
62
|
+
if maxRedirects && maxRedirects < 0
|
63
|
+
raise ArgumentError.new("'maxRedirects' should be greater than or equal to '0'")
|
64
|
+
end
|
163
65
|
|
164
66
|
request = urlOrRequest.is_a?(ChannelOwners::Request) ? urlOrRequest : nil
|
165
67
|
headers_obj = headers || request&.headers
|
@@ -212,6 +114,7 @@ module Playwright
|
|
212
114
|
fetch_params[:timeout] = timeout
|
213
115
|
fetch_params[:failOnStatusCode] = failOnStatusCode
|
214
116
|
fetch_params[:ignoreHTTPSErrors] = ignoreHTTPSErrors
|
117
|
+
fetch_params[:maxRedirects] = maxRedirects
|
215
118
|
fetch_params.compact!
|
216
119
|
response = @channel.send_message_to_server('fetch', fetch_params)
|
217
120
|
|
@@ -26,7 +26,7 @@ module Playwright
|
|
26
26
|
@channel.on('page', ->(params) { on_page(ChannelOwners::Page.from(params['page']) )})
|
27
27
|
@channel.on('route', ->(params) {
|
28
28
|
Concurrent::Promises.future {
|
29
|
-
on_route(ChannelOwners::Route.from(params['route'])
|
29
|
+
on_route(ChannelOwners::Route.from(params['route']))
|
30
30
|
}.rescue do |err|
|
31
31
|
puts err, err.backtrace
|
32
32
|
end
|
@@ -83,22 +83,21 @@ module Playwright
|
|
83
83
|
emit(Events::BrowserContext::BackgroundPage, page)
|
84
84
|
end
|
85
85
|
|
86
|
-
private def on_route(route
|
86
|
+
private def on_route(route)
|
87
87
|
# It is not desired to use PlaywrightApi.wrap directly.
|
88
88
|
# However it is a little difficult to define wrapper for `handler` parameter in generate_api.
|
89
89
|
# Just a workaround...
|
90
90
|
wrapped_route = PlaywrightApi.wrap(route)
|
91
|
-
wrapped_request = PlaywrightApi.wrap(request)
|
92
91
|
|
93
92
|
handled = @routes.any? do |handler_entry|
|
94
|
-
next false unless handler_entry.match?(request.url)
|
93
|
+
next false unless handler_entry.match?(route.request.url)
|
95
94
|
|
96
95
|
promise = Concurrent::Promises.resolvable_future
|
97
96
|
route.send(:set_handling_future, promise)
|
98
97
|
|
99
98
|
promise_handled = Concurrent::Promises.zip(
|
100
99
|
promise,
|
101
|
-
handler_entry.async_handle(wrapped_route
|
100
|
+
handler_entry.async_handle(wrapped_route)
|
102
101
|
).value!.first
|
103
102
|
|
104
103
|
promise_handled
|
@@ -1,6 +1,10 @@
|
|
1
|
+
require_relative '../locator_utils'
|
2
|
+
|
1
3
|
module Playwright
|
2
4
|
# @ref https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_frame.py
|
3
5
|
define_channel_owner :Frame do
|
6
|
+
include LocatorUtils
|
7
|
+
|
4
8
|
private def after_initialize
|
5
9
|
if @initializer['parentFrame']
|
6
10
|
@parent_frame = ChannelOwners::Frame.from(@initializer['parentFrame'])
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'base64'
|
2
|
+
require_relative '../locator_utils'
|
2
3
|
|
3
4
|
module Playwright
|
4
5
|
# @ref https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_page.py
|
5
6
|
define_channel_owner :Page do
|
6
7
|
include Utils::Errors::SafeCloseError
|
8
|
+
include LocatorUtils
|
7
9
|
attr_writer :owned_context
|
8
10
|
|
9
11
|
private def after_initialize
|
@@ -58,7 +60,7 @@ module Playwright
|
|
58
60
|
})
|
59
61
|
@channel.on('route', ->(params) {
|
60
62
|
Concurrent::Promises.future {
|
61
|
-
on_route(ChannelOwners::Route.from(params['route'])
|
63
|
+
on_route(ChannelOwners::Route.from(params['route']))
|
62
64
|
}.rescue do |err|
|
63
65
|
puts err, err.backtrace
|
64
66
|
end
|
@@ -93,22 +95,21 @@ module Playwright
|
|
93
95
|
emit(Events::Page::FrameDetached, frame)
|
94
96
|
end
|
95
97
|
|
96
|
-
private def on_route(route
|
98
|
+
private def on_route(route)
|
97
99
|
# It is not desired to use PlaywrightApi.wrap directly.
|
98
100
|
# However it is a little difficult to define wrapper for `handler` parameter in generate_api.
|
99
101
|
# Just a workaround...
|
100
102
|
wrapped_route = PlaywrightApi.wrap(route)
|
101
|
-
wrapped_request = PlaywrightApi.wrap(request)
|
102
103
|
|
103
104
|
handled = @routes.any? do |handler_entry|
|
104
|
-
next false unless handler_entry.match?(request.url)
|
105
|
+
next false unless handler_entry.match?(route.request.url)
|
105
106
|
|
106
107
|
promise = Concurrent::Promises.resolvable_future
|
107
108
|
route.send(:set_handling_future, promise)
|
108
109
|
|
109
110
|
promise_handled = Concurrent::Promises.zip(
|
110
111
|
promise,
|
111
|
-
handler_entry.async_handle(wrapped_route
|
112
|
+
handler_entry.async_handle(wrapped_route)
|
112
113
|
).value!.first
|
113
114
|
|
114
115
|
promise_handled
|
@@ -120,7 +121,7 @@ module Playwright
|
|
120
121
|
end
|
121
122
|
|
122
123
|
unless handled
|
123
|
-
@browser_context.send(:on_route, route
|
124
|
+
@browser_context.send(:on_route, route)
|
124
125
|
end
|
125
126
|
end
|
126
127
|
|
@@ -1,5 +1,9 @@
|
|
1
|
+
require_relative './locator_utils'
|
2
|
+
|
1
3
|
module Playwright
|
2
4
|
define_api_implementation :FrameLocatorImpl do
|
5
|
+
include LocatorUtils
|
6
|
+
|
3
7
|
def initialize(frame:, timeout_settings:, frame_selector:)
|
4
8
|
@frame = frame
|
5
9
|
@timeout_settings = timeout_settings
|
@@ -10,7 +14,7 @@ module Playwright
|
|
10
14
|
LocatorImpl.new(
|
11
15
|
frame: @frame,
|
12
16
|
timeout_settings: @timeout_settings,
|
13
|
-
selector: "#{@frame_selector} >> control=enter-frame >> #{selector}",
|
17
|
+
selector: "#{@frame_selector} >> internal:control=enter-frame >> #{selector}",
|
14
18
|
hasText: hasText,
|
15
19
|
has: has,
|
16
20
|
)
|
@@ -20,7 +24,7 @@ module Playwright
|
|
20
24
|
FrameLocatorImpl.new(
|
21
25
|
frame: @frame,
|
22
26
|
timeout_settings: @timeout_settings,
|
23
|
-
frame_selector: "#{@frame_selector} >> control=enter-frame >> #{selector}",
|
27
|
+
frame_selector: "#{@frame_selector} >> internal:control=enter-frame >> #{selector}",
|
24
28
|
)
|
25
29
|
end
|
26
30
|
|