playwright-ruby-client 0.7.1 → 1.14.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -0
  3. data/documentation/docs/api/accessibility.md +52 -1
  4. data/documentation/docs/api/browser.md +8 -2
  5. data/documentation/docs/api/browser_context.md +28 -0
  6. data/documentation/docs/api/browser_type.md +1 -0
  7. data/documentation/docs/api/download.md +97 -0
  8. data/documentation/docs/api/element_handle.md +38 -4
  9. data/documentation/docs/api/experimental/android_device.md +1 -0
  10. data/documentation/docs/api/frame.md +89 -17
  11. data/documentation/docs/api/keyboard.md +11 -20
  12. data/documentation/docs/api/locator.md +650 -0
  13. data/documentation/docs/api/page.md +135 -19
  14. data/documentation/docs/api/response.md +16 -0
  15. data/documentation/docs/api/touchscreen.md +8 -0
  16. data/documentation/docs/api/worker.md +37 -0
  17. data/documentation/docs/article/guides/inspector.md +31 -0
  18. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +91 -0
  19. data/documentation/docs/article/guides/semi_automation.md +5 -1
  20. data/documentation/docs/include/api_coverage.md +77 -14
  21. data/lib/playwright.rb +36 -4
  22. data/lib/playwright/accessibility_impl.rb +50 -0
  23. data/lib/playwright/channel_owners/artifact.rb +4 -0
  24. data/lib/playwright/channel_owners/browser_context.rb +77 -3
  25. data/lib/playwright/channel_owners/element_handle.rb +11 -4
  26. data/lib/playwright/channel_owners/frame.rb +107 -34
  27. data/lib/playwright/channel_owners/page.rb +163 -55
  28. data/lib/playwright/channel_owners/response.rb +8 -0
  29. data/lib/playwright/channel_owners/worker.rb +23 -0
  30. data/lib/playwright/connection.rb +2 -4
  31. data/lib/playwright/{download.rb → download_impl.rb} +5 -1
  32. data/lib/playwright/javascript/expression.rb +5 -4
  33. data/lib/playwright/locator_impl.rb +314 -0
  34. data/lib/playwright/route_handler_entry.rb +3 -2
  35. data/lib/playwright/timeout_settings.rb +4 -4
  36. data/lib/playwright/touchscreen_impl.rb +7 -0
  37. data/lib/playwright/transport.rb +0 -1
  38. data/lib/playwright/url_matcher.rb +12 -2
  39. data/lib/playwright/version.rb +2 -2
  40. data/lib/playwright/web_socket_client.rb +164 -0
  41. data/lib/playwright/web_socket_transport.rb +104 -0
  42. data/lib/playwright_api/accessibility.rb +1 -1
  43. data/lib/playwright_api/android_device.rb +6 -5
  44. data/lib/playwright_api/browser.rb +10 -4
  45. data/lib/playwright_api/browser_context.rb +12 -7
  46. data/lib/playwright_api/browser_type.rb +2 -1
  47. data/lib/playwright_api/cdp_session.rb +6 -6
  48. data/lib/playwright_api/download.rb +70 -0
  49. data/lib/playwright_api/element_handle.rb +38 -18
  50. data/lib/playwright_api/frame.rb +95 -44
  51. data/lib/playwright_api/locator.rb +509 -0
  52. data/lib/playwright_api/page.rb +102 -49
  53. data/lib/playwright_api/response.rb +10 -0
  54. data/lib/playwright_api/touchscreen.rb +1 -1
  55. data/lib/playwright_api/worker.rb +13 -3
  56. metadata +17 -7
@@ -44,6 +44,14 @@ module Playwright
44
44
  end.to_h
45
45
  end
46
46
 
47
+ def server_addr
48
+ @channel.send_message_to_server('serverAddr')
49
+ end
50
+
51
+ def security_details
52
+ @channel.send_message_to_server('securityDetails')
53
+ end
54
+
47
55
  def finished
48
56
  @channel.send_message_to_server('finished')
49
57
  end
@@ -1,4 +1,27 @@
1
1
  module Playwright
2
2
  define_channel_owner :Worker do
3
+ attr_writer :context, :page
4
+
5
+ private def after_initialize
6
+ @channel.once('close', ->(_) { on_close })
7
+ end
8
+
9
+ private def on_close
10
+ @page&.send(:remove_worker, self)
11
+ @context&.send(:remove_service_worker, self)
12
+ emit(Events::Worker::Close, self)
13
+ end
14
+
15
+ def url
16
+ @initializer['url']
17
+ end
18
+
19
+ def evaluate(expression, arg: nil)
20
+ JavaScript::Expression.new(expression, arg).evaluate(@channel)
21
+ end
22
+
23
+ def evaluate_handle(expression, arg: nil)
24
+ JavaScript::Expression.new(expression, arg).evaluate_handle(@channel)
25
+ end
3
26
  end
4
27
  end
@@ -5,10 +5,8 @@ module Playwright
5
5
  # https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_connection.py
6
6
  # https://github.com/microsoft/playwright-java/blob/master/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java
7
7
  class Connection
8
- def initialize(playwright_cli_executable_path:)
9
- @transport = Transport.new(
10
- playwright_cli_executable_path: playwright_cli_executable_path
11
- )
8
+ def initialize(transport)
9
+ @transport = transport
12
10
  @transport.on_message_received do |message|
13
11
  dispatch(message)
14
12
  end
@@ -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,5 +24,9 @@ module Playwright
24
24
  def save_as(path)
25
25
  @artifact.save_as(path)
26
26
  end
27
+
28
+ def cancel
29
+ @artifact.cancel
30
+ end
27
31
  end
28
32
  end
@@ -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=first",
146
+ )
147
+ end
148
+
149
+ def last
150
+ LocatorImpl.new(
151
+ frame: @frame,
152
+ timeout_settings: @timeout_settings,
153
+ selector: "#{@selector} >> _nth=last",
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
@@ -1,10 +1,11 @@
1
1
  module Playwright
2
2
  class RouteHandlerEntry
3
3
  # @param url [String]
4
+ # @param base_url [String|nil]
4
5
  # @param handler [Proc]
5
- def initialize(url, handler)
6
+ def initialize(url, base_url, handler)
6
7
  @url_value = url
7
- @url_matcher = UrlMatcher.new(url)
8
+ @url_matcher = UrlMatcher.new(url, base_url: base_url)
8
9
  @handler = handler
9
10
  end
10
11
 
@@ -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