playwright-ruby-client 1.18.0 → 1.19.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.md +7 -0
- data/documentation/docs/api/api_request_context.md +167 -45
- data/documentation/docs/api/api_response.md +104 -0
- data/documentation/docs/api/browser_context.md +4 -0
- data/documentation/docs/api/frame.md +1 -1
- data/documentation/docs/api/frame_locator.md +1 -1
- data/documentation/docs/api/locator.md +10 -2
- data/documentation/docs/api/page.md +9 -1
- data/documentation/docs/api/route.md +1 -0
- data/documentation/docs/api/tracing.md +6 -1
- data/documentation/docs/include/api_coverage.md +32 -14
- data/lib/playwright/api_response_impl.rb +77 -0
- data/lib/playwright/channel_owner.rb +4 -0
- data/lib/playwright/channel_owners/api_request_context.rb +236 -0
- data/lib/playwright/channel_owners/browser_context.rb +13 -10
- data/lib/playwright/channel_owners/frame.rb +2 -2
- data/lib/playwright/channel_owners/page.rb +15 -5
- data/lib/playwright/channel_owners/route.rb +18 -4
- data/lib/playwright/{tracing_impl.rb → channel_owners/tracing.rb} +4 -8
- data/lib/playwright/frame_locator_impl.rb +2 -1
- data/lib/playwright/locator_impl.rb +42 -15
- data/lib/playwright/route_handler.rb +11 -8
- data/lib/playwright/transport.rb +1 -1
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright_api/android.rb +6 -6
- data/lib/playwright_api/android_device.rb +6 -6
- data/lib/playwright_api/api_request.rb +20 -0
- data/lib/playwright_api/api_request_context.rb +16 -16
- data/lib/playwright_api/api_response.rb +81 -0
- data/lib/playwright_api/browser.rb +6 -6
- data/lib/playwright_api/browser_context.rb +9 -9
- data/lib/playwright_api/browser_type.rb +6 -6
- data/lib/playwright_api/cdp_session.rb +6 -6
- data/lib/playwright_api/console_message.rb +6 -6
- data/lib/playwright_api/dialog.rb +6 -6
- data/lib/playwright_api/element_handle.rb +6 -6
- data/lib/playwright_api/frame.rb +8 -8
- data/lib/playwright_api/frame_locator.rb +2 -2
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/locator.rb +8 -3
- data/lib/playwright_api/page.rb +18 -18
- data/lib/playwright_api/playwright.rb +8 -8
- data/lib/playwright_api/request.rb +6 -6
- data/lib/playwright_api/response.rb +6 -6
- data/lib/playwright_api/route.rb +8 -7
- data/lib/playwright_api/selectors.rb +6 -6
- data/lib/playwright_api/tracing.rb +29 -2
- data/lib/playwright_api/web_socket.rb +6 -6
- data/lib/playwright_api/worker.rb +6 -6
- metadata +10 -5
@@ -1,4 +1,240 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
1
3
|
module Playwright
|
2
4
|
define_channel_owner :APIRequestContext do
|
5
|
+
private def after_initialize
|
6
|
+
@tracing = ChannelOwners::Tracing.from(@initializer['tracing'])
|
7
|
+
end
|
8
|
+
|
9
|
+
def dispose
|
10
|
+
@channel.send_message_to_server('dispose')
|
11
|
+
end
|
12
|
+
|
13
|
+
def delete(
|
14
|
+
url,
|
15
|
+
data: nil,
|
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
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def head(
|
38
|
+
url,
|
39
|
+
failOnStatusCode: nil,
|
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
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def get(
|
56
|
+
url,
|
57
|
+
failOnStatusCode: nil,
|
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
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
def patch(
|
74
|
+
url,
|
75
|
+
data: nil,
|
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
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
def put(
|
98
|
+
url,
|
99
|
+
data: nil,
|
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
|
+
)
|
119
|
+
end
|
120
|
+
|
121
|
+
def post(
|
122
|
+
url,
|
123
|
+
data: nil,
|
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
|
+
)
|
143
|
+
end
|
144
|
+
|
145
|
+
def fetch(
|
146
|
+
urlOrRequest,
|
147
|
+
data: nil,
|
148
|
+
failOnStatusCode: nil,
|
149
|
+
form: nil,
|
150
|
+
headers: nil,
|
151
|
+
ignoreHTTPSErrors: nil,
|
152
|
+
method: nil,
|
153
|
+
multipart: nil,
|
154
|
+
params: nil,
|
155
|
+
timeout: nil)
|
156
|
+
|
157
|
+
if [ChannelOwners::Request, String].none? { |type| urlOrRequest.is_a?(type) }
|
158
|
+
raise ArgumentError.new("First argument must be either URL string or Request")
|
159
|
+
end
|
160
|
+
if [data, form, multipart].compact.count > 1
|
161
|
+
raise ArgumentError.new("Only one of 'data', 'form' or 'multipart' can be specified")
|
162
|
+
end
|
163
|
+
|
164
|
+
request = urlOrRequest.is_a?(ChannelOwners::Request) ? urlOrRequest : nil
|
165
|
+
headers_obj = headers || request&.headers
|
166
|
+
fetch_params = {
|
167
|
+
url: request&.url || urlOrRequest,
|
168
|
+
params: object_to_array(params),
|
169
|
+
method: method || request&.method || 'GET',
|
170
|
+
headers: headers_obj ? HttpHeaders.new(headers_obj).as_serialized : nil,
|
171
|
+
}
|
172
|
+
|
173
|
+
json_data = nil
|
174
|
+
form_data = nil
|
175
|
+
multipart_data = nil
|
176
|
+
post_data_buffer = nil
|
177
|
+
if data
|
178
|
+
case data
|
179
|
+
when String
|
180
|
+
if headers_obj&.any? { |key, value| key.downcase == 'content-type' && value == 'application/json' }
|
181
|
+
json_data = data
|
182
|
+
else
|
183
|
+
post_data_buffer = data
|
184
|
+
end
|
185
|
+
when Hash, Array, Numeric, true, false
|
186
|
+
json_data = data
|
187
|
+
else
|
188
|
+
raise ArgumentError.new("Unsupported 'data' type: #{data.class}")
|
189
|
+
end
|
190
|
+
elsif form
|
191
|
+
form_data = object_to_array(form)
|
192
|
+
elsif multipart
|
193
|
+
multipart_data = multipart.map do |name, value|
|
194
|
+
if file_payload?(value)
|
195
|
+
{ name: name, file: file_payload_to_json(value) }
|
196
|
+
else
|
197
|
+
{ name: name, value: value.to_s }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
if !json_data && !form_data && !multipart_data
|
203
|
+
post_data_buffer ||= request&.post_data_buffer
|
204
|
+
end
|
205
|
+
if post_data_buffer
|
206
|
+
fetch_params[:postData] = Base64.strict_encode64(post_data_buffer)
|
207
|
+
end
|
208
|
+
|
209
|
+
fetch_params[:jsonData] = json_data
|
210
|
+
fetch_params[:formData] = form_data
|
211
|
+
fetch_params[:multipartData] = multipart_data
|
212
|
+
fetch_params[:timeout] = timeout
|
213
|
+
fetch_params[:failOnStatusCode] = failOnStatusCode
|
214
|
+
fetch_params[:ignoreHTTPSErrors] = ignoreHTTPSErrors
|
215
|
+
fetch_params.compact!
|
216
|
+
response = @channel.send_message_to_server('fetch', fetch_params)
|
217
|
+
|
218
|
+
APIResponseImpl.new(self, response)
|
219
|
+
end
|
220
|
+
|
221
|
+
private def file_payload?(value)
|
222
|
+
value.is_a?(Hash) &&
|
223
|
+
%w(name mimeType buffer).all? { |key| value.has_key?(key) || value.has_key?(key.to_sym) }
|
224
|
+
end
|
225
|
+
|
226
|
+
private def file_payload_to_json(payload)
|
227
|
+
{
|
228
|
+
name: payload[:name] || payload['name'],
|
229
|
+
mimeType: payload[:mimeType] || payload['mimeType'],
|
230
|
+
buffer: Base64.strict_encode64(payload[:buffer] || payload['buffer'])
|
231
|
+
}
|
232
|
+
end
|
233
|
+
|
234
|
+
private def object_to_array(hash)
|
235
|
+
hash&.map do |key, value|
|
236
|
+
{ name: key, value: value.to_s }
|
237
|
+
end
|
238
|
+
end
|
3
239
|
end
|
4
240
|
end
|
@@ -4,7 +4,7 @@ module Playwright
|
|
4
4
|
include Utils::Errors::SafeCloseError
|
5
5
|
attr_accessor :browser
|
6
6
|
attr_writer :owner_page, :options
|
7
|
-
attr_reader :tracing
|
7
|
+
attr_reader :tracing, :request
|
8
8
|
|
9
9
|
private def after_initialize
|
10
10
|
@pages = Set.new
|
@@ -14,7 +14,9 @@ module Playwright
|
|
14
14
|
@service_workers = Set.new
|
15
15
|
@background_pages = Set.new
|
16
16
|
|
17
|
-
@tracing =
|
17
|
+
@tracing = ChannelOwners::Tracing.from(@initializer['tracing'])
|
18
|
+
@request = ChannelOwners::APIRequestContext.from(@initializer['APIRequestContext'])
|
19
|
+
|
18
20
|
@channel.on('bindingCall', ->(params) { on_binding(ChannelOwners::BindingCall.from(params['binding'])) })
|
19
21
|
@channel.once('close', ->(_) { on_close })
|
20
22
|
@channel.on('page', ->(params) { on_page(ChannelOwners::Page.from(params['page']) )})
|
@@ -70,13 +72,19 @@ module Playwright
|
|
70
72
|
wrapped_route = PlaywrightApi.wrap(route)
|
71
73
|
wrapped_request = PlaywrightApi.wrap(request)
|
72
74
|
|
73
|
-
|
74
|
-
|
75
|
-
|
75
|
+
handler_entry = @routes.find do |entry|
|
76
|
+
entry.match?(request.url)
|
77
|
+
end
|
78
|
+
|
79
|
+
if handler_entry
|
80
|
+
handler_entry.async_handle(wrapped_route, wrapped_request)
|
81
|
+
|
76
82
|
@routes.reject!(&:expired?)
|
77
83
|
if @routes.count == 0
|
78
84
|
@channel.async_send_message_to_server('setNetworkInterceptionEnabled', enabled: false)
|
79
85
|
end
|
86
|
+
else
|
87
|
+
route.continue
|
80
88
|
end
|
81
89
|
end
|
82
90
|
|
@@ -358,10 +366,5 @@ module Playwright
|
|
358
366
|
private def base_url
|
359
367
|
@options[:baseURL]
|
360
368
|
end
|
361
|
-
|
362
|
-
# called from Tracing
|
363
|
-
private def remote_connection?
|
364
|
-
@connection.remote?
|
365
|
-
end
|
366
369
|
end
|
367
370
|
end
|
@@ -400,8 +400,8 @@ module Playwright
|
|
400
400
|
nil
|
401
401
|
end
|
402
402
|
|
403
|
-
def locator(selector, hasText: nil)
|
404
|
-
LocatorImpl.new(frame: self, timeout_settings: @page.send(:timeout_settings), selector: selector, hasText: hasText)
|
403
|
+
def locator(selector, hasText: nil, has: nil)
|
404
|
+
LocatorImpl.new(frame: self, timeout_settings: @page.send(:timeout_settings), selector: selector, hasText: hasText, has: has)
|
405
405
|
end
|
406
406
|
|
407
407
|
def frame_locator(selector)
|
@@ -98,13 +98,19 @@ module Playwright
|
|
98
98
|
wrapped_route = PlaywrightApi.wrap(route)
|
99
99
|
wrapped_request = PlaywrightApi.wrap(request)
|
100
100
|
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
handler_entry = @routes.find do |entry|
|
102
|
+
entry.match?(request.url)
|
103
|
+
end
|
104
|
+
|
105
|
+
if handler_entry
|
106
|
+
handler_entry.async_handle(wrapped_route, wrapped_request)
|
107
|
+
|
104
108
|
@routes.reject!(&:expired?)
|
105
109
|
if @routes.count == 0
|
106
110
|
@channel.async_send_message_to_server('setNetworkInterceptionEnabled', enabled: false)
|
107
111
|
end
|
112
|
+
else
|
113
|
+
@browser_context.send(:on_route, route, request)
|
108
114
|
end
|
109
115
|
end
|
110
116
|
|
@@ -558,8 +564,8 @@ module Playwright
|
|
558
564
|
timeout: timeout)
|
559
565
|
end
|
560
566
|
|
561
|
-
def locator(selector, hasText: nil)
|
562
|
-
@main_frame.locator(selector, hasText: hasText)
|
567
|
+
def locator(selector, hasText: nil, has: nil)
|
568
|
+
@main_frame.locator(selector, hasText: hasText, has: has)
|
563
569
|
end
|
564
570
|
|
565
571
|
def frame_locator(selector)
|
@@ -733,6 +739,10 @@ module Playwright
|
|
733
739
|
@workers.to_a
|
734
740
|
end
|
735
741
|
|
742
|
+
def request
|
743
|
+
@browser_context.request
|
744
|
+
end
|
745
|
+
|
736
746
|
def pause
|
737
747
|
@browser_context.send(:pause)
|
738
748
|
end
|
@@ -17,16 +17,30 @@ module Playwright
|
|
17
17
|
contentType: nil,
|
18
18
|
headers: nil,
|
19
19
|
path: nil,
|
20
|
-
status: nil
|
20
|
+
status: nil,
|
21
|
+
response: nil)
|
21
22
|
params = {
|
22
23
|
contentType: contentType,
|
23
24
|
status: status,
|
24
25
|
}.compact
|
26
|
+
option_body = body
|
27
|
+
|
28
|
+
if response
|
29
|
+
params[:status] ||= response.status
|
30
|
+
params[:headers] ||= response.headers
|
31
|
+
|
32
|
+
if !body && !path && response.is_a?(APIResponse)
|
33
|
+
if response.send(:_request).send(:same_connection?, self)
|
34
|
+
params[:fetchResponseUid] = response.send(:fetch_uid)
|
35
|
+
else
|
36
|
+
option_body = response.body
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
25
40
|
|
26
|
-
length = 0
|
27
41
|
content =
|
28
|
-
if
|
29
|
-
|
42
|
+
if option_body
|
43
|
+
option_body
|
30
44
|
elsif path
|
31
45
|
File.read(path)
|
32
46
|
else
|
@@ -1,15 +1,11 @@
|
|
1
1
|
module Playwright
|
2
|
-
|
3
|
-
def
|
4
|
-
@channel = channel
|
5
|
-
@context = context
|
6
|
-
end
|
7
|
-
|
8
|
-
def start(name: nil, title: nil, screenshots: nil, snapshots: nil)
|
2
|
+
define_channel_owner :Tracing do
|
3
|
+
def start(name: nil, title: nil, screenshots: nil, snapshots: nil, sources: nil)
|
9
4
|
params = {
|
10
5
|
name: name,
|
11
6
|
screenshots: screenshots,
|
12
7
|
snapshots: snapshots,
|
8
|
+
sources: sources,
|
13
9
|
}.compact
|
14
10
|
@channel.send_message_to_server('tracingStart', params)
|
15
11
|
@channel.send_message_to_server('tracingStartChunk', { title: title }.compact)
|
@@ -31,7 +27,7 @@ module Playwright
|
|
31
27
|
private def do_stop_chunk(file_path:)
|
32
28
|
mode = 'doNotSave'
|
33
29
|
if file_path
|
34
|
-
if @
|
30
|
+
if @connection.remote?
|
35
31
|
mode = 'compressTrace'
|
36
32
|
else
|
37
33
|
mode = 'compressTraceAndSources'
|
@@ -6,12 +6,13 @@ module Playwright
|
|
6
6
|
@frame_selector = frame_selector
|
7
7
|
end
|
8
8
|
|
9
|
-
def locator(selector, hasText: nil)
|
9
|
+
def locator(selector, hasText: nil, has: nil)
|
10
10
|
LocatorImpl.new(
|
11
11
|
frame: @frame,
|
12
12
|
timeout_settings: @timeout_settings,
|
13
13
|
selector: "#{@frame_selector} >> control=enter-frame >> #{selector}",
|
14
14
|
hasText: hasText,
|
15
|
+
has: has,
|
15
16
|
)
|
16
17
|
end
|
17
18
|
|
@@ -24,29 +24,51 @@ module Playwright
|
|
24
24
|
end
|
25
25
|
|
26
26
|
define_api_implementation :LocatorImpl do
|
27
|
-
def initialize(frame:, timeout_settings:, selector:, hasText: nil)
|
27
|
+
def initialize(frame:, timeout_settings:, selector:, hasText: nil, has: nil)
|
28
28
|
@frame = frame
|
29
29
|
@timeout_settings = timeout_settings
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
30
|
+
selector_scopes = [selector]
|
31
|
+
|
32
|
+
case hasText
|
33
|
+
when Regexp
|
34
|
+
source = EscapeWithQuotes.new(hasText.source, '"')
|
35
|
+
flags = []
|
36
|
+
flags << 'ms' if (hasText.options & Regexp::MULTILINE) != 0
|
37
|
+
flags << 'i' if (hasText.options & Regexp::IGNORECASE) != 0
|
38
|
+
selector_scopes << ":scope:text-matches(#{source}, \"#{flags.join('')}\")"
|
39
|
+
when String
|
40
|
+
text = EscapeWithQuotes.new(hasText, '"')
|
41
|
+
selector_scopes << ":scope:has-text(#{text})"
|
42
|
+
end
|
43
|
+
|
44
|
+
if has
|
45
|
+
unless same_frame?(has)
|
46
|
+
raise DifferentFrameError.new
|
43
47
|
end
|
48
|
+
selector_scopes << "has=#{has.send(:selector_json)}"
|
49
|
+
end
|
50
|
+
|
51
|
+
@selector = selector_scopes.join(' >> ')
|
44
52
|
end
|
45
53
|
|
46
54
|
def to_s
|
47
55
|
"Locator@#{@selector}"
|
48
56
|
end
|
49
57
|
|
58
|
+
class DifferentFrameError < StandardError
|
59
|
+
def initialize
|
60
|
+
super('Inner "has" locator must belong to the same frame.')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private def same_frame?(other)
|
65
|
+
@frame == other.instance_variable_get(:@frame)
|
66
|
+
end
|
67
|
+
|
68
|
+
private def selector_json
|
69
|
+
@selector.to_json
|
70
|
+
end
|
71
|
+
|
50
72
|
private def with_element(timeout: nil, &block)
|
51
73
|
timeout_or_default = @timeout_settings.timeout(timeout)
|
52
74
|
start_time = Time.now
|
@@ -67,6 +89,10 @@ module Playwright
|
|
67
89
|
end
|
68
90
|
end
|
69
91
|
|
92
|
+
def page
|
93
|
+
@frame.page
|
94
|
+
end
|
95
|
+
|
70
96
|
def bounding_box(timeout: nil)
|
71
97
|
with_element(timeout: timeout) do |handle|
|
72
98
|
handle.bounding_box
|
@@ -180,12 +206,13 @@ module Playwright
|
|
180
206
|
@frame.fill(@selector, value, strict: true, force: force, noWaitAfter: noWaitAfter, timeout: timeout)
|
181
207
|
end
|
182
208
|
|
183
|
-
def locator(selector, hasText: nil)
|
209
|
+
def locator(selector, hasText: nil, has: nil)
|
184
210
|
LocatorImpl.new(
|
185
211
|
frame: @frame,
|
186
212
|
timeout_settings: @timeout_settings,
|
187
213
|
selector: "#{@selector} >> #{selector}",
|
188
214
|
hasText: hasText,
|
215
|
+
has: has,
|
189
216
|
)
|
190
217
|
end
|
191
218
|
|
@@ -5,7 +5,7 @@ module Playwright
|
|
5
5
|
@count = count
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
8
|
+
def increment
|
9
9
|
return false if expired?
|
10
10
|
|
11
11
|
@count = @count - 1
|
@@ -18,7 +18,7 @@ module Playwright
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class StubCounter
|
21
|
-
def
|
21
|
+
def increment
|
22
22
|
true
|
23
23
|
end
|
24
24
|
|
@@ -43,14 +43,17 @@ module Playwright
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
def
|
47
|
-
|
46
|
+
def match?(url)
|
47
|
+
@url_matcher.match?(url)
|
48
|
+
end
|
49
|
+
|
50
|
+
def async_handle(route, request)
|
51
|
+
@counter.increment
|
48
52
|
|
49
|
-
|
53
|
+
Concurrent::Promises.future do
|
50
54
|
@handler.call(route, request)
|
51
|
-
|
52
|
-
|
53
|
-
false
|
55
|
+
rescue => err
|
56
|
+
puts err, err.backtrace
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
data/lib/playwright/transport.rb
CHANGED
@@ -46,7 +46,7 @@ module Playwright
|
|
46
46
|
#
|
47
47
|
# @note This method blocks until playwright-cli exited. Consider using Thread or Future.
|
48
48
|
def async_run
|
49
|
-
@stdin, @stdout, @stderr, @thread = Open3.popen3("#{@driver_executable_path} run-driver")
|
49
|
+
@stdin, @stdout, @stderr, @thread = Open3.popen3("#{@driver_executable_path} run-driver", { pgroup: true })
|
50
50
|
@stdin.binmode # Ensure Strings are written 1:1 without encoding conversion, necessary for integer values
|
51
51
|
|
52
52
|
Thread.new { handle_stdout }
|
data/lib/playwright/version.rb
CHANGED
@@ -38,20 +38,20 @@ module Playwright
|
|
38
38
|
|
39
39
|
# -- inherited from EventEmitter --
|
40
40
|
# @nodoc
|
41
|
-
def
|
42
|
-
event_emitter_proxy.
|
41
|
+
def off(event, callback)
|
42
|
+
event_emitter_proxy.off(event, callback)
|
43
43
|
end
|
44
44
|
|
45
45
|
# -- inherited from EventEmitter --
|
46
46
|
# @nodoc
|
47
|
-
def
|
48
|
-
event_emitter_proxy.
|
47
|
+
def once(event, callback)
|
48
|
+
event_emitter_proxy.once(event, callback)
|
49
49
|
end
|
50
50
|
|
51
51
|
# -- inherited from EventEmitter --
|
52
52
|
# @nodoc
|
53
|
-
def
|
54
|
-
event_emitter_proxy.
|
53
|
+
def on(event, callback)
|
54
|
+
event_emitter_proxy.on(event, callback)
|
55
55
|
end
|
56
56
|
|
57
57
|
private def event_emitter_proxy
|
@@ -176,20 +176,20 @@ module Playwright
|
|
176
176
|
|
177
177
|
# -- inherited from EventEmitter --
|
178
178
|
# @nodoc
|
179
|
-
def
|
180
|
-
event_emitter_proxy.
|
179
|
+
def off(event, callback)
|
180
|
+
event_emitter_proxy.off(event, callback)
|
181
181
|
end
|
182
182
|
|
183
183
|
# -- inherited from EventEmitter --
|
184
184
|
# @nodoc
|
185
|
-
def
|
186
|
-
event_emitter_proxy.
|
185
|
+
def once(event, callback)
|
186
|
+
event_emitter_proxy.once(event, callback)
|
187
187
|
end
|
188
188
|
|
189
189
|
# -- inherited from EventEmitter --
|
190
190
|
# @nodoc
|
191
|
-
def
|
192
|
-
event_emitter_proxy.
|
191
|
+
def on(event, callback)
|
192
|
+
event_emitter_proxy.on(event, callback)
|
193
193
|
end
|
194
194
|
|
195
195
|
private def event_emitter_proxy
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Playwright
|
2
|
+
# Exposes API that can be used for the Web API testing. Each Playwright browser context has a APIRequestContext instance
|
3
|
+
# attached which shares cookies with the page context. Its also possible to create a new APIRequestContext instance
|
4
|
+
# manually. For more information see [here](./class-apirequestcontext).
|
5
|
+
class APIRequest < PlaywrightApi
|
6
|
+
|
7
|
+
# Creates new instances of `APIRequestContext`.
|
8
|
+
def new_context(
|
9
|
+
baseURL: nil,
|
10
|
+
extraHTTPHeaders: nil,
|
11
|
+
httpCredentials: nil,
|
12
|
+
ignoreHTTPSErrors: nil,
|
13
|
+
proxy: nil,
|
14
|
+
storageState: nil,
|
15
|
+
timeout: nil,
|
16
|
+
userAgent: nil)
|
17
|
+
raise NotImplementedError.new('new_context is not implemented yet.')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|