playwright-ruby-client 1.16.0 → 1.17.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/api_request.md +7 -0
  3. data/documentation/docs/api/api_request_context.md +137 -0
  4. data/documentation/docs/api/api_response.md +90 -0
  5. data/documentation/docs/api/browser_context.md +4 -0
  6. data/documentation/docs/api/element_handle.md +2 -3
  7. data/documentation/docs/api/frame.md +30 -0
  8. data/documentation/docs/api/frame_locator.md +70 -0
  9. data/documentation/docs/api/locator.md +17 -2
  10. data/documentation/docs/api/page.md +33 -3
  11. data/documentation/docs/api/request.md +3 -3
  12. data/documentation/docs/api/selectors.md +1 -1
  13. data/documentation/docs/api/tracing.md +2 -2
  14. data/documentation/docs/include/api_coverage.md +42 -12
  15. data/lib/playwright/api_response_impl.rb +73 -0
  16. data/lib/playwright/channel.rb +1 -1
  17. data/lib/playwright/channel_owners/api_request_context.rb +232 -0
  18. data/lib/playwright/channel_owners/artifact.rb +1 -6
  19. data/lib/playwright/channel_owners/browser.rb +6 -8
  20. data/lib/playwright/channel_owners/browser_context.rb +3 -4
  21. data/lib/playwright/channel_owners/browser_type.rb +0 -1
  22. data/lib/playwright/channel_owners/fetch_request.rb +2 -0
  23. data/lib/playwright/channel_owners/frame.rb +10 -6
  24. data/lib/playwright/channel_owners/page.rb +17 -10
  25. data/lib/playwright/connection.rb +9 -0
  26. data/lib/playwright/frame_locator_impl.rb +49 -0
  27. data/lib/playwright/locator_impl.rb +13 -5
  28. data/lib/playwright/tracing_impl.rb +6 -9
  29. data/lib/playwright/version.rb +2 -2
  30. data/lib/playwright/video.rb +3 -0
  31. data/lib/playwright.rb +2 -1
  32. data/lib/playwright_api/android_device.rb +4 -4
  33. data/lib/playwright_api/api_request.rb +18 -0
  34. data/lib/playwright_api/api_request_context.rb +11 -8
  35. data/lib/playwright_api/api_response.rb +68 -0
  36. data/lib/playwright_api/browser_context.rb +10 -5
  37. data/lib/playwright_api/element_handle.rb +2 -3
  38. data/lib/playwright_api/frame.rb +26 -1
  39. data/lib/playwright_api/frame_locator.rb +51 -0
  40. data/lib/playwright_api/locator.rb +12 -2
  41. data/lib/playwright_api/page.rb +34 -4
  42. data/lib/playwright_api/playwright.rb +9 -4
  43. data/lib/playwright_api/selectors.rb +2 -2
  44. data/lib/playwright_api/tracing.rb +4 -4
  45. data/playwright.gemspec +1 -1
  46. metadata +14 -6
data/lib/playwright.rb CHANGED
@@ -135,13 +135,14 @@ module Playwright
135
135
 
136
136
  transport = WebSocketTransport.new(ws_endpoint: ws_endpoint)
137
137
  connection = Connection.new(transport)
138
+ connection.mark_as_remote
138
139
  connection.async_run
139
140
 
140
141
  execution =
141
142
  begin
142
143
  playwright = connection.initialize_playwright
143
144
  browser = playwright.send(:pre_launched_browser)
144
- browser.send(:update_as_remote)
145
+ browser.should_close_connection_on_close!
145
146
  Execution.new(connection, PlaywrightApi.wrap(playwright), PlaywrightApi.wrap(browser))
146
147
  rescue
147
148
  connection.stop
@@ -165,13 +165,13 @@ module Playwright
165
165
  end
166
166
 
167
167
  # @nodoc
168
- def tree
169
- wrap_impl(@impl.tree)
168
+ def tap_on(selector, duration: nil, timeout: nil)
169
+ wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
170
170
  end
171
171
 
172
172
  # @nodoc
173
- def tap_on(selector, duration: nil, timeout: nil)
174
- wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
173
+ def tree
174
+ wrap_impl(@impl.tree)
175
175
  end
176
176
 
177
177
  # -- inherited from EventEmitter --
@@ -0,0 +1,18 @@
1
+ module Playwright
2
+ # Exposes API that can be used for the Web API testing.
3
+ class APIRequest < PlaywrightApi
4
+
5
+ # Creates new instances of `APIRequestContext`.
6
+ def new_context(
7
+ baseURL: nil,
8
+ extraHTTPHeaders: nil,
9
+ httpCredentials: nil,
10
+ ignoreHTTPSErrors: nil,
11
+ proxy: nil,
12
+ storageState: nil,
13
+ timeout: nil,
14
+ userAgent: nil)
15
+ raise NotImplementedError.new('new_context is not implemented yet.')
16
+ end
17
+ end
18
+ end
@@ -10,19 +10,22 @@ module Playwright
10
10
  # method will automatically follow redirects.
11
11
  def delete(
12
12
  url,
13
+ data: nil,
13
14
  failOnStatusCode: nil,
15
+ form: nil,
14
16
  headers: nil,
15
17
  ignoreHTTPSErrors: nil,
18
+ multipart: nil,
16
19
  params: nil,
17
20
  timeout: nil)
18
- raise NotImplementedError.new('delete is not implemented yet.')
21
+ wrap_impl(@impl.delete(unwrap_impl(url), data: unwrap_impl(data), failOnStatusCode: unwrap_impl(failOnStatusCode), form: unwrap_impl(form), headers: unwrap_impl(headers), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), multipart: unwrap_impl(multipart), params: unwrap_impl(params), timeout: unwrap_impl(timeout)))
19
22
  end
20
23
 
21
24
  # All responses returned by [`method: APIRequestContext.get`] and similar methods are stored in the memory, so that you
22
25
  # can later call [`method: APIResponse.body`]. This method discards all stored responses, and makes
23
26
  # [`method: APIResponse.body`] throw "Response disposed" error.
24
27
  def dispose
25
- raise NotImplementedError.new('dispose is not implemented yet.')
28
+ wrap_impl(@impl.dispose)
26
29
  end
27
30
 
28
31
  # Sends HTTP(S) request and returns its response. The method will populate request cookies from the context and update
@@ -38,7 +41,7 @@ module Playwright
38
41
  multipart: nil,
39
42
  params: nil,
40
43
  timeout: nil)
41
- raise NotImplementedError.new('fetch is not implemented yet.')
44
+ wrap_impl(@impl.fetch(unwrap_impl(urlOrRequest), data: unwrap_impl(data), failOnStatusCode: unwrap_impl(failOnStatusCode), form: unwrap_impl(form), headers: unwrap_impl(headers), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), method: unwrap_impl(method), multipart: unwrap_impl(multipart), params: unwrap_impl(params), timeout: unwrap_impl(timeout)))
42
45
  end
43
46
 
44
47
  # Sends HTTP(S) [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET) request and returns its response. The
@@ -51,7 +54,7 @@ module Playwright
51
54
  ignoreHTTPSErrors: nil,
52
55
  params: nil,
53
56
  timeout: nil)
54
- raise NotImplementedError.new('get is not implemented yet.')
57
+ wrap_impl(@impl.get(unwrap_impl(url), failOnStatusCode: unwrap_impl(failOnStatusCode), headers: unwrap_impl(headers), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), params: unwrap_impl(params), timeout: unwrap_impl(timeout)))
55
58
  end
56
59
 
57
60
  # Sends HTTP(S) [HEAD](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD) request and returns its response.
@@ -64,7 +67,7 @@ module Playwright
64
67
  ignoreHTTPSErrors: nil,
65
68
  params: nil,
66
69
  timeout: nil)
67
- raise NotImplementedError.new('head is not implemented yet.')
70
+ wrap_impl(@impl.head(unwrap_impl(url), failOnStatusCode: unwrap_impl(failOnStatusCode), headers: unwrap_impl(headers), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), params: unwrap_impl(params), timeout: unwrap_impl(timeout)))
68
71
  end
69
72
 
70
73
  # Sends HTTP(S) [PATCH](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH) request and returns its response.
@@ -80,7 +83,7 @@ module Playwright
80
83
  multipart: nil,
81
84
  params: nil,
82
85
  timeout: nil)
83
- raise NotImplementedError.new('patch is not implemented yet.')
86
+ wrap_impl(@impl.patch(unwrap_impl(url), data: unwrap_impl(data), failOnStatusCode: unwrap_impl(failOnStatusCode), form: unwrap_impl(form), headers: unwrap_impl(headers), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), multipart: unwrap_impl(multipart), params: unwrap_impl(params), timeout: unwrap_impl(timeout)))
84
87
  end
85
88
 
86
89
  # Sends HTTP(S) [POST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) request and returns its response.
@@ -96,7 +99,7 @@ module Playwright
96
99
  multipart: nil,
97
100
  params: nil,
98
101
  timeout: nil)
99
- raise NotImplementedError.new('post is not implemented yet.')
102
+ wrap_impl(@impl.post(unwrap_impl(url), data: unwrap_impl(data), failOnStatusCode: unwrap_impl(failOnStatusCode), form: unwrap_impl(form), headers: unwrap_impl(headers), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), multipart: unwrap_impl(multipart), params: unwrap_impl(params), timeout: unwrap_impl(timeout)))
100
103
  end
101
104
 
102
105
  # Sends HTTP(S) [PUT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT) request and returns its response. The
@@ -112,7 +115,7 @@ module Playwright
112
115
  multipart: nil,
113
116
  params: nil,
114
117
  timeout: nil)
115
- raise NotImplementedError.new('put is not implemented yet.')
118
+ wrap_impl(@impl.put(unwrap_impl(url), data: unwrap_impl(data), failOnStatusCode: unwrap_impl(failOnStatusCode), form: unwrap_impl(form), headers: unwrap_impl(headers), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), multipart: unwrap_impl(multipart), params: unwrap_impl(params), timeout: unwrap_impl(timeout)))
116
119
  end
117
120
 
118
121
  # Returns storage state for this request context, contains current cookies and local storage snapshot if it was passed to
@@ -0,0 +1,68 @@
1
+ module Playwright
2
+ # `APIResponse` class represents responses returned by [`method: APIRequestContext.get`] and similar methods.
3
+ class APIResponse < PlaywrightApi
4
+
5
+ # Returns the buffer with response body.
6
+ def body
7
+ wrap_impl(@impl.body)
8
+ end
9
+
10
+ # Disposes the body of this response. If not called then the body will stay in memory until the context closes.
11
+ def dispose
12
+ wrap_impl(@impl.dispose)
13
+ end
14
+
15
+ # An object with all the response HTTP headers associated with this response.
16
+ def headers
17
+ wrap_impl(@impl.headers)
18
+ end
19
+
20
+ # An array with all the request HTTP headers associated with this response. Header names are not lower-cased. Headers with
21
+ # multiple entries, such as `Set-Cookie`, appear in the array multiple times.
22
+ def headers_array
23
+ wrap_impl(@impl.headers_array)
24
+ end
25
+
26
+ # Returns the JSON representation of response body.
27
+ #
28
+ # This method will throw if the response body is not parsable via `JSON.parse`.
29
+ def json
30
+ wrap_impl(@impl.json)
31
+ end
32
+
33
+ # Contains a boolean stating whether the response was successful (status in the range 200-299) or not.
34
+ def ok
35
+ wrap_impl(@impl.ok)
36
+ end
37
+
38
+ # Contains the status code of the response (e.g., 200 for a success).
39
+ def status
40
+ wrap_impl(@impl.status)
41
+ end
42
+
43
+ # Contains the status text of the response (e.g. usually an "OK" for a success).
44
+ def status_text
45
+ wrap_impl(@impl.status_text)
46
+ end
47
+
48
+ # Returns the text representation of response body.
49
+ def text
50
+ wrap_impl(@impl.text)
51
+ end
52
+
53
+ # Contains the URL of the response.
54
+ def url
55
+ wrap_impl(@impl.url)
56
+ end
57
+
58
+ # @nodoc
59
+ def ok?
60
+ wrap_impl(@impl.ok?)
61
+ end
62
+
63
+ # @nodoc
64
+ def to_s
65
+ wrap_impl(@impl.to_s)
66
+ end
67
+ end
68
+ end
@@ -20,6 +20,11 @@ module Playwright
20
20
  # ```
21
21
  class BrowserContext < PlaywrightApi
22
22
 
23
+ # API testing helper associated with this context. Requests made with this API will use context cookies.
24
+ def request # property
25
+ wrap_impl(@impl.request)
26
+ end
27
+
23
28
  def tracing # property
24
29
  wrap_impl(@impl.tracing)
25
30
  end
@@ -366,6 +371,11 @@ module Playwright
366
371
  raise NotImplementedError.new('wait_for_event is not implemented yet.')
367
372
  end
368
373
 
374
+ # @nodoc
375
+ def pause
376
+ wrap_impl(@impl.pause)
377
+ end
378
+
369
379
  # @nodoc
370
380
  def enable_debug_console!
371
381
  wrap_impl(@impl.enable_debug_console!)
@@ -381,11 +391,6 @@ module Playwright
381
391
  wrap_impl(@impl.owner_page=(unwrap_impl(req)))
382
392
  end
383
393
 
384
- # @nodoc
385
- def pause
386
- wrap_impl(@impl.pause)
387
- end
388
-
389
394
  # @nodoc
390
395
  def options=(req)
391
396
  wrap_impl(@impl.options=(unwrap_impl(req)))
@@ -6,6 +6,8 @@ module Playwright
6
6
  # ElementHandle represents an in-page DOM element. ElementHandles can be created with the [`method: Page.querySelector`]
7
7
  # method.
8
8
  #
9
+ # > NOTE: The use of ElementHandle is discouraged, use `Locator` objects and web-first assertions instead.
10
+ #
9
11
  # ```python sync
10
12
  # href_element = page.query_selector("a")
11
13
  # href_element.click()
@@ -17,9 +19,6 @@ module Playwright
17
19
  # ElementHandle instances can be used as an argument in [`method: Page.evalOnSelector`] and [`method: Page.evaluate`]
18
20
  # methods.
19
21
  #
20
- # > NOTE: In most cases, you would want to use the `Locator` object instead. You should only use `ElementHandle` if you
21
- # want to retain a handle to a particular DOM Node that you intend to pass into [`method: Page.evaluate`] as an argument.
22
- #
23
22
  # The difference between the `Locator` and ElementHandle is that the ElementHandle points to a particular element, while
24
23
  # `Locator` captures the logic of how to retrieve an element.
25
24
  #
@@ -183,6 +183,9 @@ module Playwright
183
183
 
184
184
  # Returns the return value of `expression`.
185
185
  #
186
+ # > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
187
+ # tests. Use [`method: Locator.evaluate`], other `Locator` helper methods or web-first assertions instead.
188
+ #
186
189
  # The method finds an element matching the specified selector within the frame and passes it as a first argument to
187
190
  # `expression`. See [Working with selectors](./selectors.md) for more details. If no elements match the selector, the
188
191
  # method throws an error.
@@ -203,6 +206,9 @@ module Playwright
203
206
 
204
207
  # Returns the return value of `expression`.
205
208
  #
209
+ # > NOTE: In most cases, [`method: Locator.evaluateAll`], other `Locator` helper methods and web-first assertions do a
210
+ # better job.
211
+ #
206
212
  # The method finds all elements matching the specified selector within the frame and passes an array of matched elements
207
213
  # as a first argument to `expression`. See [Working with selectors](./selectors.md) for more details.
208
214
  #
@@ -243,7 +249,7 @@ module Playwright
243
249
  # `ElementHandle` instances can be passed as an argument to the [`method: Frame.evaluate`]:
244
250
  #
245
251
  # ```python sync
246
- # body_handle = frame.query_selector("body")
252
+ # body_handle = frame.evaluate("document.body")
247
253
  # html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
248
254
  # body_handle.dispose()
249
255
  # ```
@@ -324,6 +330,18 @@ module Playwright
324
330
  wrap_impl(@impl.frame_element)
325
331
  end
326
332
 
333
+ # When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
334
+ # that iframe. Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe
335
+ # id="my-frame">`:
336
+ #
337
+ # ```python sync
338
+ # locator = frame.frame_locator("#my-iframe").locator("text=Submit")
339
+ # locator.click()
340
+ # ```
341
+ def frame_locator(selector)
342
+ wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
343
+ end
344
+
327
345
  # Returns element attribute value.
328
346
  def get_attribute(selector, name, strict: nil, timeout: nil)
329
347
  wrap_impl(@impl.get_attribute(unwrap_impl(selector), unwrap_impl(name), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
@@ -478,6 +496,8 @@ module Playwright
478
496
 
479
497
  # Returns the ElementHandle pointing to the frame element.
480
498
  #
499
+ # > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects and web-first assertions instead.
500
+ #
481
501
  # The method finds an element matching the specified selector within the frame. See
482
502
  # [Working with selectors](./selectors.md) for more details. If no elements match the selector, returns `null`.
483
503
  def query_selector(selector, strict: nil)
@@ -486,6 +506,8 @@ module Playwright
486
506
 
487
507
  # Returns the ElementHandles pointing to the frame elements.
488
508
  #
509
+ # > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects instead.
510
+ #
489
511
  # The method finds all elements matching the specified selector within the frame. See
490
512
  # [Working with selectors](./selectors.md) for more details. If no elements match the selector, returns empty array.
491
513
  def query_selector_all(selector)
@@ -714,6 +736,9 @@ module Playwright
714
736
  # Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
715
737
  # `detached`.
716
738
  #
739
+ # > NOTE: Playwright automatically waits for element to be ready before performing an action. Using `Locator` objects and
740
+ # web-first assertions make the code wait-for-selector-free.
741
+ #
717
742
  # Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
718
743
  # the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
719
744
  # selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@@ -0,0 +1,51 @@
1
+ module Playwright
2
+ # FrameLocator represents a view to the `iframe` on the page. It captures the logic sufficient to retrieve the `iframe`
3
+ # and locate elements in that iframe. FrameLocator can be created with either [`method: Page.frameLocator`] or
4
+ # [`method: Locator.frameLocator`] method.
5
+ #
6
+ # ```python sync
7
+ # locator = page.frame_locator("my-frame").locator("text=Submit")
8
+ # locator.click()
9
+ # ```
10
+ #
11
+ # **Strictness**
12
+ #
13
+ # Frame locators are strict. This means that all operations on frame locators will throw if more than one element matches
14
+ # given selector.
15
+ #
16
+ # ```python sync
17
+ # # Throws if there are several frames in DOM:
18
+ # page.frame_locator('.result-frame').locator('button').click()
19
+ #
20
+ # # Works because we explicitly tell locator to pick the first frame:
21
+ # page.frame_locator('.result-frame').first.locator('button').click()
22
+ # ```
23
+ class FrameLocator < PlaywrightApi
24
+
25
+ # Returns locator to the first matching frame.
26
+ def first
27
+ wrap_impl(@impl.first)
28
+ end
29
+
30
+ # When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
31
+ # that iframe.
32
+ def frame_locator(selector)
33
+ wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
34
+ end
35
+
36
+ # Returns locator to the last matching frame.
37
+ def last
38
+ wrap_impl(@impl.last)
39
+ end
40
+
41
+ # The method finds an element matching the specified selector in the FrameLocator's subtree.
42
+ def locator(selector)
43
+ wrap_impl(@impl.locator(unwrap_impl(selector)))
44
+ end
45
+
46
+ # Returns locator to the n-th matching frame.
47
+ def nth(index)
48
+ wrap_impl(@impl.nth(unwrap_impl(index)))
49
+ end
50
+ end
51
+ end
@@ -264,6 +264,17 @@ module Playwright
264
264
  wrap_impl(@impl.focus(timeout: unwrap_impl(timeout)))
265
265
  end
266
266
 
267
+ # When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
268
+ # that iframe:
269
+ #
270
+ # ```python sync
271
+ # locator = page.frame_locator("text=Submit").locator("text=Submit")
272
+ # locator.click()
273
+ # ```
274
+ def frame_locator(selector)
275
+ wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
276
+ end
277
+
267
278
  # Returns element attribute value.
268
279
  def get_attribute(name, timeout: nil)
269
280
  wrap_impl(@impl.get_attribute(unwrap_impl(name), timeout: unwrap_impl(timeout)))
@@ -338,8 +349,7 @@ module Playwright
338
349
  wrap_impl(@impl.last)
339
350
  end
340
351
 
341
- # The method finds an element matching the specified selector in the `Locator`'s subtree. See
342
- # [Working with selectors](./selectors.md) for more details.
352
+ # The method finds an element matching the specified selector in the `Locator`'s subtree.
343
353
  def locator(selector)
344
354
  wrap_impl(@impl.locator(unwrap_impl(selector)))
345
355
  end
@@ -288,6 +288,9 @@ module Playwright
288
288
  wrap_impl(@impl.emulate_media(colorScheme: unwrap_impl(colorScheme), forcedColors: unwrap_impl(forcedColors), media: unwrap_impl(media), reducedMotion: unwrap_impl(reducedMotion)))
289
289
  end
290
290
 
291
+ # > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
292
+ # tests. Use [`method: Locator.evaluate`], other `Locator` helper methods or web-first assertions instead.
293
+ #
291
294
  # The method finds an element matching the specified selector within the page and passes it as a first argument to
292
295
  # `expression`. If no elements match the selector, the method throws an error. Returns the value of `expression`.
293
296
  #
@@ -307,6 +310,9 @@ module Playwright
307
310
  wrap_impl(@impl.eval_on_selector(unwrap_impl(selector), unwrap_impl(expression), arg: unwrap_impl(arg), strict: unwrap_impl(strict)))
308
311
  end
309
312
 
313
+ # > NOTE: In most cases, [`method: Locator.evaluateAll`], other `Locator` helper methods and web-first assertions do a
314
+ # better job.
315
+ #
310
316
  # The method finds all elements matching the specified selector within the page and passes an array of matched elements as
311
317
  # a first argument to `expression`. Returns the result of `expression` invocation.
312
318
  #
@@ -349,7 +355,7 @@ module Playwright
349
355
  # `ElementHandle` instances can be passed as an argument to the [`method: Page.evaluate`]:
350
356
  #
351
357
  # ```python sync
352
- # body_handle = page.query_selector("body")
358
+ # body_handle = page.evaluate("document.body")
353
359
  # html = page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
354
360
  # body_handle.dispose()
355
361
  # ```
@@ -533,6 +539,18 @@ module Playwright
533
539
  wrap_impl(@impl.frame(name: unwrap_impl(name), url: unwrap_impl(url)))
534
540
  end
535
541
 
542
+ # When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
543
+ # that iframe. Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe
544
+ # id="my-frame">`:
545
+ #
546
+ # ```python sync
547
+ # locator = page.frame_locator("#my-iframe").locator("text=Submit")
548
+ # locator.click()
549
+ # ```
550
+ def frame_locator(selector)
551
+ wrap_impl(@impl.frame_locator(unwrap_impl(selector)))
552
+ end
553
+
536
554
  # An array of all frames attached to the page.
537
555
  def frames
538
556
  wrap_impl(@impl.frames)
@@ -791,14 +809,18 @@ module Playwright
791
809
  wrap_impl(@impl.press(unwrap_impl(selector), unwrap_impl(key), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), strict: unwrap_impl(strict), timeout: unwrap_impl(timeout)))
792
810
  end
793
811
 
812
+ # > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects and web-first assertions instead.
813
+ #
794
814
  # The method finds an element matching the specified selector within the page. If no elements match the selector, the
795
- # return value resolves to `null`. To wait for an element on the page, use [`method: Page.waitForSelector`].
815
+ # return value resolves to `null`. To wait for an element on the page, use [`method: Locator.waitFor`].
796
816
  #
797
817
  # Shortcut for main frame's [`method: Frame.querySelector`].
798
818
  def query_selector(selector, strict: nil)
799
819
  wrap_impl(@impl.query_selector(unwrap_impl(selector), strict: unwrap_impl(strict)))
800
820
  end
801
821
 
822
+ # > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects and web-first assertions instead.
823
+ #
802
824
  # The method finds all elements matching the specified selector within the page. If no elements match the selector, the
803
825
  # return value resolves to `[]`.
804
826
  #
@@ -807,8 +829,8 @@ module Playwright
807
829
  wrap_impl(@impl.query_selector_all(unwrap_impl(selector)))
808
830
  end
809
831
 
810
- # Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
811
- # last redirect.
832
+ # This method reloads the current page, in the same way as if the user had triggered a browser refresh. Returns the main
833
+ # resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
812
834
  def reload(timeout: nil, waitUntil: nil)
813
835
  wrap_impl(@impl.reload(timeout: unwrap_impl(timeout), waitUntil: unwrap_impl(waitUntil)))
814
836
  end
@@ -1267,6 +1289,9 @@ module Playwright
1267
1289
  # Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
1268
1290
  # `detached`.
1269
1291
  #
1292
+ # > NOTE: Playwright automatically waits for element to be ready before performing an action. Using `Locator` objects and
1293
+ # web-first assertions make the code wait-for-selector-free.
1294
+ #
1270
1295
  # Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
1271
1296
  # the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
1272
1297
  # selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@@ -1356,6 +1381,11 @@ module Playwright
1356
1381
  wrap_impl(@impl.owned_context=(unwrap_impl(req)))
1357
1382
  end
1358
1383
 
1384
+ # @nodoc
1385
+ def request
1386
+ wrap_impl(@impl.request)
1387
+ end
1388
+
1359
1389
  # @nodoc
1360
1390
  def start_js_coverage(resetOnNavigation: nil, reportAnonymousScripts: nil)
1361
1391
  wrap_impl(@impl.start_js_coverage(resetOnNavigation: unwrap_impl(resetOnNavigation), reportAnonymousScripts: unwrap_impl(reportAnonymousScripts)))
@@ -50,6 +50,11 @@ module Playwright
50
50
  wrap_impl(@impl.firefox)
51
51
  end
52
52
 
53
+ # Exposes API that can be used for the Web API testing.
54
+ def request # property
55
+ raise NotImplementedError.new('request is not implemented yet.')
56
+ end
57
+
53
58
  # Selectors can be used to install custom selector engines. See [Working with selectors](./selectors.md) for more
54
59
  # information.
55
60
  def selectors # property
@@ -82,13 +87,13 @@ module Playwright
82
87
  end
83
88
 
84
89
  # @nodoc
85
- def electron
86
- wrap_impl(@impl.electron)
90
+ def android
91
+ wrap_impl(@impl.android)
87
92
  end
88
93
 
89
94
  # @nodoc
90
- def android
91
- wrap_impl(@impl.android)
95
+ def electron
96
+ wrap_impl(@impl.electron)
92
97
  end
93
98
 
94
99
  # -- inherited from EventEmitter --
@@ -28,11 +28,11 @@ module Playwright
28
28
  # page.set_content('<div><button>Click me</button></div>')
29
29
  #
30
30
  # # Use the selector prefixed with its name.
31
- # button = page.query_selector('tag=button')
31
+ # button = page.locator('tag=button')
32
32
  # # Combine it with other selector engines.
33
33
  # page.click('tag=div >> text="Click me"')
34
34
  # # Can use it in any methods supporting selectors.
35
- # button_count = page.eval_on_selector_all('tag=button', 'buttons => buttons.length')
35
+ # button_count = page.locator('tag=button').count()
36
36
  # print(button_count)
37
37
  # browser.close()
38
38
  #
@@ -22,8 +22,8 @@ module Playwright
22
22
  # page.goto("https://playwright.dev")
23
23
  # context.tracing.stop(path = "trace.zip")
24
24
  # ```
25
- def start(name: nil, screenshots: nil, snapshots: nil)
26
- wrap_impl(@impl.start(name: unwrap_impl(name), screenshots: unwrap_impl(screenshots), snapshots: unwrap_impl(snapshots)))
25
+ def start(name: nil, screenshots: nil, snapshots: nil, title: nil)
26
+ wrap_impl(@impl.start(name: unwrap_impl(name), screenshots: unwrap_impl(screenshots), snapshots: unwrap_impl(snapshots), title: unwrap_impl(title)))
27
27
  end
28
28
 
29
29
  # Start a new trace chunk. If you'd like to record multiple traces on the same `BrowserContext`, use
@@ -45,8 +45,8 @@ module Playwright
45
45
  # # Save a second trace file with different actions.
46
46
  # context.tracing.stop_chunk(path = "trace2.zip")
47
47
  # ```
48
- def start_chunk
49
- wrap_impl(@impl.start_chunk)
48
+ def start_chunk(title: nil)
49
+ wrap_impl(@impl.start_chunk(title: unwrap_impl(title)))
50
50
  end
51
51
 
52
52
  # Stop tracing.
data/playwright.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.required_ruby_version = '>= 2.4'
28
28
  spec.add_dependency 'concurrent-ruby', '>= 1.1.6'
29
29
  spec.add_dependency 'mime-types', '>= 3.0'
30
- spec.add_development_dependency 'bundler', '~> 2.2.3'
30
+ spec.add_development_dependency 'bundler', '~> 2.3.0'
31
31
  spec.add_development_dependency 'chunky_png'
32
32
  spec.add_development_dependency 'dry-inflector'
33
33
  spec.add_development_dependency 'faye-websocket'