playwright-ruby-client 1.26.0 → 1.28.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/api_request_context.md +86 -0
- data/documentation/docs/api/browser_context.md +3 -3
- data/documentation/docs/api/download.md +1 -1
- data/documentation/docs/api/element_handle.md +2 -1
- data/documentation/docs/api/file_chooser.md +1 -1
- data/documentation/docs/api/frame.md +151 -4
- data/documentation/docs/api/frame_locator.md +151 -4
- data/documentation/docs/api/js_handle.md +5 -3
- data/documentation/docs/api/keyboard.md +1 -1
- data/documentation/docs/api/locator.md +191 -6
- data/documentation/docs/api/page.md +166 -9
- data/documentation/docs/api/request.md +1 -1
- data/documentation/docs/api/tracing.md +1 -1
- data/documentation/docs/article/guides/rails_integration.md +1 -0
- data/documentation/docs/article/guides/rails_integration_with_null_driver.md +59 -0
- data/documentation/docs/include/api_coverage.md +32 -0
- data/lib/playwright/channel_owner.rb +41 -0
- data/lib/playwright/channel_owners/browser_context.rb +6 -0
- data/lib/playwright/channel_owners/element_handle.rb +8 -1
- data/lib/playwright/channel_owners/frame.rb +6 -0
- data/lib/playwright/channel_owners/page.rb +25 -28
- data/lib/playwright/channel_owners/selectors.rb +4 -0
- data/lib/playwright/connection.rb +4 -1
- data/lib/playwright/frame_locator_impl.rb +6 -2
- data/lib/playwright/locator_impl.rb +21 -31
- data/lib/playwright/locator_utils.rb +136 -0
- data/lib/playwright/utils.rb +6 -0
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright_api/android.rb +12 -6
- data/lib/playwright_api/android_device.rb +6 -6
- data/lib/playwright_api/api_request_context.rb +86 -8
- 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/download.rb +1 -1
- data/lib/playwright_api/element_handle.rb +9 -8
- data/lib/playwright_api/file_chooser.rb +1 -1
- data/lib/playwright_api/frame.rb +119 -11
- data/lib/playwright_api/frame_locator.rb +113 -5
- data/lib/playwright_api/js_handle.rb +7 -7
- data/lib/playwright_api/keyboard.rb +1 -1
- data/lib/playwright_api/locator.rb +145 -6
- data/lib/playwright_api/page.rb +133 -16
- data/lib/playwright_api/playwright.rb +6 -6
- data/lib/playwright_api/request.rb +9 -9
- data/lib/playwright_api/response.rb +8 -8
- data/lib/playwright_api/route.rb +6 -6
- data/lib/playwright_api/selectors.rb +14 -3
- data/lib/playwright_api/tracing.rb +7 -7
- data/lib/playwright_api/web_socket.rb +6 -6
- data/lib/playwright_api/worker.rb +8 -8
- metadata +5 -4
@@ -36,6 +36,7 @@ module Playwright
|
|
36
36
|
@type = type
|
37
37
|
@guid = guid
|
38
38
|
@initializer = initializer
|
39
|
+
@event_to_subscription_mapping = {}
|
39
40
|
|
40
41
|
after_initialize
|
41
42
|
end
|
@@ -59,6 +60,46 @@ module Playwright
|
|
59
60
|
@objects.clear
|
60
61
|
end
|
61
62
|
|
63
|
+
private def set_event_to_subscription_mapping(event_to_subscription_mapping)
|
64
|
+
@event_to_subscription_mapping = event_to_subscription_mapping
|
65
|
+
end
|
66
|
+
|
67
|
+
private def update_subscription(event, enabled)
|
68
|
+
protocol_event = @event_to_subscription_mapping[event]
|
69
|
+
if protocol_event
|
70
|
+
payload = {
|
71
|
+
event: protocol_event,
|
72
|
+
enabled: enabled,
|
73
|
+
}
|
74
|
+
@channel.async_send_message_to_server('updateSubscription', payload)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# @override
|
79
|
+
def on(event, callback)
|
80
|
+
if listener_count(event) == 0
|
81
|
+
update_subscription(event, true)
|
82
|
+
end
|
83
|
+
super
|
84
|
+
end
|
85
|
+
|
86
|
+
# @override
|
87
|
+
def once(event, callback)
|
88
|
+
if listener_count(event) == 0
|
89
|
+
update_subscription(event, true)
|
90
|
+
end
|
91
|
+
super
|
92
|
+
end
|
93
|
+
|
94
|
+
# @override
|
95
|
+
def off(event, callback)
|
96
|
+
super
|
97
|
+
if listener_count(event) == 0
|
98
|
+
update_subscription(event, false)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
62
103
|
# Suppress long long inspect log and avoid RSpec from hanging up...
|
63
104
|
def inspect
|
64
105
|
to_s
|
@@ -58,6 +58,12 @@ module Playwright
|
|
58
58
|
ChannelOwners::Page.from_nullable(params['page']),
|
59
59
|
)
|
60
60
|
})
|
61
|
+
set_event_to_subscription_mapping({
|
62
|
+
Events::BrowserContext::Request => "request",
|
63
|
+
Events::BrowserContext::Response => "response",
|
64
|
+
Events::BrowserContext::RequestFinished => "requestFinished",
|
65
|
+
Events::BrowserContext::RequestFailed => "requestFailed",
|
66
|
+
})
|
61
67
|
|
62
68
|
@closed_promise = Concurrent::Promises.resolvable_future
|
63
69
|
end
|
@@ -76,10 +76,17 @@ module Playwright
|
|
76
76
|
nil
|
77
77
|
end
|
78
78
|
|
79
|
-
def hover(
|
79
|
+
def hover(
|
80
|
+
force: nil,
|
81
|
+
modifiers: nil,
|
82
|
+
noWaitAfter: nil,
|
83
|
+
position: nil,
|
84
|
+
timeout: nil,
|
85
|
+
trial: nil)
|
80
86
|
params = {
|
81
87
|
force: force,
|
82
88
|
modifiers: modifiers,
|
89
|
+
noWaitAfter: noWaitAfter,
|
83
90
|
position: position,
|
84
91
|
timeout: timeout,
|
85
92
|
trial: trial,
|
@@ -1,6 +1,10 @@
|
|
1
|
+
require_relative '../locator_utils'
|
2
|
+
|
1
3
|
module Playwright
|
2
4
|
# @ref https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_frame.py
|
3
5
|
define_channel_owner :Frame do
|
6
|
+
include LocatorUtils
|
7
|
+
|
4
8
|
private def after_initialize
|
5
9
|
if @initializer['parentFrame']
|
6
10
|
@parent_frame = ChannelOwners::Frame.from(@initializer['parentFrame'])
|
@@ -457,6 +461,7 @@ module Playwright
|
|
457
461
|
selector,
|
458
462
|
force: nil,
|
459
463
|
modifiers: nil,
|
464
|
+
noWaitAfter: nil,
|
460
465
|
position: nil,
|
461
466
|
strict: nil,
|
462
467
|
timeout: nil,
|
@@ -465,6 +470,7 @@ module Playwright
|
|
465
470
|
selector: selector,
|
466
471
|
force: force,
|
467
472
|
modifiers: modifiers,
|
473
|
+
noWaitAfter: noWaitAfter,
|
468
474
|
position: position,
|
469
475
|
strict: strict,
|
470
476
|
timeout: timeout,
|
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'base64'
|
2
|
+
require_relative '../locator_utils'
|
2
3
|
|
3
4
|
module Playwright
|
4
5
|
# @ref https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_page.py
|
5
6
|
define_channel_owner :Page do
|
6
7
|
include Utils::Errors::SafeCloseError
|
8
|
+
include LocatorUtils
|
7
9
|
attr_writer :owned_context
|
8
10
|
|
11
|
+
|
9
12
|
private def after_initialize
|
10
13
|
@browser_context = @parent
|
11
14
|
@timeout_settings = TimeoutSettings.new(@browser_context.send(:_timeout_settings))
|
@@ -71,6 +74,14 @@ module Playwright
|
|
71
74
|
worker = ChannelOwners::Worker.from(params['worker'])
|
72
75
|
on_worker(worker)
|
73
76
|
})
|
77
|
+
|
78
|
+
set_event_to_subscription_mapping({
|
79
|
+
Events::Page::Request => "request",
|
80
|
+
Events::Page::Response => "response",
|
81
|
+
Events::Page::RequestFinished => "requestFinished",
|
82
|
+
Events::Page::RequestFailed => "requestFailed",
|
83
|
+
Events::Page::FileChooser => "fileChooser",
|
84
|
+
})
|
74
85
|
end
|
75
86
|
|
76
87
|
attr_reader \
|
@@ -167,30 +178,6 @@ module Playwright
|
|
167
178
|
video.send(:set_artifact, artifact)
|
168
179
|
end
|
169
180
|
|
170
|
-
# @override
|
171
|
-
def on(event, callback)
|
172
|
-
if event == Events::Page::FileChooser && listener_count(event) == 0
|
173
|
-
@channel.async_send_message_to_server('setFileChooserInterceptedNoReply', intercepted: true)
|
174
|
-
end
|
175
|
-
super
|
176
|
-
end
|
177
|
-
|
178
|
-
# @override
|
179
|
-
def once(event, callback)
|
180
|
-
if event == Events::Page::FileChooser && listener_count(event) == 0
|
181
|
-
@channel.async_send_message_to_server('setFileChooserInterceptedNoReply', intercepted: true)
|
182
|
-
end
|
183
|
-
super
|
184
|
-
end
|
185
|
-
|
186
|
-
# @override
|
187
|
-
def off(event, callback)
|
188
|
-
super
|
189
|
-
if event == Events::Page::FileChooser && listener_count(event) == 0
|
190
|
-
@channel.async_send_message_to_server('setFileChooserInterceptedNoReply', intercepted: false)
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
181
|
def context
|
195
182
|
@browser_context
|
196
183
|
end
|
@@ -364,16 +351,24 @@ module Playwright
|
|
364
351
|
|
365
352
|
def emulate_media(colorScheme: nil, forcedColors: nil, media: nil, reducedMotion: nil)
|
366
353
|
params = {
|
367
|
-
colorScheme: colorScheme,
|
368
|
-
forcedColors: forcedColors,
|
369
|
-
media: media,
|
370
|
-
reducedMotion: reducedMotion,
|
354
|
+
colorScheme: no_override_if_null(colorScheme),
|
355
|
+
forcedColors: no_override_if_null(forcedColors),
|
356
|
+
media: no_override_if_null(media),
|
357
|
+
reducedMotion: no_override_if_null(reducedMotion),
|
371
358
|
}.compact
|
372
359
|
@channel.send_message_to_server('emulateMedia', params)
|
373
360
|
|
374
361
|
nil
|
375
362
|
end
|
376
363
|
|
364
|
+
private def no_override_if_null(target)
|
365
|
+
if target == 'null'
|
366
|
+
'no-override'
|
367
|
+
else
|
368
|
+
target
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
377
372
|
def set_viewport_size(viewportSize)
|
378
373
|
@viewport_size = viewportSize
|
379
374
|
@channel.send_message_to_server('setViewportSize', { viewportSize: viewportSize })
|
@@ -635,6 +630,7 @@ module Playwright
|
|
635
630
|
selector,
|
636
631
|
force: nil,
|
637
632
|
modifiers: nil,
|
633
|
+
noWaitAfter: nil,
|
638
634
|
position: nil,
|
639
635
|
strict: nil,
|
640
636
|
timeout: nil,
|
@@ -643,6 +639,7 @@ module Playwright
|
|
643
639
|
selector,
|
644
640
|
force: force,
|
645
641
|
modifiers: modifiers,
|
642
|
+
noWaitAfter: noWaitAfter,
|
646
643
|
position: position,
|
647
644
|
strict: strict,
|
648
645
|
timeout: timeout,
|
@@ -43,7 +43,10 @@ module Playwright
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def initialize_playwright
|
46
|
-
|
46
|
+
# Avoid Error: sdkLanguage: expected one of (javascript|python|java|csharp)
|
47
|
+
# ref: https://github.com/microsoft/playwright/pull/18308
|
48
|
+
# ref: https://github.com/YusukeIwaki/playwright-ruby-client/issues/228
|
49
|
+
result = send_message_to_server('', 'initialize', { sdkLanguage: 'python' })
|
47
50
|
ChannelOwners::Playwright.from(result['playwright'])
|
48
51
|
end
|
49
52
|
|
@@ -1,5 +1,9 @@
|
|
1
|
+
require_relative './locator_utils'
|
2
|
+
|
1
3
|
module Playwright
|
2
4
|
define_api_implementation :FrameLocatorImpl do
|
5
|
+
include LocatorUtils
|
6
|
+
|
3
7
|
def initialize(frame:, timeout_settings:, frame_selector:)
|
4
8
|
@frame = frame
|
5
9
|
@timeout_settings = timeout_settings
|
@@ -10,7 +14,7 @@ module Playwright
|
|
10
14
|
LocatorImpl.new(
|
11
15
|
frame: @frame,
|
12
16
|
timeout_settings: @timeout_settings,
|
13
|
-
selector: "#{@frame_selector} >> control=enter-frame >> #{selector}",
|
17
|
+
selector: "#{@frame_selector} >> internal:control=enter-frame >> #{selector}",
|
14
18
|
hasText: hasText,
|
15
19
|
has: has,
|
16
20
|
)
|
@@ -20,7 +24,7 @@ module Playwright
|
|
20
24
|
FrameLocatorImpl.new(
|
21
25
|
frame: @frame,
|
22
26
|
timeout_settings: @timeout_settings,
|
23
|
-
frame_selector: "#{@frame_selector} >> control=enter-frame >> #{selector}",
|
27
|
+
frame_selector: "#{@frame_selector} >> internal:control=enter-frame >> #{selector}",
|
24
28
|
)
|
25
29
|
end
|
26
30
|
|
@@ -1,49 +1,24 @@
|
|
1
1
|
require 'json'
|
2
|
+
require_relative './locator_utils'
|
2
3
|
|
3
4
|
module Playwright
|
4
|
-
class EscapeWithQuotes
|
5
|
-
def initialize(text, char = "'")
|
6
|
-
stringified = text.to_json
|
7
|
-
escaped_text = stringified[1...-1].gsub(/\\"/, '"')
|
8
|
-
|
9
|
-
case char
|
10
|
-
when '"'
|
11
|
-
text = escaped_text.gsub(/["]/, '\\"')
|
12
|
-
@text = "\"#{text}\""
|
13
|
-
when "'"
|
14
|
-
text = escaped_text.gsub(/[']/, '\\\'')
|
15
|
-
@text = "'#{text}'"
|
16
|
-
else
|
17
|
-
raise ArgumentError.new('Invalid escape char')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def to_s
|
22
|
-
@text
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
5
|
define_api_implementation :LocatorImpl do
|
6
|
+
include LocatorUtils
|
7
|
+
|
27
8
|
def initialize(frame:, timeout_settings:, selector:, hasText: nil, has: nil)
|
28
9
|
@frame = frame
|
29
10
|
@timeout_settings = timeout_settings
|
30
11
|
selector_scopes = [selector]
|
31
12
|
|
32
|
-
|
33
|
-
|
34
|
-
regex = JavaScript::Regex.new(hasText)
|
35
|
-
source = EscapeWithQuotes.new(regex.source, '"')
|
36
|
-
selector_scopes << "has=#{"text=/#{regex.source}/#{regex.flag}".to_json}"
|
37
|
-
when String
|
38
|
-
text = EscapeWithQuotes.new(hasText, '"')
|
39
|
-
selector_scopes << ":scope:has-text(#{text})"
|
13
|
+
if hasText
|
14
|
+
selector_scopes << "internal:has-text=#{escape_for_text_selector(hasText, false)}"
|
40
15
|
end
|
41
16
|
|
42
17
|
if has
|
43
18
|
unless same_frame?(has)
|
44
19
|
raise DifferentFrameError.new
|
45
20
|
end
|
46
|
-
selector_scopes << "has=#{has.send(:selector_json)}"
|
21
|
+
selector_scopes << "internal:has=#{has.send(:selector_json)}"
|
47
22
|
end
|
48
23
|
|
49
24
|
@selector = selector_scopes.join(' >> ')
|
@@ -211,6 +186,10 @@ module Playwright
|
|
211
186
|
@frame.fill(@selector, value, strict: true, force: force, noWaitAfter: noWaitAfter, timeout: timeout)
|
212
187
|
end
|
213
188
|
|
189
|
+
def clear(force: nil, noWaitAfter: nil, timeout: nil)
|
190
|
+
@frame.fill(@selector, '', strict: true, force: force, noWaitAfter: noWaitAfter, timeout: timeout)
|
191
|
+
end
|
192
|
+
|
214
193
|
def locator(selector, hasText: nil, has: nil)
|
215
194
|
LocatorImpl.new(
|
216
195
|
frame: @frame,
|
@@ -275,6 +254,15 @@ module Playwright
|
|
275
254
|
@frame.focus(@selector, strict: true, timeout: timeout)
|
276
255
|
end
|
277
256
|
|
257
|
+
def blur(timeout: nil)
|
258
|
+
params = {
|
259
|
+
selector: @selector,
|
260
|
+
strict: true,
|
261
|
+
timeout: timeout,
|
262
|
+
}.compact
|
263
|
+
@frame.channel.send_message_to_server('blur', params)
|
264
|
+
end
|
265
|
+
|
278
266
|
def count
|
279
267
|
@frame.eval_on_selector_all(@selector, 'ee => ee.length')
|
280
268
|
end
|
@@ -286,6 +274,7 @@ module Playwright
|
|
286
274
|
def hover(
|
287
275
|
force: nil,
|
288
276
|
modifiers: nil,
|
277
|
+
noWaitAfter: nil,
|
289
278
|
position: nil,
|
290
279
|
timeout: nil,
|
291
280
|
trial: nil)
|
@@ -293,6 +282,7 @@ module Playwright
|
|
293
282
|
strict: true,
|
294
283
|
force: force,
|
295
284
|
modifiers: modifiers,
|
285
|
+
noWaitAfter: noWaitAfter,
|
296
286
|
position: position,
|
297
287
|
timeout: timeout,
|
298
288
|
trial: trial)
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Playwright
|
4
|
+
module LocatorUtils
|
5
|
+
def get_by_test_id(test_id)
|
6
|
+
test_id_attribute_name = ::Playwright::LocatorUtils.instance_variable_get(:@test_id_attribute_name)
|
7
|
+
locator(get_by_test_id_selector(test_id_attribute_name, test_id))
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_by_alt_text(text, exact: false)
|
11
|
+
locator(get_by_alt_text_selector(text, exact: exact))
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_by_label(text, exact: false)
|
15
|
+
locator(get_by_label_selector(text, exact: exact))
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_by_placeholder(text, exact: false)
|
19
|
+
locator(get_by_placeholder_selector(text, exact: exact))
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_by_text(text, exact: false)
|
23
|
+
locator(get_by_text_selector(text, exact: exact))
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_by_title(text, exact: false)
|
27
|
+
locator(get_by_title_selector(text, exact: exact))
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_by_role(role, **options)
|
31
|
+
locator(get_by_role_selector(role, **(options.compact)))
|
32
|
+
end
|
33
|
+
|
34
|
+
# set from Playwright::Selectors#test_id_attribute=
|
35
|
+
@test_id_attribute_name = 'data-testid'
|
36
|
+
|
37
|
+
private def get_by_attribute_text_selector(attr_name, text, exact: false)
|
38
|
+
"internal:attr=[#{attr_name}=#{escape_for_attribute_selector_or_regex(text, exact)}]"
|
39
|
+
end
|
40
|
+
|
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(test_id, true)}]"
|
43
|
+
end
|
44
|
+
|
45
|
+
private def get_by_label_selector(text, exact:)
|
46
|
+
"internal:label=#{escape_for_text_selector(text, exact)}"
|
47
|
+
end
|
48
|
+
|
49
|
+
private def get_by_alt_text_selector(text, exact:)
|
50
|
+
get_by_attribute_text_selector('alt', text, exact: exact)
|
51
|
+
end
|
52
|
+
|
53
|
+
private def get_by_title_selector(text, exact:)
|
54
|
+
get_by_attribute_text_selector('title', text, exact: exact)
|
55
|
+
end
|
56
|
+
|
57
|
+
private def get_by_placeholder_selector(text, exact:)
|
58
|
+
get_by_attribute_text_selector('placeholder', text, exact: exact)
|
59
|
+
end
|
60
|
+
|
61
|
+
private def get_by_text_selector(text, exact:)
|
62
|
+
"internal:text=#{escape_for_text_selector(text, exact)}"
|
63
|
+
end
|
64
|
+
|
65
|
+
private def get_by_role_selector(role, **options)
|
66
|
+
props = []
|
67
|
+
|
68
|
+
ex = {
|
69
|
+
includeHidden: -> (value) { ['include-hidden', value.to_s] },
|
70
|
+
name: -> (value) { ['name', escape_for_attribute_selector_or_regex(value, options[:exact])]},
|
71
|
+
}
|
72
|
+
|
73
|
+
%i[
|
74
|
+
checked
|
75
|
+
disabled
|
76
|
+
selected
|
77
|
+
expanded
|
78
|
+
includeHidden
|
79
|
+
level
|
80
|
+
name
|
81
|
+
pressed
|
82
|
+
].each do |attr_name|
|
83
|
+
if options.key?(attr_name)
|
84
|
+
attr_value = options[attr_name]
|
85
|
+
props << (ex[attr_name]&.call(attr_value) || [attr_name, attr_value.to_s])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
opts = props.map { |k, v| "[#{k}=#{v}]"}.join('')
|
90
|
+
"internal:role=#{role}#{opts}"
|
91
|
+
end
|
92
|
+
|
93
|
+
# @param text [String]
|
94
|
+
private def escape_for_regex(text)
|
95
|
+
text.gsub(/[.*+?^>${}()|\[\]\\]/) { "\\#{$&}" }
|
96
|
+
end
|
97
|
+
|
98
|
+
# @param text [Regexp|String]
|
99
|
+
private def escape_for_text_selector(text, exact)
|
100
|
+
if text.is_a?(Regexp)
|
101
|
+
regex = JavaScript::Regex.new(text)
|
102
|
+
return "/#{regex.source}/#{regex.flag}"
|
103
|
+
end
|
104
|
+
|
105
|
+
if exact
|
106
|
+
"#{text.to_json}s"
|
107
|
+
else
|
108
|
+
"#{text.to_json}i"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# @param text [Regexp|String]
|
113
|
+
private def escape_for_attribute_selector_or_regex(text, exact)
|
114
|
+
if text.is_a?(Regexp)
|
115
|
+
regex = JavaScript::Regex.new(text)
|
116
|
+
"/#{regex.source}/#{regex.flag}"
|
117
|
+
else
|
118
|
+
escape_for_attribute_selector(text, exact)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# @param text [String]
|
123
|
+
private def escape_for_attribute_selector(text, exact)
|
124
|
+
# TODO: this should actually be
|
125
|
+
# cssEscape(value).replace(/\\ /g, ' ')
|
126
|
+
# However, our attribute selectors do not conform to CSS parsing spec,
|
127
|
+
# so we escape them differently.
|
128
|
+
_text = text.gsub(/["]/, '\\"')
|
129
|
+
if exact
|
130
|
+
"\"#{_text}\""
|
131
|
+
else
|
132
|
+
"\"#{_text}\"i"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/lib/playwright/utils.rb
CHANGED
@@ -55,6 +55,12 @@ module Playwright
|
|
55
55
|
params[:storageState] = JSON.parse(File.read(params[:storageState]))
|
56
56
|
end
|
57
57
|
|
58
|
+
%i[colorScheme reducedMotion forcedColors].each do |key|
|
59
|
+
if params[key] == 'null'
|
60
|
+
params[key] = 'no-override'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
58
64
|
params
|
59
65
|
end
|
60
66
|
end
|
data/lib/playwright/version.rb
CHANGED
@@ -25,6 +25,12 @@ module Playwright
|
|
25
25
|
# ```
|
26
26
|
class Android < PlaywrightApi
|
27
27
|
|
28
|
+
# This methods attaches Playwright to an existing Android device. Use [`method: Android.launchServer`] to launch a new
|
29
|
+
# Android server instance.
|
30
|
+
def connect(wsEndpoint, headers: nil, slowMo: nil, timeout: nil)
|
31
|
+
raise NotImplementedError.new('connect is not implemented yet.')
|
32
|
+
end
|
33
|
+
|
28
34
|
# Returns the list of detected Android devices.
|
29
35
|
def devices(host: nil, omitDriverInstall: nil, port: nil)
|
30
36
|
wrap_impl(@impl.devices(host: unwrap_impl(host), omitDriverInstall: unwrap_impl(omitDriverInstall), port: unwrap_impl(port)))
|
@@ -36,12 +42,6 @@ module Playwright
|
|
36
42
|
end
|
37
43
|
alias_method :default_timeout=, :set_default_timeout
|
38
44
|
|
39
|
-
# -- inherited from EventEmitter --
|
40
|
-
# @nodoc
|
41
|
-
def off(event, callback)
|
42
|
-
event_emitter_proxy.off(event, callback)
|
43
|
-
end
|
44
|
-
|
45
45
|
# -- inherited from EventEmitter --
|
46
46
|
# @nodoc
|
47
47
|
def once(event, callback)
|
@@ -54,6 +54,12 @@ module Playwright
|
|
54
54
|
event_emitter_proxy.on(event, callback)
|
55
55
|
end
|
56
56
|
|
57
|
+
# -- inherited from EventEmitter --
|
58
|
+
# @nodoc
|
59
|
+
def off(event, callback)
|
60
|
+
event_emitter_proxy.off(event, callback)
|
61
|
+
end
|
62
|
+
|
57
63
|
private def event_emitter_proxy
|
58
64
|
@event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
|
59
65
|
end
|
@@ -173,12 +173,6 @@ module Playwright
|
|
173
173
|
wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
|
174
174
|
end
|
175
175
|
|
176
|
-
# -- inherited from EventEmitter --
|
177
|
-
# @nodoc
|
178
|
-
def off(event, callback)
|
179
|
-
event_emitter_proxy.off(event, callback)
|
180
|
-
end
|
181
|
-
|
182
176
|
# -- inherited from EventEmitter --
|
183
177
|
# @nodoc
|
184
178
|
def once(event, callback)
|
@@ -191,6 +185,12 @@ module Playwright
|
|
191
185
|
event_emitter_proxy.on(event, callback)
|
192
186
|
end
|
193
187
|
|
188
|
+
# -- inherited from EventEmitter --
|
189
|
+
# @nodoc
|
190
|
+
def off(event, callback)
|
191
|
+
event_emitter_proxy.off(event, callback)
|
192
|
+
end
|
193
|
+
|
194
194
|
private def event_emitter_proxy
|
195
195
|
@event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
|
196
196
|
end
|