playwright-ruby-client 0.8.1 → 1.14.beta3
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/accessibility.md +51 -1
- data/documentation/docs/api/browser_context.md +28 -0
- data/documentation/docs/api/download.md +97 -0
- data/documentation/docs/api/element_handle.md +28 -3
- data/documentation/docs/api/experimental/android.md +15 -2
- data/documentation/docs/api/frame.md +116 -114
- data/documentation/docs/api/locator.md +650 -0
- data/documentation/docs/api/mouse.md +3 -4
- data/documentation/docs/api/page.md +109 -19
- data/documentation/docs/api/request.md +15 -19
- data/documentation/docs/api/touchscreen.md +8 -0
- data/documentation/docs/api/tracing.md +13 -12
- data/documentation/docs/api/worker.md +37 -0
- data/documentation/docs/article/guides/inspector.md +31 -0
- data/documentation/docs/article/guides/playwright_on_alpine_linux.md +1 -1
- data/documentation/docs/article/guides/semi_automation.md +1 -1
- data/documentation/docs/include/api_coverage.md +70 -14
- data/lib/playwright.rb +0 -1
- data/lib/playwright/accessibility_impl.rb +50 -0
- data/lib/playwright/channel_owners/browser_context.rb +70 -0
- data/lib/playwright/channel_owners/frame.rb +79 -33
- data/lib/playwright/channel_owners/page.rb +133 -42
- data/lib/playwright/channel_owners/request.rb +8 -8
- data/lib/playwright/channel_owners/worker.rb +23 -0
- data/lib/playwright/{download.rb → download_impl.rb} +1 -1
- data/lib/playwright/javascript/expression.rb +5 -4
- data/lib/playwright/locator_impl.rb +314 -0
- data/lib/playwright/timeout_settings.rb +4 -4
- data/lib/playwright/touchscreen_impl.rb +7 -0
- data/lib/playwright/tracing_impl.rb +9 -8
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright_api/accessibility.rb +1 -1
- data/lib/playwright_api/android.rb +21 -8
- data/lib/playwright_api/android_device.rb +6 -6
- data/lib/playwright_api/browser.rb +6 -6
- data/lib/playwright_api/browser_context.rb +16 -11
- 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 +70 -0
- data/lib/playwright_api/element_handle.rb +34 -20
- data/lib/playwright_api/frame.rb +85 -53
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/locator.rb +509 -0
- data/lib/playwright_api/page.rb +91 -57
- 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/selectors.rb +6 -6
- data/lib/playwright_api/touchscreen.rb +1 -1
- data/lib/playwright_api/web_socket.rb +6 -6
- data/lib/playwright_api/worker.rb +16 -6
- metadata +13 -6
@@ -24,13 +24,14 @@ module Playwright
|
|
24
24
|
::Playwright::ChannelOwner.from(resp)
|
25
25
|
end
|
26
26
|
|
27
|
-
def eval_on_selector(channel, selector)
|
28
|
-
|
29
|
-
'evalOnSelector',
|
27
|
+
def eval_on_selector(channel, selector, strict: nil)
|
28
|
+
params = {
|
30
29
|
selector: selector,
|
31
30
|
expression: @expression,
|
32
31
|
arg: @serialized_arg,
|
33
|
-
|
32
|
+
}
|
33
|
+
params[:strict] = strict if strict
|
34
|
+
value = channel.send_message_to_server('evalOnSelector', params)
|
34
35
|
ValueParser.new(value).parse
|
35
36
|
end
|
36
37
|
|
@@ -0,0 +1,314 @@
|
|
1
|
+
module Playwright
|
2
|
+
define_api_implementation :LocatorImpl do
|
3
|
+
def initialize(frame:, timeout_settings:, selector:)
|
4
|
+
@frame = frame
|
5
|
+
@timeout_settings = timeout_settings
|
6
|
+
@selector = selector
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
"Locator@#{@selector}"
|
11
|
+
end
|
12
|
+
|
13
|
+
private def with_element(timeout: nil, &block)
|
14
|
+
start_time = Time.now
|
15
|
+
|
16
|
+
handle = @frame.wait_for_selector(@selector, strict: true, state: 'attached', timeout: timeout)
|
17
|
+
unless handle
|
18
|
+
raise "Could not resolve #{@selector} to DOM Element"
|
19
|
+
end
|
20
|
+
|
21
|
+
call_options = {}
|
22
|
+
if timeout
|
23
|
+
call_options[:timeout] = (timeout - (Time.now - start_time) * 1000).to_i
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
block.call(handle, call_options)
|
28
|
+
ensure
|
29
|
+
handle.dispose
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def bounding_box(timeout: nil)
|
34
|
+
with_element(timeout: timeout) do |handle|
|
35
|
+
handle.bounding_box
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def check(
|
40
|
+
force: nil,
|
41
|
+
noWaitAfter: nil,
|
42
|
+
position: nil,
|
43
|
+
timeout: nil,
|
44
|
+
trial: nil)
|
45
|
+
|
46
|
+
@frame.check(@selector,
|
47
|
+
strict: true,
|
48
|
+
force: force,
|
49
|
+
noWaitAfter: noWaitAfter,
|
50
|
+
position: position,
|
51
|
+
timeout: timeout,
|
52
|
+
trial: trial)
|
53
|
+
end
|
54
|
+
|
55
|
+
def click(
|
56
|
+
button: nil,
|
57
|
+
clickCount: nil,
|
58
|
+
delay: nil,
|
59
|
+
force: nil,
|
60
|
+
modifiers: nil,
|
61
|
+
noWaitAfter: nil,
|
62
|
+
position: nil,
|
63
|
+
timeout: nil,
|
64
|
+
trial: nil)
|
65
|
+
|
66
|
+
@frame.click(@selector,
|
67
|
+
strict: true,
|
68
|
+
button: button,
|
69
|
+
clickCount: clickCount,
|
70
|
+
delay: delay,
|
71
|
+
force: force,
|
72
|
+
modifiers: modifiers,
|
73
|
+
noWaitAfter: noWaitAfter,
|
74
|
+
position: position,
|
75
|
+
timeout: timeout,
|
76
|
+
trial: trial)
|
77
|
+
end
|
78
|
+
|
79
|
+
def dblclick(
|
80
|
+
button: nil,
|
81
|
+
delay: nil,
|
82
|
+
force: nil,
|
83
|
+
modifiers: nil,
|
84
|
+
noWaitAfter: nil,
|
85
|
+
position: nil,
|
86
|
+
timeout: nil,
|
87
|
+
trial: nil)
|
88
|
+
|
89
|
+
@frame.dblclick(@selector,
|
90
|
+
strict: true,
|
91
|
+
button: button,
|
92
|
+
delay: delay,
|
93
|
+
force: force,
|
94
|
+
modifiers: modifiers,
|
95
|
+
noWaitAfter: noWaitAfter,
|
96
|
+
position: position,
|
97
|
+
timeout: timeout,
|
98
|
+
trial: trial)
|
99
|
+
end
|
100
|
+
|
101
|
+
def dispatch_event(type, eventInit: nil, timeout: nil)
|
102
|
+
@frame.dispatch_event(@selector, type, strict: true, eventInit: eventInit, timeout: timeout)
|
103
|
+
end
|
104
|
+
|
105
|
+
def evaluate(expression, arg: nil, timeout: nil)
|
106
|
+
with_element(timeout: timeout) do |handle|
|
107
|
+
handle.evaluate(expression, arg: arg)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def evaluate_all(expression, arg: nil)
|
112
|
+
@frame.eval_on_selector_all(@selector, expression, arg: arg)
|
113
|
+
end
|
114
|
+
|
115
|
+
def evaluate_handle(expression, arg: nil, timeout: nil)
|
116
|
+
with_element(timeout: timeout) do |handle|
|
117
|
+
handle.evaluate_handle(expression, arg: arg)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def fill(value, force: nil, noWaitAfter: nil, timeout: nil)
|
122
|
+
@frame.fill(@selector, value, strict: true, force: force, noWaitAfter: noWaitAfter, timeout: timeout)
|
123
|
+
end
|
124
|
+
|
125
|
+
def locator(selector)
|
126
|
+
LocatorImpl.new(
|
127
|
+
frame: @frame,
|
128
|
+
timeout_settings: @timeout_settings,
|
129
|
+
selector: "#{@selector} >> #{selector}",
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
def element_handle(timeout: nil)
|
134
|
+
@frame.wait_for_selector(@selector, strict: true, state: 'attached', timeout: timeout)
|
135
|
+
end
|
136
|
+
|
137
|
+
def element_handles
|
138
|
+
@frame.query_selector_all(@selector)
|
139
|
+
end
|
140
|
+
|
141
|
+
def first
|
142
|
+
LocatorImpl.new(
|
143
|
+
frame: @frame,
|
144
|
+
timeout_settings: @timeout_settings,
|
145
|
+
selector: "#{@selector} >> nth=0",
|
146
|
+
)
|
147
|
+
end
|
148
|
+
|
149
|
+
def last
|
150
|
+
LocatorImpl.new(
|
151
|
+
frame: @frame,
|
152
|
+
timeout_settings: @timeout_settings,
|
153
|
+
selector: "#{@selector} >> nth=-1",
|
154
|
+
)
|
155
|
+
end
|
156
|
+
|
157
|
+
def nth(index)
|
158
|
+
LocatorImpl.new(
|
159
|
+
frame: @frame,
|
160
|
+
timeout_settings: @timeout_settings,
|
161
|
+
selector: "#{@selector} >> nth=#{index}",
|
162
|
+
)
|
163
|
+
end
|
164
|
+
|
165
|
+
def focus(timeout: nil)
|
166
|
+
@frame.focus(@selector, strict: true, timeout: timeout)
|
167
|
+
end
|
168
|
+
|
169
|
+
def count
|
170
|
+
@frame.eval_on_selector_all(@selector, 'ee => ee.length')
|
171
|
+
end
|
172
|
+
|
173
|
+
def get_attribute(name, timeout: nil)
|
174
|
+
@frame.get_attribute(@selector, name, strict: true, timeout: timeout)
|
175
|
+
end
|
176
|
+
|
177
|
+
def hover(
|
178
|
+
force: nil,
|
179
|
+
modifiers: nil,
|
180
|
+
position: nil,
|
181
|
+
timeout: nil,
|
182
|
+
trial: nil)
|
183
|
+
@frame.hover(@selector,
|
184
|
+
strict: true,
|
185
|
+
force: force,
|
186
|
+
modifiers: modifiers,
|
187
|
+
position: position,
|
188
|
+
timeout: timeout,
|
189
|
+
trial: trial)
|
190
|
+
end
|
191
|
+
|
192
|
+
def inner_html(timeout: nil)
|
193
|
+
@frame.inner_html(@selector, strict: true, timeout: timeout)
|
194
|
+
end
|
195
|
+
|
196
|
+
def inner_text(timeout: nil)
|
197
|
+
@frame.inner_text(@selector, strict: true, timeout: timeout)
|
198
|
+
end
|
199
|
+
|
200
|
+
def input_value(timeout: nil)
|
201
|
+
@frame.input_value(@selector, strict: true, timeout: timeout)
|
202
|
+
end
|
203
|
+
|
204
|
+
%i[checked? disabled? editable? enabled? hidden? visible?].each do |method_name|
|
205
|
+
define_method(method_name) do |timeout: nil|
|
206
|
+
@frame.public_send(method_name, @selector, strict: true, timeout: timeout)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def press(key, delay: nil, noWaitAfter: nil, timeout: nil)
|
211
|
+
@frame.press(@selector, key, strict: true, noWaitAfter: noWaitAfter, timeout: timeout)
|
212
|
+
end
|
213
|
+
|
214
|
+
def screenshot(
|
215
|
+
omitBackground: nil,
|
216
|
+
path: nil,
|
217
|
+
quality: nil,
|
218
|
+
timeout: nil,
|
219
|
+
type: nil)
|
220
|
+
with_element(timeout: timeout) do |handle, options|
|
221
|
+
handle.screenshot(
|
222
|
+
omitBackground: omitBackground,
|
223
|
+
path: path,
|
224
|
+
quality: quality,
|
225
|
+
timeout: options[:timeout],
|
226
|
+
type: type)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def scroll_into_view_if_needed(timeout: nil)
|
231
|
+
with_element(timeout: timeout) do |handle, options|
|
232
|
+
handle.scroll_into_view_if_needed(timeout: options[:timeout])
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def select_option(
|
237
|
+
element: nil,
|
238
|
+
index: nil,
|
239
|
+
value: nil,
|
240
|
+
label: nil,
|
241
|
+
force: nil,
|
242
|
+
noWaitAfter: nil,
|
243
|
+
timeout: nil)
|
244
|
+
|
245
|
+
@frame.select_option(@selector,
|
246
|
+
strict: true,
|
247
|
+
element: element,
|
248
|
+
index: index,
|
249
|
+
value: value,
|
250
|
+
label: label,
|
251
|
+
force: force,
|
252
|
+
noWaitAfter: noWaitAfter,
|
253
|
+
timeout: timeout)
|
254
|
+
end
|
255
|
+
|
256
|
+
def select_text(force: nil, timeout: nil)
|
257
|
+
with_element(timeout: timeout) do |handle, options|
|
258
|
+
handle.select_text(force: force, timeout: options[:timeout])
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def set_input_files(files, noWaitAfter: nil, timeout: nil)
|
263
|
+
@frame.set_input_files(@selector, files, strict: true, noWaitAfter: noWaitAfter, timeout: timeout)
|
264
|
+
end
|
265
|
+
|
266
|
+
def tap_point(
|
267
|
+
force: nil,
|
268
|
+
modifiers: nil,
|
269
|
+
noWaitAfter: nil,
|
270
|
+
position: nil,
|
271
|
+
timeout: nil,
|
272
|
+
trial: nil)
|
273
|
+
@frame.tap_point(@selector,
|
274
|
+
strict: true,
|
275
|
+
force: force,
|
276
|
+
modifiers: modifiers,
|
277
|
+
noWaitAfter: noWaitAfter,
|
278
|
+
position: position,
|
279
|
+
timeout: timeout,
|
280
|
+
trial: trial)
|
281
|
+
end
|
282
|
+
|
283
|
+
def text_content(timeout: nil)
|
284
|
+
@frame.text_content(@selector, strict: true, timeout: timeout)
|
285
|
+
end
|
286
|
+
|
287
|
+
def type(text, delay: nil, noWaitAfter: nil, timeout: nil)
|
288
|
+
@frame.type(@selector, text, strict: true, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout)
|
289
|
+
end
|
290
|
+
|
291
|
+
def uncheck(
|
292
|
+
force: nil,
|
293
|
+
noWaitAfter: nil,
|
294
|
+
position: nil,
|
295
|
+
timeout: nil,
|
296
|
+
trial: nil)
|
297
|
+
@frame.uncheck(@selector,
|
298
|
+
strict: true,
|
299
|
+
force: force,
|
300
|
+
noWaitAfter: noWaitAfter,
|
301
|
+
position: position,
|
302
|
+
timeout: timeout,
|
303
|
+
trial: trial)
|
304
|
+
end
|
305
|
+
|
306
|
+
def all_inner_texts
|
307
|
+
@frame.eval_on_selector_all(@selector, 'ee => ee.map(e => e.innerText)')
|
308
|
+
end
|
309
|
+
|
310
|
+
def all_text_contents
|
311
|
+
@frame.eval_on_selector_all(@selector, "ee => ee.map(e => e.textContent || '')")
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
@@ -8,12 +8,12 @@ module Playwright
|
|
8
8
|
|
9
9
|
attr_writer :default_timeout, :default_navigation_timeout
|
10
10
|
|
11
|
-
def navigation_timeout
|
12
|
-
@default_navigation_timeout || @default_timeout || @parent&.navigation_timeout || DEFAULT_TIMEOUT
|
11
|
+
def navigation_timeout(timeout_override = nil)
|
12
|
+
timeout_override || @default_navigation_timeout || @default_timeout || @parent&.navigation_timeout || DEFAULT_TIMEOUT
|
13
13
|
end
|
14
14
|
|
15
|
-
def timeout
|
16
|
-
@default_timeout || @parent&.timeout || DEFAULT_TIMEOUT
|
15
|
+
def timeout(timeout_override = nil)
|
16
|
+
timeout_override || @default_timeout || @parent&.timeout || DEFAULT_TIMEOUT
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -16,16 +16,17 @@ module Playwright
|
|
16
16
|
|
17
17
|
# Stop tracing.
|
18
18
|
def stop(path: nil)
|
19
|
+
export(path: path) if path
|
19
20
|
@channel.send_message_to_server('tracingStop')
|
21
|
+
end
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
23
|
+
private def export(path:)
|
24
|
+
resp = @channel.send_message_to_server('tracingExport')
|
25
|
+
artifact = ChannelOwners::Artifact.from(resp)
|
26
|
+
# if self._context._browser:
|
27
|
+
# artifact._is_remote = self._context._browser._is_remote
|
28
|
+
artifact.save_as(path)
|
29
|
+
artifact.delete
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
data/lib/playwright/version.rb
CHANGED
@@ -44,7 +44,7 @@ module Playwright
|
|
44
44
|
# print(node["name"])
|
45
45
|
# ```
|
46
46
|
def snapshot(interestingOnly: nil, root: nil)
|
47
|
-
|
47
|
+
wrap_impl(@impl.snapshot(interestingOnly: unwrap_impl(interestingOnly), root: unwrap_impl(root)))
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -1,6 +1,19 @@
|
|
1
1
|
module Playwright
|
2
|
-
# Playwright has **experimental** support for Android automation.
|
3
|
-
#
|
2
|
+
# Playwright has **experimental** support for Android automation. This includes Chrome for Android and Android WebView.
|
3
|
+
#
|
4
|
+
# *Requirements*
|
5
|
+
# - Android device or AVD Emulator.
|
6
|
+
# - [ADB daemon](https://developer.android.com/studio/command-line/adb) running and authenticated with your device.
|
7
|
+
# Typically running `adb devices` is all you need to do.
|
8
|
+
# - [`Chrome 87`](https://play.google.com/store/apps/details?id=com.android.chrome) or newer installed on the device
|
9
|
+
# - "Enable command line on non-rooted devices" enabled in `chrome://flags`.
|
10
|
+
#
|
11
|
+
# *Known limitations*
|
12
|
+
# - Raw USB operation is not yet supported, so you need ADB.
|
13
|
+
# - Device needs to be awake to produce screenshots. Enabling "Stay awake" developer mode will help.
|
14
|
+
# - We didn't run all the tests against the device, so not everything works.
|
15
|
+
#
|
16
|
+
# *How to run*
|
4
17
|
#
|
5
18
|
# An example of the Android automation script would be:
|
6
19
|
#
|
@@ -23,12 +36,6 @@ module Playwright
|
|
23
36
|
end
|
24
37
|
alias_method :default_timeout=, :set_default_timeout
|
25
38
|
|
26
|
-
# -- inherited from EventEmitter --
|
27
|
-
# @nodoc
|
28
|
-
def off(event, callback)
|
29
|
-
event_emitter_proxy.off(event, callback)
|
30
|
-
end
|
31
|
-
|
32
39
|
# -- inherited from EventEmitter --
|
33
40
|
# @nodoc
|
34
41
|
def once(event, callback)
|
@@ -41,6 +48,12 @@ module Playwright
|
|
41
48
|
event_emitter_proxy.on(event, callback)
|
42
49
|
end
|
43
50
|
|
51
|
+
# -- inherited from EventEmitter --
|
52
|
+
# @nodoc
|
53
|
+
def off(event, callback)
|
54
|
+
event_emitter_proxy.off(event, callback)
|
55
|
+
end
|
56
|
+
|
44
57
|
private def event_emitter_proxy
|
45
58
|
@event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
|
46
59
|
end
|