playwright-ruby-client 1.22.0 → 1.23.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|