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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/accessibility.md +51 -1
  3. data/documentation/docs/api/browser_context.md +28 -0
  4. data/documentation/docs/api/download.md +97 -0
  5. data/documentation/docs/api/element_handle.md +28 -3
  6. data/documentation/docs/api/experimental/android.md +15 -2
  7. data/documentation/docs/api/frame.md +116 -114
  8. data/documentation/docs/api/locator.md +650 -0
  9. data/documentation/docs/api/mouse.md +3 -4
  10. data/documentation/docs/api/page.md +109 -19
  11. data/documentation/docs/api/request.md +15 -19
  12. data/documentation/docs/api/touchscreen.md +8 -0
  13. data/documentation/docs/api/tracing.md +13 -12
  14. data/documentation/docs/api/worker.md +37 -0
  15. data/documentation/docs/article/guides/inspector.md +31 -0
  16. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +1 -1
  17. data/documentation/docs/article/guides/semi_automation.md +1 -1
  18. data/documentation/docs/include/api_coverage.md +70 -14
  19. data/lib/playwright.rb +0 -1
  20. data/lib/playwright/accessibility_impl.rb +50 -0
  21. data/lib/playwright/channel_owners/browser_context.rb +70 -0
  22. data/lib/playwright/channel_owners/frame.rb +79 -33
  23. data/lib/playwright/channel_owners/page.rb +133 -42
  24. data/lib/playwright/channel_owners/request.rb +8 -8
  25. data/lib/playwright/channel_owners/worker.rb +23 -0
  26. data/lib/playwright/{download.rb → download_impl.rb} +1 -1
  27. data/lib/playwright/javascript/expression.rb +5 -4
  28. data/lib/playwright/locator_impl.rb +314 -0
  29. data/lib/playwright/timeout_settings.rb +4 -4
  30. data/lib/playwright/touchscreen_impl.rb +7 -0
  31. data/lib/playwright/tracing_impl.rb +9 -8
  32. data/lib/playwright/version.rb +2 -2
  33. data/lib/playwright_api/accessibility.rb +1 -1
  34. data/lib/playwright_api/android.rb +21 -8
  35. data/lib/playwright_api/android_device.rb +6 -6
  36. data/lib/playwright_api/browser.rb +6 -6
  37. data/lib/playwright_api/browser_context.rb +16 -11
  38. data/lib/playwright_api/browser_type.rb +6 -6
  39. data/lib/playwright_api/cdp_session.rb +6 -6
  40. data/lib/playwright_api/console_message.rb +6 -6
  41. data/lib/playwright_api/dialog.rb +6 -6
  42. data/lib/playwright_api/download.rb +70 -0
  43. data/lib/playwright_api/element_handle.rb +34 -20
  44. data/lib/playwright_api/frame.rb +85 -53
  45. data/lib/playwright_api/js_handle.rb +6 -6
  46. data/lib/playwright_api/locator.rb +509 -0
  47. data/lib/playwright_api/page.rb +91 -57
  48. data/lib/playwright_api/playwright.rb +6 -6
  49. data/lib/playwright_api/request.rb +6 -6
  50. data/lib/playwright_api/response.rb +6 -6
  51. data/lib/playwright_api/route.rb +6 -6
  52. data/lib/playwright_api/selectors.rb +6 -6
  53. data/lib/playwright_api/touchscreen.rb +1 -1
  54. data/lib/playwright_api/web_socket.rb +6 -6
  55. data/lib/playwright_api/worker.rb +16 -6
  56. metadata +13 -6
@@ -1,5 +1,5 @@
1
1
  module Playwright
2
- class Download
2
+ define_api_implementation :DownloadImpl do
3
3
  def initialize(page:, url:, suggested_filename:, artifact:)
4
4
  @page = page
5
5
  @url = url
@@ -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
- value = channel.send_message_to_server(
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
@@ -3,5 +3,12 @@ module Playwright
3
3
  def initialize(channel)
4
4
  @channel = channel
5
5
  end
6
+
7
+ def tap_point(x, y)
8
+ @channel.send_message_to_server('touchscreenTap', {
9
+ x: x,
10
+ y: y,
11
+ })
12
+ end
6
13
  end
7
14
  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
- if path
22
- resp = @channel.send_message_to_server('tracingExport')
23
- artifact = ChannelOwners::Artifact.from(resp)
24
- # if self._context._browser:
25
- # artifact._is_remote = self._context._browser._is_remote
26
- artifact.save_as(path)
27
- artifact.delete
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playwright
4
- VERSION = '0.8.1'
5
- COMPATIBLE_PLAYWRIGHT_VERSION = '1.13.0'
4
+ VERSION = '1.14.beta3'
5
+ COMPATIBLE_PLAYWRIGHT_VERSION = '1.14.0'
6
6
  end
@@ -44,7 +44,7 @@ module Playwright
44
44
  # print(node["name"])
45
45
  # ```
46
46
  def snapshot(interestingOnly: nil, root: nil)
47
- raise NotImplementedError.new('snapshot is not implemented yet.')
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. See [here](./mobile.md) for more information. You can
3
- # access android namespace via:
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