playwright-ruby-client 1.60.0 → 1.62.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/README.md +12 -17
- data/documentation/docs/api/api_response.md +30 -0
- data/documentation/docs/api/browser_context.md +11 -3
- data/documentation/docs/api/browser_type.md +3 -0
- data/documentation/docs/api/credentials.md +136 -0
- data/documentation/docs/api/element_handle.md +7 -0
- data/documentation/docs/api/frame.md +12 -4
- data/documentation/docs/api/locator.md +29 -0
- data/documentation/docs/api/locator_assertions.md +4 -2
- data/documentation/docs/api/page.md +26 -2
- data/documentation/docs/api/playwright.md +2 -2
- data/documentation/docs/api/touchscreen.md +1 -1
- data/documentation/docs/api/web_storage.md +65 -0
- data/documentation/docs/article/getting_started.md +12 -11
- data/documentation/docs/article/guides/download_playwright_driver.md +11 -32
- data/documentation/docs/article/guides/launch_browser.md +5 -4
- data/documentation/docs/article/guides/playwright_on_alpine_linux.md +6 -5
- data/documentation/docs/article/guides/rails_integration.md +72 -4
- data/documentation/docs/article/guides/rails_integration_with_null_driver.md +4 -3
- data/documentation/docs/article/guides/semi_automation.md +1 -1
- data/documentation/docs/article/guides/use_storage_state.md +1 -1
- data/documentation/docs/include/api_coverage.md +22 -0
- data/documentation/docusaurus.config.js +31 -0
- data/documentation/package.json +3 -0
- data/documentation/yarn.lock +159 -174
- data/lib/playwright/api_response_impl.rb +24 -0
- data/lib/playwright/channel_owners/browser_context.rb +8 -3
- data/lib/playwright/channel_owners/browser_type.rb +2 -1
- data/lib/playwright/channel_owners/element_handle.rb +14 -4
- data/lib/playwright/channel_owners/frame.rb +50 -17
- data/lib/playwright/channel_owners/page.rb +31 -10
- data/lib/playwright/connection.rb +16 -2
- data/lib/playwright/credentials_impl.rb +35 -0
- data/lib/playwright/errors.rb +4 -1
- data/lib/playwright/locator_assertions_impl.rb +14 -1
- data/lib/playwright/locator_impl.rb +28 -5
- data/lib/playwright/locator_utils.rb +9 -1
- data/lib/playwright/screencast.rb +22 -6
- data/lib/playwright/screenshot_utils.rb +24 -0
- data/lib/playwright/test.rb +12 -2
- data/lib/playwright/url_matcher.rb +120 -4
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright/waiter.rb +9 -41
- data/lib/playwright/web_storage_impl.rb +34 -0
- data/lib/playwright.rb +2 -2
- data/lib/playwright_api/api_request_context.rb +6 -6
- data/lib/playwright_api/api_response.rb +21 -0
- data/lib/playwright_api/browser.rb +6 -6
- data/lib/playwright_api/browser_context.rb +27 -18
- data/lib/playwright_api/browser_type.rb +10 -7
- data/lib/playwright_api/cdp_session.rb +6 -6
- data/lib/playwright_api/credentials.rb +124 -0
- data/lib/playwright_api/dialog.rb +6 -6
- data/lib/playwright_api/element_handle.rb +20 -13
- data/lib/playwright_api/frame.rb +36 -28
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/locator.rb +37 -11
- data/lib/playwright_api/locator_assertions.rb +6 -4
- data/lib/playwright_api/page.rb +55 -29
- data/lib/playwright_api/playwright.rb +6 -6
- data/lib/playwright_api/request.rb +6 -6
- data/lib/playwright_api/response.rb +6 -6
- data/lib/playwright_api/route.rb +6 -6
- data/lib/playwright_api/touchscreen.rb +1 -1
- data/lib/playwright_api/tracing.rb +6 -6
- data/lib/playwright_api/web_socket.rb +6 -6
- data/lib/playwright_api/web_storage.rb +48 -0
- data/lib/playwright_api/worker.rb +6 -6
- data/playwright.gemspec +5 -0
- data/sig/playwright.rbs +62 -40
- metadata +13 -3
|
@@ -105,6 +105,7 @@ module Playwright
|
|
|
105
105
|
force: nil,
|
|
106
106
|
noWaitAfter: nil,
|
|
107
107
|
position: nil,
|
|
108
|
+
scroll: nil,
|
|
108
109
|
timeout: nil,
|
|
109
110
|
trial: nil)
|
|
110
111
|
|
|
@@ -113,6 +114,7 @@ module Playwright
|
|
|
113
114
|
force: force,
|
|
114
115
|
noWaitAfter: noWaitAfter,
|
|
115
116
|
position: position,
|
|
117
|
+
scroll: scroll,
|
|
116
118
|
timeout: timeout,
|
|
117
119
|
trial: trial)
|
|
118
120
|
end
|
|
@@ -125,6 +127,7 @@ module Playwright
|
|
|
125
127
|
modifiers: nil,
|
|
126
128
|
noWaitAfter: nil,
|
|
127
129
|
position: nil,
|
|
130
|
+
scroll: nil,
|
|
128
131
|
timeout: nil,
|
|
129
132
|
trial: nil,
|
|
130
133
|
steps: nil)
|
|
@@ -138,6 +141,7 @@ module Playwright
|
|
|
138
141
|
modifiers: modifiers,
|
|
139
142
|
noWaitAfter: noWaitAfter,
|
|
140
143
|
position: position,
|
|
144
|
+
scroll: scroll,
|
|
141
145
|
timeout: timeout,
|
|
142
146
|
trial: trial,
|
|
143
147
|
steps: steps)
|
|
@@ -150,6 +154,7 @@ module Playwright
|
|
|
150
154
|
modifiers: nil,
|
|
151
155
|
noWaitAfter: nil,
|
|
152
156
|
position: nil,
|
|
157
|
+
scroll: nil,
|
|
153
158
|
timeout: nil,
|
|
154
159
|
trial: nil,
|
|
155
160
|
steps: nil)
|
|
@@ -162,6 +167,7 @@ module Playwright
|
|
|
162
167
|
modifiers: modifiers,
|
|
163
168
|
noWaitAfter: noWaitAfter,
|
|
164
169
|
position: position,
|
|
170
|
+
scroll: scroll,
|
|
165
171
|
timeout: timeout,
|
|
166
172
|
trial: trial,
|
|
167
173
|
steps: steps)
|
|
@@ -174,6 +180,7 @@ module Playwright
|
|
|
174
180
|
def drag_to(target,
|
|
175
181
|
force: nil,
|
|
176
182
|
noWaitAfter: nil,
|
|
183
|
+
scroll: nil,
|
|
177
184
|
sourcePosition: nil,
|
|
178
185
|
targetPosition: nil,
|
|
179
186
|
timeout: nil,
|
|
@@ -185,6 +192,7 @@ module Playwright
|
|
|
185
192
|
target.instance_variable_get(:@selector),
|
|
186
193
|
force: force,
|
|
187
194
|
noWaitAfter: noWaitAfter,
|
|
195
|
+
scroll: scroll,
|
|
188
196
|
sourcePosition: sourcePosition,
|
|
189
197
|
targetPosition: targetPosition,
|
|
190
198
|
timeout: timeout,
|
|
@@ -363,6 +371,7 @@ module Playwright
|
|
|
363
371
|
modifiers: nil,
|
|
364
372
|
noWaitAfter: nil,
|
|
365
373
|
position: nil,
|
|
374
|
+
scroll: nil,
|
|
366
375
|
timeout: nil,
|
|
367
376
|
trial: nil)
|
|
368
377
|
@frame.hover(@selector,
|
|
@@ -371,6 +380,7 @@ module Playwright
|
|
|
371
380
|
modifiers: modifiers,
|
|
372
381
|
noWaitAfter: noWaitAfter,
|
|
373
382
|
position: position,
|
|
383
|
+
scroll: scroll,
|
|
374
384
|
timeout: timeout,
|
|
375
385
|
trial: trial)
|
|
376
386
|
end
|
|
@@ -426,7 +436,7 @@ module Playwright
|
|
|
426
436
|
end
|
|
427
437
|
end
|
|
428
438
|
|
|
429
|
-
def aria_snapshot(boxes: nil, depth: nil, mode: nil, timeout: nil
|
|
439
|
+
def aria_snapshot(boxes: nil, depth: nil, mode: nil, timeout: nil)
|
|
430
440
|
params = {
|
|
431
441
|
selector: @selector,
|
|
432
442
|
timeout: _timeout(timeout),
|
|
@@ -434,10 +444,6 @@ module Playwright
|
|
|
434
444
|
params[:boxes] = boxes unless boxes.nil?
|
|
435
445
|
params[:depth] = depth if depth
|
|
436
446
|
params[:mode] = mode if mode
|
|
437
|
-
if _track
|
|
438
|
-
params.delete(:selector)
|
|
439
|
-
params[:track] = _track
|
|
440
|
-
end
|
|
441
447
|
result = @frame.channel.send_message_to_server_result('ariaSnapshot', params.compact)
|
|
442
448
|
result['snapshot']
|
|
443
449
|
end
|
|
@@ -499,6 +505,7 @@ module Playwright
|
|
|
499
505
|
modifiers: nil,
|
|
500
506
|
noWaitAfter: nil,
|
|
501
507
|
position: nil,
|
|
508
|
+
scroll: nil,
|
|
502
509
|
timeout: nil,
|
|
503
510
|
trial: nil)
|
|
504
511
|
@frame.tap_point(@selector,
|
|
@@ -507,6 +514,7 @@ module Playwright
|
|
|
507
514
|
modifiers: modifiers,
|
|
508
515
|
noWaitAfter: noWaitAfter,
|
|
509
516
|
position: position,
|
|
517
|
+
scroll: scroll,
|
|
510
518
|
timeout: timeout,
|
|
511
519
|
trial: trial)
|
|
512
520
|
end
|
|
@@ -527,6 +535,7 @@ module Playwright
|
|
|
527
535
|
force: nil,
|
|
528
536
|
noWaitAfter: nil,
|
|
529
537
|
position: nil,
|
|
538
|
+
scroll: nil,
|
|
530
539
|
timeout: nil,
|
|
531
540
|
trial: nil)
|
|
532
541
|
@frame.uncheck(@selector,
|
|
@@ -534,10 +543,24 @@ module Playwright
|
|
|
534
543
|
force: force,
|
|
535
544
|
noWaitAfter: noWaitAfter,
|
|
536
545
|
position: position,
|
|
546
|
+
scroll: scroll,
|
|
537
547
|
timeout: timeout,
|
|
538
548
|
trial: trial)
|
|
539
549
|
end
|
|
540
550
|
|
|
551
|
+
def wait_for_function(expression, arg: nil, timeout: nil)
|
|
552
|
+
@frame.channel.send_message_to_server(
|
|
553
|
+
'waitForFunction',
|
|
554
|
+
selector: @selector,
|
|
555
|
+
strict: true,
|
|
556
|
+
expression: expression,
|
|
557
|
+
isFunction: true,
|
|
558
|
+
arg: JavaScript::ValueSerializer.new(arg).serialize,
|
|
559
|
+
timeout: _timeout(timeout),
|
|
560
|
+
)
|
|
561
|
+
nil
|
|
562
|
+
end
|
|
563
|
+
|
|
541
564
|
def wait_for(state: nil, timeout: nil)
|
|
542
565
|
@frame.wait_for_selector(@selector, strict: true, state: state, timeout: timeout)
|
|
543
566
|
end
|
|
@@ -39,7 +39,15 @@ module Playwright
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
private def get_by_test_id_selector(test_id_attribute_name, test_id)
|
|
42
|
-
"internal:testid=[#{test_id_attribute_name}=#{escape_for_attribute_selector_or_regex(test_id, true)}]"
|
|
42
|
+
"internal:testid=[#{encode_test_id_attribute_name(test_id_attribute_name)}=#{escape_for_attribute_selector_or_regex(test_id, true)}]"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private def encode_test_id_attribute_name(test_id_attribute_name)
|
|
46
|
+
if test_id_attribute_name.include?(',')
|
|
47
|
+
JSON.generate(test_id_attribute_name)
|
|
48
|
+
else
|
|
49
|
+
test_id_attribute_name
|
|
50
|
+
end
|
|
43
51
|
end
|
|
44
52
|
|
|
45
53
|
private def get_by_label_selector(text, exact:)
|
|
@@ -63,11 +63,12 @@ module Playwright
|
|
|
63
63
|
@page.send(:channel).send_message_to_server('screencastChapter', params)
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
def show_actions(duration: nil, fontSize: nil, position: nil)
|
|
66
|
+
def show_actions(duration: nil, fontSize: nil, position: nil, cursor: nil)
|
|
67
67
|
params = {}
|
|
68
68
|
params[:duration] = duration if duration
|
|
69
69
|
params[:fontSize] = fontSize if fontSize
|
|
70
70
|
params[:position] = position if position
|
|
71
|
+
params[:cursor] = cursor if cursor
|
|
71
72
|
@page.send(:channel).send_message_to_server('screencastShowActions', params)
|
|
72
73
|
DisposableStub.new { hide_actions }
|
|
73
74
|
end
|
|
@@ -85,11 +86,26 @@ module Playwright
|
|
|
85
86
|
end
|
|
86
87
|
|
|
87
88
|
private def handle_screencast_frame(event)
|
|
88
|
-
@on_frame
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
on_frame = @on_frame
|
|
90
|
+
Thread.new do
|
|
91
|
+
begin
|
|
92
|
+
on_frame&.call({
|
|
93
|
+
data: Base64.strict_decode64(event['data']),
|
|
94
|
+
timestamp: event['timestamp'],
|
|
95
|
+
viewportWidth: event['viewportWidth'],
|
|
96
|
+
viewportHeight: event['viewportHeight'],
|
|
97
|
+
})
|
|
98
|
+
ensure
|
|
99
|
+
begin
|
|
100
|
+
@page.send(:channel).async_send_message_to_server(
|
|
101
|
+
'screencastFrameAck',
|
|
102
|
+
frameId: event['frameId'],
|
|
103
|
+
)
|
|
104
|
+
rescue Transport::AlreadyDisconnectedError
|
|
105
|
+
# The page or driver may close while a callback is running.
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
93
109
|
end
|
|
94
110
|
end
|
|
95
111
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'mime/types'
|
|
2
|
+
|
|
3
|
+
module Playwright
|
|
4
|
+
module ScreenshotUtils
|
|
5
|
+
module_function
|
|
6
|
+
|
|
7
|
+
def determine_type(path:, type:)
|
|
8
|
+
return type if type
|
|
9
|
+
return nil unless path
|
|
10
|
+
|
|
11
|
+
mime_type = MIME::Types.type_for(path).first
|
|
12
|
+
case mime_type&.content_type
|
|
13
|
+
when 'image/png'
|
|
14
|
+
'png'
|
|
15
|
+
when 'image/jpeg'
|
|
16
|
+
'jpeg'
|
|
17
|
+
when 'image/webp'
|
|
18
|
+
'webp'
|
|
19
|
+
else
|
|
20
|
+
raise ArgumentError.new("path: unsupported mime type \"#{mime_type}\"")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/playwright/test.rb
CHANGED
|
@@ -30,7 +30,7 @@ module Playwright
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def matches?(actual)
|
|
33
|
-
|
|
33
|
+
call_assertion(actual, false)
|
|
34
34
|
true
|
|
35
35
|
rescue AssertionError => e
|
|
36
36
|
@failure_message = e.full_message
|
|
@@ -38,7 +38,7 @@ module Playwright
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def does_not_match?(actual)
|
|
41
|
-
|
|
41
|
+
call_assertion(actual, true)
|
|
42
42
|
true
|
|
43
43
|
rescue AssertionError => e
|
|
44
44
|
@failure_message = e.full_message
|
|
@@ -55,6 +55,16 @@ module Playwright
|
|
|
55
55
|
|
|
56
56
|
private
|
|
57
57
|
|
|
58
|
+
def call_assertion(actual, is_not)
|
|
59
|
+
args = @args
|
|
60
|
+
kwargs = @kwargs
|
|
61
|
+
if ['to_have_attribute', 'not_to_have_attribute'].include?(@method) && args.length == 2 && !kwargs.key?(:value)
|
|
62
|
+
args = [args.first]
|
|
63
|
+
kwargs = kwargs.merge(value: @args.last)
|
|
64
|
+
end
|
|
65
|
+
assertions_for(actual, is_not).send(@method, *args, **kwargs)
|
|
66
|
+
end
|
|
67
|
+
|
|
58
68
|
def assertions_for(actual, is_not)
|
|
59
69
|
if actual.respond_to?(:_assertions)
|
|
60
70
|
actual._assertions(::Playwright::Test.expect_timeout, is_not, nil)
|
|
@@ -23,7 +23,7 @@ module Playwright
|
|
|
23
23
|
def match?(target_url)
|
|
24
24
|
case @url
|
|
25
25
|
when String
|
|
26
|
-
joined_url == target_url || File.fnmatch?(
|
|
26
|
+
joined_url == target_url || File.fnmatch?(joined_url, target_url)
|
|
27
27
|
when Regexp
|
|
28
28
|
@url.match?(target_url)
|
|
29
29
|
else
|
|
@@ -32,13 +32,129 @@ module Playwright
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
private def joined_url
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
normalized_url = normalize_literal_url(@url)
|
|
36
|
+
if @base_url && !normalized_url.start_with?('*')
|
|
37
|
+
normalize_literal_url(URI.join(normalize_literal_url(@base_url), normalized_url).to_s)
|
|
37
38
|
else
|
|
38
|
-
|
|
39
|
+
normalized_url
|
|
39
40
|
end
|
|
40
41
|
end
|
|
41
42
|
|
|
43
|
+
private def normalize_literal_url(url)
|
|
44
|
+
match = url.match(/\A([a-z][a-z0-9+.-]*):\/\/([^\/?#]*)(.*)\z/i)
|
|
45
|
+
return percent_encode_literal_characters(url) unless match
|
|
46
|
+
|
|
47
|
+
scheme = match[1].downcase
|
|
48
|
+
authority = match[2]
|
|
49
|
+
suffix = percent_encode_literal_characters(match[3])
|
|
50
|
+
|
|
51
|
+
before, separator, after = authority.rpartition('@')
|
|
52
|
+
if separator.empty?
|
|
53
|
+
userinfo = nil
|
|
54
|
+
host_port = authority
|
|
55
|
+
else
|
|
56
|
+
userinfo = before
|
|
57
|
+
host_port = after
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
if host_port.start_with?('[')
|
|
61
|
+
host = host_port
|
|
62
|
+
port = nil
|
|
63
|
+
else
|
|
64
|
+
host, separator, candidate_port = host_port.rpartition(':')
|
|
65
|
+
if separator.empty? || candidate_port !~ /\A\d+\z/
|
|
66
|
+
host = host_port
|
|
67
|
+
port = nil
|
|
68
|
+
else
|
|
69
|
+
port = candidate_port
|
|
70
|
+
end
|
|
71
|
+
host = host.split('.').map { |label| punycode_label(label.downcase) }.join('.')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
port = nil if (scheme == 'http' && port == '80') || (scheme == 'https' && port == '443')
|
|
75
|
+
normalized_authority = String.new
|
|
76
|
+
normalized_authority << "#{userinfo}@" if userinfo
|
|
77
|
+
normalized_authority << host
|
|
78
|
+
normalized_authority << ":#{port}" if port
|
|
79
|
+
"#{scheme}://#{normalized_authority}#{suffix}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private def percent_encode_literal_characters(value)
|
|
83
|
+
value.each_char.map do |char|
|
|
84
|
+
if char == ' '
|
|
85
|
+
'%20'
|
|
86
|
+
elsif char.ascii_only?
|
|
87
|
+
char
|
|
88
|
+
else
|
|
89
|
+
char.encode(Encoding::UTF_8).bytes.map { |byte| format('%%%02X', byte) }.join
|
|
90
|
+
end
|
|
91
|
+
end.join
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# RFC 3492 Punycode encoder for the non-ASCII URL host labels normalized by WHATWG URL.
|
|
95
|
+
private def punycode_label(label)
|
|
96
|
+
return label if label.ascii_only?
|
|
97
|
+
|
|
98
|
+
codepoints = label.codepoints
|
|
99
|
+
output = codepoints.select { |codepoint| codepoint < 0x80 }.map(&:chr).join
|
|
100
|
+
basic_length = output.length
|
|
101
|
+
output << '-' if basic_length > 0
|
|
102
|
+
|
|
103
|
+
handled = basic_length
|
|
104
|
+
n = 128
|
|
105
|
+
delta = 0
|
|
106
|
+
bias = 72
|
|
107
|
+
while handled < codepoints.length
|
|
108
|
+
next_codepoint = codepoints.select { |codepoint| codepoint >= n }.min
|
|
109
|
+
delta += (next_codepoint - n) * (handled + 1)
|
|
110
|
+
n = next_codepoint
|
|
111
|
+
|
|
112
|
+
codepoints.each do |codepoint|
|
|
113
|
+
delta += 1 if codepoint < n
|
|
114
|
+
next unless codepoint == n
|
|
115
|
+
|
|
116
|
+
q = delta
|
|
117
|
+
k = 36
|
|
118
|
+
loop do
|
|
119
|
+
threshold = if k <= bias
|
|
120
|
+
1
|
|
121
|
+
elsif k >= bias + 26
|
|
122
|
+
26
|
|
123
|
+
else
|
|
124
|
+
k - bias
|
|
125
|
+
end
|
|
126
|
+
break if q < threshold
|
|
127
|
+
|
|
128
|
+
output << punycode_digit(threshold + ((q - threshold) % (36 - threshold)))
|
|
129
|
+
q = (q - threshold) / (36 - threshold)
|
|
130
|
+
k += 36
|
|
131
|
+
end
|
|
132
|
+
output << punycode_digit(q)
|
|
133
|
+
bias = adapt_punycode_bias(delta, handled + 1, handled == basic_length)
|
|
134
|
+
delta = 0
|
|
135
|
+
handled += 1
|
|
136
|
+
end
|
|
137
|
+
delta += 1
|
|
138
|
+
n += 1
|
|
139
|
+
end
|
|
140
|
+
"xn--#{output}"
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
private def punycode_digit(value)
|
|
144
|
+
value < 26 ? (value + 97).chr : (value - 26 + 48).chr
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
private def adapt_punycode_bias(delta, points, first_time)
|
|
148
|
+
delta = first_time ? delta / 700 : delta / 2
|
|
149
|
+
delta += delta / points
|
|
150
|
+
k = 0
|
|
151
|
+
while delta > 455
|
|
152
|
+
delta /= 35
|
|
153
|
+
k += 36
|
|
154
|
+
end
|
|
155
|
+
k + ((36 * delta) / (delta + 38))
|
|
156
|
+
end
|
|
157
|
+
|
|
42
158
|
private def validate_glob_pattern
|
|
43
159
|
in_group = false
|
|
44
160
|
escaped = false
|
data/lib/playwright/version.rb
CHANGED
data/lib/playwright/waiter.rb
CHANGED
|
@@ -12,33 +12,14 @@ module Playwright
|
|
|
12
12
|
@registered_listeners = Set.new
|
|
13
13
|
@listeners_mutex = Mutex.new
|
|
14
14
|
@logs = []
|
|
15
|
-
|
|
15
|
+
send_wait_info(waitId: @wait_id, phase: 'before', event: @event)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
private def
|
|
19
|
-
@channel.async_send_message_to_server(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"waitId": @wait_id,
|
|
24
|
-
"phase": "before",
|
|
25
|
-
"event": @event,
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
private def wait_for_event_info_after(error: nil)
|
|
32
|
-
@channel.async_send_message_to_server(
|
|
33
|
-
"waitForEventInfo",
|
|
34
|
-
{
|
|
35
|
-
"info": {
|
|
36
|
-
"waitId": @wait_id,
|
|
37
|
-
"phase": "after",
|
|
38
|
-
"error": error,
|
|
39
|
-
}.compact,
|
|
40
|
-
},
|
|
41
|
-
)
|
|
18
|
+
private def send_wait_info(params)
|
|
19
|
+
@channel.async_send_message_to_server('__waitInfo__', params.compact)
|
|
20
|
+
rescue
|
|
21
|
+
# Fire-and-forget. The server intentionally does not reply and this must
|
|
22
|
+
# not affect the API call that is being waited for.
|
|
42
23
|
end
|
|
43
24
|
|
|
44
25
|
def reject_on_event(emitter, event, error_or_proc, predicate: nil)
|
|
@@ -89,7 +70,7 @@ module Playwright
|
|
|
89
70
|
cleanup
|
|
90
71
|
return if @result.resolved?
|
|
91
72
|
@result.fulfill(result)
|
|
92
|
-
|
|
73
|
+
send_wait_info(waitId: @wait_id, phase: 'after')
|
|
93
74
|
end
|
|
94
75
|
|
|
95
76
|
private def reject(error)
|
|
@@ -98,7 +79,7 @@ module Playwright
|
|
|
98
79
|
klass = error.is_a?(TimeoutError) ? TimeoutError : Error
|
|
99
80
|
ex = klass.new(message: "#{error.message}#{format_log_recording(@logs)}")
|
|
100
81
|
@result.reject(ex)
|
|
101
|
-
|
|
82
|
+
send_wait_info(waitId: @wait_id, phase: 'after', error: ex.message)
|
|
102
83
|
end
|
|
103
84
|
|
|
104
85
|
# @param [Playwright::EventEmitter]
|
|
@@ -135,20 +116,7 @@ module Playwright
|
|
|
135
116
|
|
|
136
117
|
def log(message)
|
|
137
118
|
@logs << message
|
|
138
|
-
|
|
139
|
-
@channel.async_send_message_to_server(
|
|
140
|
-
"waitForEventInfo",
|
|
141
|
-
{
|
|
142
|
-
"info": {
|
|
143
|
-
"waitId": @wait_id,
|
|
144
|
-
"phase": "log",
|
|
145
|
-
"message": message,
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
)
|
|
149
|
-
rescue => err
|
|
150
|
-
# ignore
|
|
151
|
-
end
|
|
119
|
+
send_wait_info(waitId: @wait_id, phase: 'log', message: message)
|
|
152
120
|
end
|
|
153
121
|
|
|
154
122
|
# @param logs [Array<String>]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Playwright
|
|
2
|
+
# ref: https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/client/webStorage.ts
|
|
3
|
+
define_api_implementation :WebStorageImpl do
|
|
4
|
+
# @param page [ChannelOwners::Page]
|
|
5
|
+
# @param kind [String] 'local' or 'session'
|
|
6
|
+
def initialize(page, kind)
|
|
7
|
+
@page = page
|
|
8
|
+
@kind = kind
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def items
|
|
12
|
+
@page.channel.send_message_to_server('webStorageItems', kind: @kind)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def get_item(name)
|
|
16
|
+
@page.channel.send_message_to_server('webStorageGetItem', kind: @kind, name: name)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def set_item(name, value)
|
|
20
|
+
@page.channel.send_message_to_server('webStorageSetItem', kind: @kind, name: name, value: value)
|
|
21
|
+
nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def remove_item(name)
|
|
25
|
+
@page.channel.send_message_to_server('webStorageRemoveItem', kind: @kind, name: name)
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def clear
|
|
30
|
+
@page.channel.send_message_to_server('webStorageClear', kind: @kind)
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/playwright.rb
CHANGED
|
@@ -138,7 +138,7 @@ module Playwright
|
|
|
138
138
|
end
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
-
# Connects to Playwright server, launched by `
|
|
141
|
+
# Connects to Playwright server, launched by `playwright-core launch-server --browser chromium` or `playwright-core run-server`
|
|
142
142
|
#
|
|
143
143
|
# Playwright.connect_to_browser_server('ws://....') do |browser|
|
|
144
144
|
# page = browser.new_page
|
|
@@ -186,7 +186,7 @@ module Playwright
|
|
|
186
186
|
end
|
|
187
187
|
end
|
|
188
188
|
|
|
189
|
-
# Connects to Playwright server, launched by `
|
|
189
|
+
# Connects to Playwright server, launched by `playwright-core launch-server --browser _android` or `playwright._android.launchServer()`
|
|
190
190
|
#
|
|
191
191
|
# Playwright.connect_to_android_server('ws://....') do |browser|
|
|
192
192
|
# page = browser.new_page
|
|
@@ -292,20 +292,20 @@ module Playwright
|
|
|
292
292
|
|
|
293
293
|
# -- inherited from EventEmitter --
|
|
294
294
|
# @nodoc
|
|
295
|
-
def
|
|
296
|
-
event_emitter_proxy.
|
|
295
|
+
def once(event, callback)
|
|
296
|
+
event_emitter_proxy.once(event, callback)
|
|
297
297
|
end
|
|
298
298
|
|
|
299
299
|
# -- inherited from EventEmitter --
|
|
300
300
|
# @nodoc
|
|
301
|
-
def
|
|
302
|
-
event_emitter_proxy.
|
|
301
|
+
def on(event, callback)
|
|
302
|
+
event_emitter_proxy.on(event, callback)
|
|
303
303
|
end
|
|
304
304
|
|
|
305
305
|
# -- inherited from EventEmitter --
|
|
306
306
|
# @nodoc
|
|
307
|
-
def
|
|
308
|
-
event_emitter_proxy.
|
|
307
|
+
def off(event, callback)
|
|
308
|
+
event_emitter_proxy.off(event, callback)
|
|
309
309
|
end
|
|
310
310
|
|
|
311
311
|
private def event_emitter_proxy
|
|
@@ -55,6 +55,18 @@ module Playwright
|
|
|
55
55
|
wrap_impl(@impl.ok)
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
+
#
|
|
59
|
+
# Returns SSL and other security information. Resolves to `null` for non-HTTPS responses. For redirected requests, returns the information for the last request in the redirect chain.
|
|
60
|
+
def security_details
|
|
61
|
+
wrap_impl(@impl.security_details)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# Returns the IP address and port of the server. Resolves to `null` if the server address is not available. For redirected requests, returns the information for the last request in the redirect chain.
|
|
66
|
+
def server_addr
|
|
67
|
+
wrap_impl(@impl.server_addr)
|
|
68
|
+
end
|
|
69
|
+
|
|
58
70
|
#
|
|
59
71
|
# Contains the status code of the response (e.g., 200 for a success).
|
|
60
72
|
def status
|
|
@@ -73,6 +85,15 @@ module Playwright
|
|
|
73
85
|
wrap_impl(@impl.text)
|
|
74
86
|
end
|
|
75
87
|
|
|
88
|
+
#
|
|
89
|
+
# Returns resource timing information for given response. For redirected requests, returns the information for the last
|
|
90
|
+
# request in the redirect chain. When the response is served [from the HAR file](../mock.md#replaying-from-har), timing
|
|
91
|
+
# information is not available and all the values are -1. Find more information at
|
|
92
|
+
# [Resource Timing API](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming).
|
|
93
|
+
def timing
|
|
94
|
+
wrap_impl(@impl.timing)
|
|
95
|
+
end
|
|
96
|
+
|
|
76
97
|
#
|
|
77
98
|
# Contains the URL of the response.
|
|
78
99
|
def url
|
|
@@ -217,20 +217,20 @@ module Playwright
|
|
|
217
217
|
|
|
218
218
|
# -- inherited from EventEmitter --
|
|
219
219
|
# @nodoc
|
|
220
|
-
def
|
|
221
|
-
event_emitter_proxy.
|
|
220
|
+
def once(event, callback)
|
|
221
|
+
event_emitter_proxy.once(event, callback)
|
|
222
222
|
end
|
|
223
223
|
|
|
224
224
|
# -- inherited from EventEmitter --
|
|
225
225
|
# @nodoc
|
|
226
|
-
def
|
|
227
|
-
event_emitter_proxy.
|
|
226
|
+
def on(event, callback)
|
|
227
|
+
event_emitter_proxy.on(event, callback)
|
|
228
228
|
end
|
|
229
229
|
|
|
230
230
|
# -- inherited from EventEmitter --
|
|
231
231
|
# @nodoc
|
|
232
|
-
def
|
|
233
|
-
event_emitter_proxy.
|
|
232
|
+
def off(event, callback)
|
|
233
|
+
event_emitter_proxy.off(event, callback)
|
|
234
234
|
end
|
|
235
235
|
|
|
236
236
|
private def event_emitter_proxy
|