playwright-ruby-client 1.22.0 → 1.23.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/browser.md +16 -0
- data/documentation/docs/api/browser_context.md +15 -2
- data/documentation/docs/api/browser_type.md +4 -0
- data/documentation/docs/api/element_handle.md +0 -5
- data/documentation/docs/api/experimental/android_device.md +4 -0
- data/documentation/docs/api/locator.md +13 -6
- data/documentation/docs/api/page.md +14 -1
- data/documentation/docs/api/request.md +3 -1
- data/documentation/docs/api/response.md +12 -1
- data/documentation/docs/api/route.md +65 -0
- data/documentation/docs/include/api_coverage.md +5 -3
- data/lib/playwright/channel.rb +1 -3
- data/lib/playwright/channel_owners/browser.rb +13 -0
- data/lib/playwright/channel_owners/browser_context.rb +81 -13
- data/lib/playwright/channel_owners/browser_type.rb +4 -0
- data/lib/playwright/channel_owners/frame.rb +16 -2
- data/lib/playwright/channel_owners/local_utils.rb +29 -0
- data/lib/playwright/channel_owners/page.rb +43 -15
- data/lib/playwright/channel_owners/request.rb +31 -6
- data/lib/playwright/channel_owners/response.rb +6 -0
- data/lib/playwright/channel_owners/route.rb +104 -45
- data/lib/playwright/connection.rb +6 -1
- data/lib/playwright/har_router.rb +82 -0
- data/lib/playwright/http_headers.rb +1 -1
- data/lib/playwright/javascript/regex.rb +23 -0
- data/lib/playwright/javascript/value_serializer.rb +3 -4
- data/lib/playwright/javascript.rb +1 -0
- data/lib/playwright/locator_impl.rb +3 -5
- data/lib/playwright/route_handler.rb +2 -6
- data/lib/playwright/utils.rb +31 -6
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright.rb +2 -0
- data/lib/playwright_api/android_device.rb +5 -1
- data/lib/playwright_api/browser.rb +15 -2
- data/lib/playwright_api/browser_context.rb +16 -6
- data/lib/playwright_api/browser_type.rb +5 -1
- data/lib/playwright_api/element_handle.rb +0 -11
- data/lib/playwright_api/locator.rb +11 -12
- data/lib/playwright_api/page.rb +16 -6
- data/lib/playwright_api/request.rb +8 -1
- data/lib/playwright_api/response.rb +14 -1
- data/lib/playwright_api/route.rb +61 -2
- data/lib/playwright_api/worker.rb +4 -4
- metadata +5 -4
- data/lib/playwright_api/local_utils.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d8cc3ad6fb1bd9c8a42f249085e91f92dbed26ebcbbd310559810299b60ea31
|
4
|
+
data.tar.gz: 6fb3450345d6f7bcbcbb19e3206244739f8aecf0813a94216e58df03674fb8e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4e12e990b3a9df4532154ad62d6064c343664b75d8f29d088e6c28c00b5f22608d3de49c3568af2e2ac8689e9d9769e478e36571e7921d928c21eb3a18d9a56
|
7
|
+
data.tar.gz: 49f939af824f3affd9bbb011eb389238d5484a3f320fed6ad170bfb8c011ac351f6dba239f4e685d6b9058f4b72461fd5d1b5aee98835e34948eeef90b535dbc
|
@@ -21,6 +21,14 @@ end
|
|
21
21
|
|
22
22
|
|
23
23
|
|
24
|
+
## browser_type
|
25
|
+
|
26
|
+
```
|
27
|
+
def browser_type
|
28
|
+
```
|
29
|
+
|
30
|
+
Get the browser type (chromium, firefox or webkit) that the browser belongs to.
|
31
|
+
|
24
32
|
## close
|
25
33
|
|
26
34
|
```
|
@@ -93,12 +101,16 @@ def new_context(
|
|
93
101
|
offline: nil,
|
94
102
|
permissions: nil,
|
95
103
|
proxy: nil,
|
104
|
+
record_har_content: nil,
|
105
|
+
record_har_mode: nil,
|
96
106
|
record_har_omit_content: nil,
|
97
107
|
record_har_path: nil,
|
108
|
+
record_har_url_filter: nil,
|
98
109
|
record_video_dir: nil,
|
99
110
|
record_video_size: nil,
|
100
111
|
reducedMotion: nil,
|
101
112
|
screen: nil,
|
113
|
+
serviceWorkers: nil,
|
102
114
|
storageState: nil,
|
103
115
|
strictSelectors: nil,
|
104
116
|
timezoneId: nil,
|
@@ -144,12 +156,16 @@ def new_page(
|
|
144
156
|
offline: nil,
|
145
157
|
permissions: nil,
|
146
158
|
proxy: nil,
|
159
|
+
record_har_content: nil,
|
160
|
+
record_har_mode: nil,
|
147
161
|
record_har_omit_content: nil,
|
148
162
|
record_har_path: nil,
|
163
|
+
record_har_url_filter: nil,
|
149
164
|
record_video_dir: nil,
|
150
165
|
record_video_size: nil,
|
151
166
|
reducedMotion: nil,
|
152
167
|
screen: nil,
|
168
|
+
serviceWorkers: nil,
|
153
169
|
storageState: nil,
|
154
170
|
strictSelectors: nil,
|
155
171
|
timezoneId: nil,
|
@@ -271,9 +271,9 @@ def route(url, handler, times: nil)
|
|
271
271
|
Routing provides the capability to modify network requests that are made by any page in the browser context. Once route
|
272
272
|
is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted.
|
273
273
|
|
274
|
-
> NOTE: [
|
274
|
+
> NOTE: [BrowserContext#route](./browser_context#route) will not intercept requests intercepted by Service Worker. See
|
275
275
|
[this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend disabling Service Workers when using
|
276
|
-
request interception
|
276
|
+
request interception by setting `Browser.newContext.serviceWorkers` to `'block'`.
|
277
277
|
|
278
278
|
An example of a naive handler that aborts all image requests:
|
279
279
|
|
@@ -315,6 +315,19 @@ To remove a route with its handler you can use [BrowserContext#unroute](./browse
|
|
315
315
|
|
316
316
|
> NOTE: Enabling routing disables http cache.
|
317
317
|
|
318
|
+
## route_from_har
|
319
|
+
|
320
|
+
```
|
321
|
+
def route_from_har(har, notFound: nil, update: nil, url: nil)
|
322
|
+
```
|
323
|
+
|
324
|
+
If specified the network requests that are made in the context will be served from the HAR file. Read more about
|
325
|
+
[Replaying from HAR](https://playwright.dev/python/docs/network).
|
326
|
+
|
327
|
+
Playwright will not serve requests intercepted by Service Worker from the HAR file. See
|
328
|
+
[this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend disabling Service Workers when using
|
329
|
+
request interception by setting `Browser.newContext.serviceWorkers` to `'block'`.
|
330
|
+
|
318
331
|
## service_workers
|
319
332
|
|
320
333
|
```
|
@@ -131,12 +131,16 @@ def launch_persistent_context(
|
|
131
131
|
offline: nil,
|
132
132
|
permissions: nil,
|
133
133
|
proxy: nil,
|
134
|
+
record_har_content: nil,
|
135
|
+
record_har_mode: nil,
|
134
136
|
record_har_omit_content: nil,
|
135
137
|
record_har_path: nil,
|
138
|
+
record_har_url_filter: nil,
|
136
139
|
record_video_dir: nil,
|
137
140
|
record_video_size: nil,
|
138
141
|
reducedMotion: nil,
|
139
142
|
screen: nil,
|
143
|
+
serviceWorkers: nil,
|
140
144
|
slowMo: nil,
|
141
145
|
strictSelectors: nil,
|
142
146
|
timeout: nil,
|
@@ -504,11 +504,6 @@ element_handle.select_option(label: "blue")
|
|
504
504
|
element_handle.select_option(value: ["red", "green", "blue"])
|
505
505
|
```
|
506
506
|
|
507
|
-
```ruby
|
508
|
-
# multiple selection for blue, red and second option
|
509
|
-
element_handle.select_option(value: "blue", index: 2, label: "red")
|
510
|
-
```
|
511
|
-
|
512
507
|
|
513
508
|
|
514
509
|
## select_text
|
@@ -45,12 +45,16 @@ def launch_browser(
|
|
45
45
|
noViewport: nil,
|
46
46
|
offline: nil,
|
47
47
|
permissions: nil,
|
48
|
+
record_har_content: nil,
|
49
|
+
record_har_mode: nil,
|
48
50
|
record_har_omit_content: nil,
|
49
51
|
record_har_path: nil,
|
52
|
+
record_har_url_filter: nil,
|
50
53
|
record_video_dir: nil,
|
51
54
|
record_video_size: nil,
|
52
55
|
reducedMotion: nil,
|
53
56
|
screen: nil,
|
57
|
+
serviceWorkers: nil,
|
54
58
|
strictSelectors: nil,
|
55
59
|
timezoneId: nil,
|
56
60
|
userAgent: nil,
|
@@ -291,7 +291,19 @@ To send fine-grained keyboard events, use [Locator#type](./locator#type).
|
|
291
291
|
def filter(has: nil, hasText: nil)
|
292
292
|
```
|
293
293
|
|
294
|
-
This method narrows existing locator according to the options, for example filters by text.
|
294
|
+
This method narrows existing locator according to the options, for example filters by text. It can be chained to filter
|
295
|
+
multiple times.
|
296
|
+
|
297
|
+
```ruby
|
298
|
+
row_locator = page.locator("tr")
|
299
|
+
# ...
|
300
|
+
row_locator.
|
301
|
+
filter(has_text="text in column 1").
|
302
|
+
filter(has=page.locator("tr", has_text="column 2 button")).
|
303
|
+
screenshot
|
304
|
+
```
|
305
|
+
|
306
|
+
|
295
307
|
|
296
308
|
## first
|
297
309
|
|
@@ -564,11 +576,6 @@ element.select_option(label: "blue")
|
|
564
576
|
element.select_option(value: ["red", "green", "blue"])
|
565
577
|
```
|
566
578
|
|
567
|
-
```ruby
|
568
|
-
# multiple selection for blue, red and second option
|
569
|
-
element.select_option(value: "blue", index: 2, label: "red")
|
570
|
-
```
|
571
|
-
|
572
579
|
|
573
580
|
|
574
581
|
## select_text
|
@@ -975,7 +975,7 @@ Once routing is enabled, every request matching the url pattern will stall unles
|
|
975
975
|
> NOTE: The handler will only be called for the first url if the response is a redirect.
|
976
976
|
> NOTE: [Page#route](./page#route) will not intercept requests intercepted by Service Worker. See
|
977
977
|
[this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend disabling Service Workers when using
|
978
|
-
request interception
|
978
|
+
request interception by setting `Browser.newContext.serviceWorkers` to `'block'`.
|
979
979
|
|
980
980
|
An example of a naive handler that aborts all image requests:
|
981
981
|
|
@@ -1013,6 +1013,19 @@ To remove a route with its handler you can use [Page#unroute](./page#unroute).
|
|
1013
1013
|
|
1014
1014
|
> NOTE: Enabling routing disables http cache.
|
1015
1015
|
|
1016
|
+
## route_from_har
|
1017
|
+
|
1018
|
+
```
|
1019
|
+
def route_from_har(har, notFound: nil, update: nil, url: nil)
|
1020
|
+
```
|
1021
|
+
|
1022
|
+
If specified the network requests that are made in the page will be served from the HAR file. Read more about
|
1023
|
+
[Replaying from HAR](https://playwright.dev/python/docs/network).
|
1024
|
+
|
1025
|
+
Playwright will not serve requests intercepted by Service Worker from the HAR file. See
|
1026
|
+
[this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend disabling Service Workers when using
|
1027
|
+
request interception by setting `Browser.newContext.serviceWorkers` to `'block'`.
|
1028
|
+
|
1016
1029
|
## screenshot
|
1017
1030
|
|
1018
1031
|
```
|
@@ -56,7 +56,9 @@ Returns the [Frame](./frame) that initiated this request.
|
|
56
56
|
def headers
|
57
57
|
```
|
58
58
|
|
59
|
-
|
59
|
+
An object with the request HTTP headers. The header names are lower-cased. Note that this method does not return
|
60
|
+
security-related headers, including cookie-related ones. You can use [Request#all_headers](./request#all_headers) for complete list of
|
61
|
+
headers that include `cookie` information.
|
60
62
|
|
61
63
|
## headers_array
|
62
64
|
|
@@ -38,13 +38,24 @@ def frame
|
|
38
38
|
|
39
39
|
Returns the [Frame](./frame) that initiated this response.
|
40
40
|
|
41
|
+
## from_service_worker
|
42
|
+
|
43
|
+
```
|
44
|
+
def from_service_worker
|
45
|
+
```
|
46
|
+
|
47
|
+
Indicates whether this Response was fullfilled by a Service Worker's Fetch Handler (i.e. via
|
48
|
+
[FetchEvent.respondWith](https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent/respondWith)).
|
49
|
+
|
41
50
|
## headers
|
42
51
|
|
43
52
|
```
|
44
53
|
def headers
|
45
54
|
```
|
46
55
|
|
47
|
-
|
56
|
+
An object with the response HTTP headers. The header names are lower-cased. Note that this method does not return
|
57
|
+
security-related headers, including cookie-related ones. You can use [Response#all_headers](./response#all_headers) for complete list
|
58
|
+
of headers that include `cookie` information.
|
48
59
|
|
49
60
|
## headers_array
|
50
61
|
|
@@ -31,6 +31,7 @@ def handle(route, request)
|
|
31
31
|
headers = request.headers
|
32
32
|
headers['foo'] = 'bar' # set "foo" header
|
33
33
|
headers['user-agent'] = 'Unknown Browser' # modify user-agent
|
34
|
+
headers.delete('bar') # remove "bar" header
|
34
35
|
|
35
36
|
route.continue(headers: headers)
|
36
37
|
end
|
@@ -39,6 +40,70 @@ page.route("**/*", method(:handle))
|
|
39
40
|
|
40
41
|
|
41
42
|
|
43
|
+
## fallback
|
44
|
+
|
45
|
+
```
|
46
|
+
def fallback(headers: nil, method: nil, postData: nil, url: nil)
|
47
|
+
```
|
48
|
+
|
49
|
+
When several routes match the given pattern, they run in the order opposite to their registration. That way the last
|
50
|
+
registered route can always override all the previos ones. In the example below, request will be handled by the
|
51
|
+
bottom-most handler first, then it'll fall back to the previous one and in the end will be aborted by the first
|
52
|
+
registered route.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
page.route("**/*", -> (route,_) { route.abort }) # Runs last.
|
56
|
+
page.route("**/*", -> (route,_) { route.fallback }) # Runs second.
|
57
|
+
page.route("**/*", -> (route,_) { route.fallback }) # Runs first.
|
58
|
+
```
|
59
|
+
|
60
|
+
Registering multiple routes is useful when you want separate handlers to handle different kinds of requests, for example
|
61
|
+
API calls vs page resources or GET requests vs POST requests as in the example below.
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
# Handle GET requests.
|
65
|
+
def handle_post(route, request)
|
66
|
+
if request.method != "GET"
|
67
|
+
route.fallback
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
71
|
+
# Handling GET only.
|
72
|
+
# ...
|
73
|
+
end
|
74
|
+
|
75
|
+
# Handle POST requests.
|
76
|
+
def handle_post(route)
|
77
|
+
if request.method != "POST"
|
78
|
+
route.fallback
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
# Handling POST only.
|
83
|
+
# ...
|
84
|
+
end
|
85
|
+
|
86
|
+
page.route("**/*", handle_get)
|
87
|
+
page.route("**/*", handle_post)
|
88
|
+
```
|
89
|
+
|
90
|
+
One can also modify request while falling back to the subsequent handler, that way intermediate route handler can modify
|
91
|
+
url, method, headers and postData of the request.
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
def handle(route, request)
|
95
|
+
# override headers
|
96
|
+
headers = request.headers
|
97
|
+
headers['foo'] = 'bar' # set "foo" header
|
98
|
+
headers['user-agent'] = 'Unknown Browser' # modify user-agent
|
99
|
+
headers.delete('bar') # remove "bar" header
|
100
|
+
|
101
|
+
route.fallback(headers: headers)
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
|
106
|
+
|
42
107
|
## fulfill
|
43
108
|
|
44
109
|
```
|
@@ -27,6 +27,7 @@
|
|
27
27
|
* body
|
28
28
|
* finished
|
29
29
|
* frame
|
30
|
+
* from_service_worker
|
30
31
|
* headers
|
31
32
|
* headers_array
|
32
33
|
* header_value
|
@@ -45,6 +46,7 @@
|
|
45
46
|
|
46
47
|
* abort
|
47
48
|
* continue
|
49
|
+
* fallback
|
48
50
|
* fulfill
|
49
51
|
* request
|
50
52
|
|
@@ -280,6 +282,7 @@
|
|
280
282
|
* query_selector_all
|
281
283
|
* reload
|
282
284
|
* route
|
285
|
+
* route_from_har
|
283
286
|
* screenshot
|
284
287
|
* select_option
|
285
288
|
* set_checked
|
@@ -339,6 +342,7 @@
|
|
339
342
|
* new_page
|
340
343
|
* pages
|
341
344
|
* route
|
345
|
+
* route_from_har
|
342
346
|
* service_workers
|
343
347
|
* set_default_navigation_timeout
|
344
348
|
* set_default_timeout
|
@@ -360,6 +364,7 @@
|
|
360
364
|
|
361
365
|
## Browser
|
362
366
|
|
367
|
+
* browser_type
|
363
368
|
* close
|
364
369
|
* contexts
|
365
370
|
* connected?
|
@@ -454,9 +459,6 @@
|
|
454
459
|
* locator
|
455
460
|
* nth
|
456
461
|
|
457
|
-
## LocalUtils
|
458
|
-
|
459
|
-
|
460
462
|
## APIResponse
|
461
463
|
|
462
464
|
* body
|
data/lib/playwright/channel.rb
CHANGED
@@ -37,13 +37,11 @@ module Playwright
|
|
37
37
|
|
38
38
|
# @param method [String]
|
39
39
|
# @param params [Hash]
|
40
|
-
# @returns
|
40
|
+
# @returns [Concurrent::Promises::Future]
|
41
41
|
def async_send_message_to_server(method, params = {})
|
42
42
|
with_logging do |metadata|
|
43
43
|
@connection.async_send_message_to_server(@guid, method, params, metadata: metadata)
|
44
44
|
end
|
45
|
-
|
46
|
-
nil
|
47
45
|
end
|
48
46
|
|
49
47
|
private def with_logging(&block)
|
@@ -5,6 +5,7 @@ module Playwright
|
|
5
5
|
include Utils::PrepareBrowserContextOptions
|
6
6
|
|
7
7
|
private def after_initialize
|
8
|
+
@browser_type = @parent
|
8
9
|
@connected = true
|
9
10
|
@closed_or_closing = false
|
10
11
|
@should_close_connection_on_close = false
|
@@ -17,6 +18,10 @@ module Playwright
|
|
17
18
|
@contexts.to_a
|
18
19
|
end
|
19
20
|
|
21
|
+
def browser_type
|
22
|
+
@browser_type
|
23
|
+
end
|
24
|
+
|
20
25
|
def connected?
|
21
26
|
@connected
|
22
27
|
end
|
@@ -30,6 +35,7 @@ module Playwright
|
|
30
35
|
@contexts << context
|
31
36
|
context.browser = self
|
32
37
|
context.options = params
|
38
|
+
context.send(:update_browser_type, @browser_type)
|
33
39
|
return context unless block
|
34
40
|
|
35
41
|
begin
|
@@ -54,6 +60,13 @@ module Playwright
|
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
63
|
+
private def update_browser_type(browser_type)
|
64
|
+
@browser_type = browser_type
|
65
|
+
@contexts.each do |context|
|
66
|
+
context.send(:update_browser_type, browser_type)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
57
70
|
def close
|
58
71
|
return if @closed_or_closing
|
59
72
|
@closed_or_closing = true
|
@@ -2,6 +2,8 @@ module Playwright
|
|
2
2
|
# @ref https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_browser_context.py
|
3
3
|
define_channel_owner :BrowserContext do
|
4
4
|
include Utils::Errors::SafeCloseError
|
5
|
+
include Utils::PrepareBrowserContextOptions
|
6
|
+
|
5
7
|
attr_accessor :browser
|
6
8
|
attr_writer :owner_page, :options
|
7
9
|
attr_reader :tracing, :request
|
@@ -17,12 +19,17 @@ module Playwright
|
|
17
19
|
|
18
20
|
@tracing = ChannelOwners::Tracing.from(@initializer['tracing'])
|
19
21
|
@request = ChannelOwners::APIRequestContext.from(@initializer['APIRequestContext'])
|
22
|
+
@har_recorders = {}
|
20
23
|
|
21
24
|
@channel.on('bindingCall', ->(params) { on_binding(ChannelOwners::BindingCall.from(params['binding'])) })
|
22
25
|
@channel.once('close', ->(_) { on_close })
|
23
26
|
@channel.on('page', ->(params) { on_page(ChannelOwners::Page.from(params['page']) )})
|
24
27
|
@channel.on('route', ->(params) {
|
25
|
-
|
28
|
+
Concurrent::Promises.future {
|
29
|
+
on_route(ChannelOwners::Route.from(params['route']), ChannelOwners::Request.from(params['request']))
|
30
|
+
}.rescue do |err|
|
31
|
+
puts err, err.backtrace
|
32
|
+
end
|
26
33
|
})
|
27
34
|
@channel.on('backgroundPage', ->(params) {
|
28
35
|
on_background_page(ChannelOwners::Page.from(params['page']))
|
@@ -55,6 +62,16 @@ module Playwright
|
|
55
62
|
@closed_promise = Concurrent::Promises.resolvable_future
|
56
63
|
end
|
57
64
|
|
65
|
+
private def update_browser_type(browser_type)
|
66
|
+
@browser_type = browser_type
|
67
|
+
if @options[:recordHar]
|
68
|
+
@har_recorders[''] = {
|
69
|
+
path: @options[:recordHar][:path],
|
70
|
+
content: @options[:recordHar][:content]
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
58
75
|
private def on_page(page)
|
59
76
|
@pages << page
|
60
77
|
emit(Events::BrowserContext::Page, page)
|
@@ -73,19 +90,29 @@ module Playwright
|
|
73
90
|
wrapped_route = PlaywrightApi.wrap(route)
|
74
91
|
wrapped_request = PlaywrightApi.wrap(request)
|
75
92
|
|
76
|
-
|
77
|
-
|
93
|
+
handled = @routes.any? do |handler_entry|
|
94
|
+
next false unless handler_entry.match?(request.url)
|
95
|
+
|
96
|
+
promise = Concurrent::Promises.resolvable_future
|
97
|
+
route.send(:set_handling_future, promise)
|
98
|
+
|
99
|
+
promise_handled = Concurrent::Promises.zip(
|
100
|
+
promise,
|
101
|
+
handler_entry.async_handle(wrapped_route, wrapped_request)
|
102
|
+
).value!.first
|
103
|
+
|
104
|
+
promise_handled
|
78
105
|
end
|
79
106
|
|
80
|
-
|
81
|
-
|
107
|
+
@routes.reject!(&:expired?)
|
108
|
+
if @routes.count == 0
|
109
|
+
@channel.async_send_message_to_server('setNetworkInterceptionEnabled', enabled: false)
|
110
|
+
end
|
82
111
|
|
83
|
-
|
84
|
-
|
85
|
-
|
112
|
+
unless handled
|
113
|
+
route.send(:async_continue_route).rescue do |err|
|
114
|
+
puts err, err.backtrace
|
86
115
|
end
|
87
|
-
else
|
88
|
-
route.continue
|
89
116
|
end
|
90
117
|
end
|
91
118
|
|
@@ -266,6 +293,37 @@ module Playwright
|
|
266
293
|
end
|
267
294
|
end
|
268
295
|
|
296
|
+
private def record_into_har(har, page, notFound:, url:)
|
297
|
+
params = {
|
298
|
+
options: prepare_record_har_options(
|
299
|
+
record_har_path: har,
|
300
|
+
record_har_content: "attach",
|
301
|
+
record_har_mode: "minimal",
|
302
|
+
record_har_url_filter: url,
|
303
|
+
)
|
304
|
+
}
|
305
|
+
if page
|
306
|
+
params[:page] = page.channel
|
307
|
+
end
|
308
|
+
har_id = @channel.send_message_to_server('harStart', params)
|
309
|
+
@har_recorders[har_id] = { path: har, content: 'attach' }
|
310
|
+
end
|
311
|
+
|
312
|
+
def route_from_har(har, notFound: nil, update: nil, url: nil)
|
313
|
+
if update
|
314
|
+
record_into_har(har, nil, notFound: notFound, url: url)
|
315
|
+
return
|
316
|
+
end
|
317
|
+
|
318
|
+
router = HarRouter.create(
|
319
|
+
@connection.local_utils,
|
320
|
+
har.to_s,
|
321
|
+
notFound || "abort",
|
322
|
+
url_match: url,
|
323
|
+
)
|
324
|
+
router.add_context_route(self)
|
325
|
+
end
|
326
|
+
|
269
327
|
def expect_event(event, predicate: nil, timeout: nil, &block)
|
270
328
|
wait_helper = WaitHelper.new
|
271
329
|
wait_helper.reject_on_timeout(timeout || @timeout_settings.timeout, "Timeout while waiting for event \"#{event}\"")
|
@@ -283,9 +341,19 @@ module Playwright
|
|
283
341
|
end
|
284
342
|
|
285
343
|
def close
|
286
|
-
|
287
|
-
har = ChannelOwners::Artifact.from(@channel.send_message_to_server('harExport'))
|
288
|
-
|
344
|
+
@har_recorders.each do |har_id, params|
|
345
|
+
har = ChannelOwners::Artifact.from(@channel.send_message_to_server('harExport', harId: har_id))
|
346
|
+
# Server side will compress artifact if content is attach or if file is .zip.
|
347
|
+
compressed = params[:content] == "attach" || params[:path].end_with?('.zip')
|
348
|
+
need_comppressed = params[:path].end_with?('.zip')
|
349
|
+
if compressed && !need_comppressed
|
350
|
+
tmp_path = "#{params[:path]}.tmp"
|
351
|
+
har.save_as(tmp_path)
|
352
|
+
@connection.local_utils.har_unzip(tmp_path, params[:path])
|
353
|
+
else
|
354
|
+
har.save_as(params[:path])
|
355
|
+
end
|
356
|
+
|
289
357
|
har.delete
|
290
358
|
end
|
291
359
|
@channel.send_message_to_server('close')
|
@@ -13,6 +13,7 @@ module Playwright
|
|
13
13
|
def launch(options, &block)
|
14
14
|
resp = @channel.send_message_to_server('launch', options.compact)
|
15
15
|
browser = ChannelOwners::Browser.from(resp)
|
16
|
+
browser.send(:update_browser_type, self)
|
16
17
|
return browser unless block
|
17
18
|
|
18
19
|
begin
|
@@ -29,6 +30,8 @@ module Playwright
|
|
29
30
|
|
30
31
|
resp = @channel.send_message_to_server('launchPersistentContext', params.compact)
|
31
32
|
context = ChannelOwners::Browser.from(resp)
|
33
|
+
context.options = params
|
34
|
+
context.send(:update_browser_type, self)
|
32
35
|
return context unless block
|
33
36
|
|
34
37
|
begin
|
@@ -54,6 +57,7 @@ module Playwright
|
|
54
57
|
|
55
58
|
result = @channel.send_message_to_server_result('connectOverCDP', params)
|
56
59
|
browser = ChannelOwners::Browser.from(result['browser'])
|
60
|
+
browser.send(:update_browser_type, self)
|
57
61
|
|
58
62
|
if result['defaultContext']
|
59
63
|
context = ChannelOwners::BrowserContext.from(result['defaultContext'])
|
@@ -25,11 +25,25 @@ module Playwright
|
|
25
25
|
private def on_load_state(add:, remove:)
|
26
26
|
if add
|
27
27
|
@load_states << add
|
28
|
-
|
28
|
+
|
29
|
+
# Original JS version of Playwright emit event here.
|
30
|
+
# @event_emitter.emit('loadstate', add)
|
29
31
|
end
|
30
32
|
if remove
|
31
33
|
@load_states.delete(remove)
|
32
34
|
end
|
35
|
+
unless @parent_frame
|
36
|
+
if add == 'load'
|
37
|
+
@page&.emit(Events::Page::Load, @page)
|
38
|
+
elsif add == 'domcontentloaded'
|
39
|
+
@page&.emit(Events::Page::DOMContentLoaded, @page)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# emit to waitForLoadState(load) listeners explicitly after waitForEvent(load) listeners
|
44
|
+
if add
|
45
|
+
@event_emitter.emit('loadstate', add)
|
46
|
+
end
|
33
47
|
end
|
34
48
|
|
35
49
|
private def on_frame_navigated(event)
|
@@ -38,7 +52,7 @@ module Playwright
|
|
38
52
|
@event_emitter.emit('navigated', event)
|
39
53
|
|
40
54
|
unless event['error']
|
41
|
-
@page&.emit(
|
55
|
+
@page&.emit(Events::Page::FrameNavigated, self)
|
42
56
|
end
|
43
57
|
end
|
44
58
|
|
@@ -10,5 +10,34 @@ module Playwright
|
|
10
10
|
@channel.send_message_to_server('zip', params)
|
11
11
|
nil
|
12
12
|
end
|
13
|
+
|
14
|
+
|
15
|
+
# @param file [String]
|
16
|
+
# @return [String] har ID
|
17
|
+
def har_open(file)
|
18
|
+
@channel.send_message_to_server('harOpen', file: file)
|
19
|
+
end
|
20
|
+
|
21
|
+
def har_lookup(har_id:, url:, method:, headers:, is_navigation_request:, post_data: nil)
|
22
|
+
params = {
|
23
|
+
harId: har_id,
|
24
|
+
url: url,
|
25
|
+
method: method,
|
26
|
+
headers: headers,
|
27
|
+
postData: post_data,
|
28
|
+
isNavigationRequest: is_navigation_request,
|
29
|
+
}.compact
|
30
|
+
|
31
|
+
@channel.send_message_to_server_result('harLookup', params)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param har_id [String]
|
35
|
+
def async_har_close(har_id)
|
36
|
+
@channel.async_send_message_to_server('harClose', harId: har_id)
|
37
|
+
end
|
38
|
+
|
39
|
+
def har_unzip(zip_file, har_file)
|
40
|
+
@channel.send_message_to_server('harUnzip', zipFile: zip_file, harFile: har_file)
|
41
|
+
end
|
13
42
|
end
|
14
43
|
end
|