playwright-ruby-client 1.26.0 → 1.28.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_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
|