playwright-ruby-client 1.16.1 → 1.17.beta1

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/element_handle.md +2 -3
  3. data/documentation/docs/api/frame.md +30 -0
  4. data/documentation/docs/api/frame_locator.md +70 -0
  5. data/documentation/docs/api/locator.md +17 -2
  6. data/documentation/docs/api/page.md +33 -3
  7. data/documentation/docs/api/selectors.md +1 -1
  8. data/documentation/docs/api/tracing.md +2 -2
  9. data/documentation/docs/include/api_coverage.md +13 -0
  10. data/lib/playwright/channel_owners/artifact.rb +1 -6
  11. data/lib/playwright/channel_owners/browser.rb +6 -8
  12. data/lib/playwright/channel_owners/browser_context.rb +0 -3
  13. data/lib/playwright/channel_owners/browser_type.rb +0 -1
  14. data/lib/playwright/channel_owners/frame.rb +10 -6
  15. data/lib/playwright/channel_owners/page.rb +13 -10
  16. data/lib/playwright/connection.rb +9 -0
  17. data/lib/playwright/frame_locator_impl.rb +49 -0
  18. data/lib/playwright/locator_impl.rb +13 -5
  19. data/lib/playwright/tracing_impl.rb +6 -9
  20. data/lib/playwright/version.rb +2 -2
  21. data/lib/playwright/video.rb +3 -0
  22. data/lib/playwright.rb +2 -1
  23. data/lib/playwright_api/api_request_context.rb +3 -0
  24. data/lib/playwright_api/browser_context.rb +5 -0
  25. data/lib/playwright_api/element_handle.rb +2 -3
  26. data/lib/playwright_api/frame.rb +26 -1
  27. data/lib/playwright_api/frame_locator.rb +51 -0
  28. data/lib/playwright_api/locator.rb +12 -2
  29. data/lib/playwright_api/page.rb +33 -8
  30. data/lib/playwright_api/playwright.rb +5 -0
  31. data/lib/playwright_api/selectors.rb +2 -2
  32. data/lib/playwright_api/tracing.rb +4 -4
  33. data/lib/playwright_api/worker.rb +4 -4
  34. metadata +8 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e3d50fa44b6ed68d4c5edbcf0b96f802908beb8d0f988f13069d85e96771e11
4
- data.tar.gz: a25808094dd8a763da76c8e36ebf40041f41fa076c1231d664cdc159793a1366
3
+ metadata.gz: c2fe4b12d358a45b087eee4cdfc8aecb03b9e6df7d012158e4a04a042d290d13
4
+ data.tar.gz: ed57849806349f58419ead4e64164cafb94de892fa5d4be7cbf9f6e67867eb5d
5
5
  SHA512:
6
- metadata.gz: ba3f3f15fb496b90c1179b3ec39543d202c708098edb664dd5e43291241b435877a5004d1054f15142aba97c38ef9b6a4ed11851afe4ebe2535b6e799ba001ee
7
- data.tar.gz: '0927a665bc87db2296d8e479d8420786b12cbda7886c364bd3cb4eceeefb2d11c0ed7c2b9b6fa3779821f6440c5270ef9723062cb8b814c4fb29e02f47bc981f'
6
+ metadata.gz: b4245e2cc937bf4dd85ab98848b4a56149d796d814407598e17258f64154d85f252a3f993e13c8a81bda0f0112ffc5c1fa93e699c7fb691e3bf7592f27cd6133
7
+ data.tar.gz: 5680b2040b8ff3927b952e9f5321355137c298c697b0ba5ecde686eb89545f8b3444e191da3fe8ba22315df6fc982e452bdff73d71774419ee32a08e9a0281ef
@@ -9,6 +9,8 @@ sidebar_position: 10
9
9
  ElementHandle represents an in-page DOM element. ElementHandles can be created with the [Page#query_selector](./page#query_selector)
10
10
  method.
11
11
 
12
+ > NOTE: The use of ElementHandle is discouraged, use [Locator](./locator) objects and web-first assertions instead.
13
+
12
14
  ```ruby
13
15
  href_element = page.query_selector("a")
14
16
  href_element.click
@@ -20,9 +22,6 @@ ElementHandle prevents DOM element from garbage collection unless the handle is
20
22
  ElementHandle instances can be used as an argument in [Page#eval_on_selector](./page#eval_on_selector) and [Page#evaluate](./page#evaluate)
21
23
  methods.
22
24
 
23
- > NOTE: In most cases, you would want to use the [Locator](./locator) object instead. You should only use [ElementHandle](./element_handle) if you
24
- want to retain a handle to a particular DOM Node that you intend to pass into [Page#evaluate](./page#evaluate) as an argument.
25
-
26
25
  The difference between the [Locator](./locator) and ElementHandle is that the ElementHandle points to a particular element, while
27
26
  [Locator](./locator) captures the logic of how to retrieve an element.
28
27
 
@@ -218,6 +218,9 @@ def eval_on_selector(selector, expression, arg: nil, strict: nil)
218
218
 
219
219
  Returns the return value of `expression`.
220
220
 
221
+ > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
222
+ tests. Use [Locator#evaluate](./locator#evaluate), other [Locator](./locator) helper methods or web-first assertions instead.
223
+
221
224
  The method finds an element matching the specified selector within the frame and passes it as a first argument to
222
225
  `expression`. See [Working with selectors](https://playwright.dev/python/docs/selectors) for more details. If no elements match the selector, the
223
226
  method throws an error.
@@ -243,6 +246,9 @@ def eval_on_selector_all(selector, expression, arg: nil)
243
246
 
244
247
  Returns the return value of `expression`.
245
248
 
249
+ > NOTE: In most cases, [Locator#evaluate_all](./locator#evaluate_all), other [Locator](./locator) helper methods and web-first assertions do a
250
+ better job.
251
+
246
252
  The method finds all elements matching the specified selector within the frame and passes an array of matched elements
247
253
  as a first argument to `expression`. See [Working with selectors](https://playwright.dev/python/docs/selectors) for more details.
248
254
 
@@ -384,6 +390,23 @@ puts frame == content_frame # => true
384
390
 
385
391
 
386
392
 
393
+ ## frame_locator
394
+
395
+ ```
396
+ def frame_locator(selector)
397
+ ```
398
+
399
+ When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
400
+ that iframe. Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe
401
+ id="my-frame">`:
402
+
403
+ ```ruby
404
+ locator = frame.frame_locator("#my-iframe").locator("text=Submit")
405
+ locator.click
406
+ ```
407
+
408
+
409
+
387
410
  ## get_attribute
388
411
 
389
412
  ```
@@ -598,6 +621,8 @@ def query_selector(selector, strict: nil)
598
621
 
599
622
  Returns the ElementHandle pointing to the frame element.
600
623
 
624
+ > NOTE: The use of [ElementHandle](./element_handle) is discouraged, use [Locator](./locator) objects and web-first assertions instead.
625
+
601
626
  The method finds an element matching the specified selector within the frame. See
602
627
  [Working with selectors](https://playwright.dev/python/docs/selectors) for more details. If no elements match the selector, returns `null`.
603
628
 
@@ -609,6 +634,8 @@ def query_selector_all(selector)
609
634
 
610
635
  Returns the ElementHandles pointing to the frame elements.
611
636
 
637
+ > NOTE: The use of [ElementHandle](./element_handle) is discouraged, use [Locator](./locator) objects instead.
638
+
612
639
  The method finds all elements matching the specified selector within the frame. See
613
640
  [Working with selectors](https://playwright.dev/python/docs/selectors) for more details. If no elements match the selector, returns empty array.
614
641
 
@@ -878,6 +905,9 @@ def wait_for_selector(selector, state: nil, strict: nil, timeout: nil)
878
905
  Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
879
906
  `detached`.
880
907
 
908
+ > NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator](./locator) objects and
909
+ web-first assertions make the code wait-for-selector-free.
910
+
881
911
  Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
882
912
  the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
883
913
  selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@@ -0,0 +1,70 @@
1
+ ---
2
+ sidebar_position: 10
3
+ ---
4
+
5
+ # FrameLocator
6
+
7
+ FrameLocator represents a view to the `iframe` on the page. It captures the logic sufficient to retrieve the `iframe`
8
+ and locate elements in that iframe. FrameLocator can be created with either [Page#frame_locator](./page#frame_locator) or
9
+ [Locator#frame_locator](./locator#frame_locator) method.
10
+
11
+ ```ruby
12
+ locator = page.frame_locator("my-frame").locator("text=Submit")
13
+ locator.click
14
+ ```
15
+
16
+ **Strictness**
17
+
18
+ Frame locators are strict. This means that all operations on frame locators will throw if more than one element matches
19
+ given selector.
20
+
21
+ ```ruby
22
+ # Throws if there are several frames in DOM:
23
+ page.frame_locator('.result-frame').locator('button').click
24
+
25
+ # Works because we explicitly tell locator to pick the first frame:
26
+ page.frame_locator('.result-frame').first.locator('button').click
27
+ ```
28
+
29
+
30
+
31
+ ## first
32
+
33
+ ```
34
+ def first
35
+ ```
36
+
37
+ Returns locator to the first matching frame.
38
+
39
+ ## frame_locator
40
+
41
+ ```
42
+ def frame_locator(selector)
43
+ ```
44
+
45
+ When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
46
+ that iframe.
47
+
48
+ ## last
49
+
50
+ ```
51
+ def last
52
+ ```
53
+
54
+ Returns locator to the last matching frame.
55
+
56
+ ## locator
57
+
58
+ ```
59
+ def locator(selector)
60
+ ```
61
+
62
+ The method finds an element matching the specified selector in the FrameLocator's subtree.
63
+
64
+ ## nth
65
+
66
+ ```
67
+ def nth(index)
68
+ ```
69
+
70
+ Returns locator to the n-th matching frame.
@@ -329,6 +329,22 @@ def focus(timeout: nil)
329
329
 
330
330
  Calls [focus](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on the element.
331
331
 
332
+ ## frame_locator
333
+
334
+ ```
335
+ def frame_locator(selector)
336
+ ```
337
+
338
+ When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
339
+ that iframe:
340
+
341
+ ```ruby
342
+ locator = page.frame_locator("text=Submit").locator("text=Submit")
343
+ locator.click
344
+ ```
345
+
346
+
347
+
332
348
  ## get_attribute
333
349
 
334
350
  ```
@@ -445,8 +461,7 @@ Returns locator to the last matching element.
445
461
  def locator(selector)
446
462
  ```
447
463
 
448
- The method finds an element matching the specified selector in the [Locator](./locator)'s subtree. See
449
- [Working with selectors](https://playwright.dev/python/docs/selectors) for more details.
464
+ The method finds an element matching the specified selector in the [Locator](./locator)'s subtree.
450
465
 
451
466
  ## nth
452
467
 
@@ -315,6 +315,9 @@ page.evaluate("matchMedia('(prefers-color-scheme: no-preference)').matches") # =
315
315
  def eval_on_selector(selector, expression, arg: nil, strict: nil)
316
316
  ```
317
317
 
318
+ > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
319
+ tests. Use [Locator#evaluate](./locator#evaluate), other [Locator](./locator) helper methods or web-first assertions instead.
320
+
318
321
  The method finds an element matching the specified selector within the page and passes it as a first argument to
319
322
  `expression`. If no elements match the selector, the method throws an error. Returns the value of `expression`.
320
323
 
@@ -337,6 +340,9 @@ Shortcut for main frame's [Frame#eval_on_selector](./frame#eval_on_selector).
337
340
  def eval_on_selector_all(selector, expression, arg: nil)
338
341
  ```
339
342
 
343
+ > NOTE: In most cases, [Locator#evaluate_all](./locator#evaluate_all), other [Locator](./locator) helper methods and web-first assertions do a
344
+ better job.
345
+
340
346
  The method finds all elements matching the specified selector within the page and passes an array of matched elements as
341
347
  a first argument to `expression`. Returns the result of `expression` invocation.
342
348
 
@@ -575,6 +581,23 @@ frame = page.frame(url: /.*domain.*/)
575
581
 
576
582
 
577
583
 
584
+ ## frame_locator
585
+
586
+ ```
587
+ def frame_locator(selector)
588
+ ```
589
+
590
+ When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
591
+ that iframe. Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe
592
+ id="my-frame">`:
593
+
594
+ ```ruby
595
+ locator = page.frame_locator("#my-iframe").locator("text=Submit")
596
+ locator.click
597
+ ```
598
+
599
+
600
+
578
601
  ## frames
579
602
 
580
603
  ```
@@ -905,8 +928,10 @@ page.screenshot(path: "o.png")
905
928
  def query_selector(selector, strict: nil)
906
929
  ```
907
930
 
931
+ > NOTE: The use of [ElementHandle](./element_handle) is discouraged, use [Locator](./locator) objects and web-first assertions instead.
932
+
908
933
  The method finds an element matching the specified selector within the page. If no elements match the selector, the
909
- return value resolves to `null`. To wait for an element on the page, use [Page#wait_for_selector](./page#wait_for_selector).
934
+ return value resolves to `null`. To wait for an element on the page, use [Locator#wait_for](./locator#wait_for).
910
935
 
911
936
  Shortcut for main frame's [Frame#query_selector](./frame#query_selector).
912
937
 
@@ -916,6 +941,8 @@ Shortcut for main frame's [Frame#query_selector](./frame#query_selector).
916
941
  def query_selector_all(selector)
917
942
  ```
918
943
 
944
+ > NOTE: The use of [ElementHandle](./element_handle) is discouraged, use [Locator](./locator) objects and web-first assertions instead.
945
+
919
946
  The method finds all elements matching the specified selector within the page. If no elements match the selector, the
920
947
  return value resolves to `[]`.
921
948
 
@@ -927,8 +954,8 @@ Shortcut for main frame's [Frame#query_selector_all](./frame#query_selector_all)
927
954
  def reload(timeout: nil, waitUntil: nil)
928
955
  ```
929
956
 
930
- Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
931
- last redirect.
957
+ This method reloads the current page, in the same way as if the user had triggered a browser refresh. Returns the main
958
+ resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
932
959
 
933
960
  ## route
934
961
 
@@ -1484,6 +1511,9 @@ def wait_for_selector(selector, state: nil, strict: nil, timeout: nil)
1484
1511
  Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
1485
1512
  `detached`.
1486
1513
 
1514
+ > NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator](./locator) objects and
1515
+ web-first assertions make the code wait-for-selector-free.
1516
+
1487
1517
  Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
1488
1518
  the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
1489
1519
  selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@@ -41,7 +41,7 @@ playwright.chromium.launch do |browser|
41
41
  page.click('tag=div >> text="Click me"')
42
42
 
43
43
  # Can use it in any methods supporting selectors.
44
- button_count = page.eval_on_selector_all('tag=button', 'buttons => buttons.length')
44
+ button_count = page.locator('tag=button').count
45
45
  button_count # => 1
46
46
  end
47
47
  ```
@@ -23,7 +23,7 @@ end
23
23
  ## start
24
24
 
25
25
  ```
26
- def start(name: nil, screenshots: nil, snapshots: nil)
26
+ def start(name: nil, screenshots: nil, snapshots: nil, title: nil)
27
27
  ```
28
28
 
29
29
  Start tracing.
@@ -40,7 +40,7 @@ context.tracing.stop(path: 'trace.zip')
40
40
  ## start_chunk
41
41
 
42
42
  ```
43
- def start_chunk
43
+ def start_chunk(title: nil)
44
44
  ```
45
45
 
46
46
  Start a new trace chunk. If you'd like to record multiple traces on the same [BrowserContext](./browser_context), use
@@ -167,6 +167,7 @@
167
167
  * fill
168
168
  * focus
169
169
  * frame_element
170
+ * frame_locator
170
171
  * get_attribute
171
172
  * goto
172
173
  * hover
@@ -264,6 +265,7 @@
264
265
  * fill
265
266
  * focus
266
267
  * frame
268
+ * frame_locator
267
269
  * frames
268
270
  * get_attribute
269
271
  * go_back
@@ -359,6 +361,7 @@
359
361
  * expect_event
360
362
  * expect_page
361
363
  * ~~wait_for_event~~
364
+ * ~~request~~
362
365
  * tracing
363
366
 
364
367
  ## CDPSession
@@ -393,6 +396,7 @@
393
396
  * chromium
394
397
  * devices
395
398
  * firefox
399
+ * ~~request~~
396
400
  * selectors
397
401
  * webkit
398
402
 
@@ -421,6 +425,7 @@
421
425
  * fill
422
426
  * first
423
427
  * focus
428
+ * frame_locator
424
429
  * get_attribute
425
430
  * hover
426
431
  * inner_html
@@ -448,6 +453,14 @@
448
453
  * uncheck
449
454
  * wait_for
450
455
 
456
+ ## FrameLocator
457
+
458
+ * first
459
+ * frame_locator
460
+ * last
461
+ * locator
462
+ * nth
463
+
451
464
  ## Android
452
465
 
453
466
  * devices
@@ -1,14 +1,13 @@
1
1
  module Playwright
2
2
  define_channel_owner :Artifact do
3
3
  private def after_initialize
4
- @remote = false
5
4
  @absolute_path = @initializer['absolutePath']
6
5
  end
7
6
 
8
7
  attr_reader :absolute_path
9
8
 
10
9
  def path_after_finished
11
- if @remote
10
+ if @connection.remote?
12
11
  raise "Path is not available when using browser_type.connect(). Use save_as() to save a local copy."
13
12
  end
14
13
  @channel.send_message_to_server('pathAfterFinished')
@@ -30,9 +29,5 @@ module Playwright
30
29
  def cancel
31
30
  @channel.send_message_to_server('cancel')
32
31
  end
33
-
34
- private def update_as_remote
35
- @remote = true
36
- end
37
32
  end
38
33
  end
@@ -7,7 +7,7 @@ module Playwright
7
7
  private def after_initialize
8
8
  @connected = true
9
9
  @closed_or_closing = false
10
- @remote = false
10
+ @should_close_connection_on_close = false
11
11
 
12
12
  @contexts = Set.new
13
13
  @channel.on('close', method(:on_close))
@@ -58,6 +58,9 @@ module Playwright
58
58
  return if @closed_or_closing
59
59
  @closed_or_closing = true
60
60
  @channel.send_message_to_server('close')
61
+ if @should_close_connection_on_close
62
+ @connection.stop
63
+ end
61
64
  nil
62
65
  rescue => err
63
66
  raise unless safe_close_error?(err)
@@ -99,13 +102,8 @@ module Playwright
99
102
  @contexts << context
100
103
  end
101
104
 
102
- # called from BrowserType#connectOverCDP
103
- private def update_as_remote
104
- @remote = true
105
- end
106
-
107
- private def remote?
108
- @remote
105
+ private def should_close_connection_on_close!
106
+ @should_close_connection_on_close = true
109
107
  end
110
108
 
111
109
  # called from BrowserContext#on_close with send(:remove_context), so keep private.
@@ -276,9 +276,6 @@ module Playwright
276
276
  def close
277
277
  if @options && @options.key?(:recordHar)
278
278
  har = ChannelOwners::Artifact.from(@channel.send_message_to_server('harExport'))
279
- if @browser.send(:remote?)
280
- har.update_as_remote
281
- end
282
279
  har.save_as(@options[:recordHar][:path])
283
280
  har.delete
284
281
  end
@@ -54,7 +54,6 @@ module Playwright
54
54
 
55
55
  result = @channel.send_message_to_server_result('connectOverCDP', params)
56
56
  browser = ChannelOwners::Browser.from(result['browser'])
57
- browser.send(:update_as_remote)
58
57
 
59
58
  if result['defaultContext']
60
59
  context = ChannelOwners::BrowserContext.from(result['defaultContext'])
@@ -110,8 +110,8 @@ module Playwright
110
110
  def wait_for_load_state(state: nil, timeout: nil)
111
111
  option_state = state || 'load'
112
112
  option_timeout = timeout || @page.send(:timeout_settings).navigation_timeout
113
- unless %w(load domcontentloaded networkidle).include?(option_state)
114
- raise ArgumentError.new('state: expected one of (load|domcontentloaded|networkidle)')
113
+ unless %w(load domcontentloaded networkidle commit).include?(option_state)
114
+ raise ArgumentError.new('state: expected one of (load|domcontentloaded|networkidle|commit)')
115
115
  end
116
116
  if @load_states.include?(option_state)
117
117
  return
@@ -191,10 +191,6 @@ module Playwright
191
191
  @channel.send_message_to_server('isVisible', params)
192
192
  end
193
193
 
194
- def locator(selector)
195
- LocatorImpl.new(frame: self, timeout_settings: @page.send(:timeout_settings), selector: selector)
196
- end
197
-
198
194
  def dispatch_event(selector, type, eventInit: nil, strict: nil, timeout: nil)
199
195
  params = {
200
196
  selector: selector,
@@ -404,6 +400,14 @@ module Playwright
404
400
  nil
405
401
  end
406
402
 
403
+ def locator(selector)
404
+ LocatorImpl.new(frame: self, timeout_settings: @page.send(:timeout_settings), selector: selector)
405
+ end
406
+
407
+ def frame_locator(selector)
408
+ FrameLocatorImpl.new(frame: self, timeout_settings: @page.send(:timeout_settings), frame_selector: selector)
409
+ end
410
+
407
411
  def focus(selector, strict: nil, timeout: nil)
408
412
  params = { selector: selector, strict: strict, timeout: timeout }.compact
409
413
  @channel.send_message_to_server('focus', params)
@@ -138,9 +138,6 @@ module Playwright
138
138
 
139
139
  private def on_download(params)
140
140
  artifact = ChannelOwners::Artifact.from(params['artifact'])
141
- if @browser_context.browser.send(:remote?)
142
- artifact.update_as_remote
143
- end
144
141
  download = DownloadImpl.new(
145
142
  page: self,
146
143
  url: params['url'],
@@ -152,9 +149,6 @@ module Playwright
152
149
 
153
150
  private def on_video(params)
154
151
  artifact = ChannelOwners::Artifact.from(params['artifact'])
155
- if @browser_context.browser.send(:remote?)
156
- artifact.update_as_remote
157
- end
158
152
  video.send(:set_artifact, artifact)
159
153
  end
160
154
 
@@ -261,10 +255,6 @@ module Playwright
261
255
  @main_frame.visible?(selector, strict: strict, timeout: timeout)
262
256
  end
263
257
 
264
- def locator(selector)
265
- @main_frame.locator(selector)
266
- end
267
-
268
258
  def dispatch_event(selector, type, eventInit: nil, strict: nil, timeout: nil)
269
259
  @main_frame.dispatch_event(selector, type, eventInit: eventInit, strict: strict, timeout: timeout)
270
260
  end
@@ -568,6 +558,14 @@ module Playwright
568
558
  timeout: timeout)
569
559
  end
570
560
 
561
+ def locator(selector)
562
+ @main_frame.locator(selector)
563
+ end
564
+
565
+ def frame_locator(selector)
566
+ @main_frame.frame_locator(selector)
567
+ end
568
+
571
569
  def focus(selector, strict: nil, timeout: nil)
572
570
  @main_frame.focus(selector, strict: strict, timeout: timeout)
573
571
  end
@@ -925,6 +923,11 @@ module Playwright
925
923
  @workers.delete(worker)
926
924
  end
927
925
 
926
+ # called from Video
927
+ private def remote_connection?
928
+ @connection.remote?
929
+ end
930
+
928
931
  # Expose guid for library developers.
929
932
  # Not intended to be used by users.
930
933
  def guid
@@ -21,6 +21,15 @@ module Playwright
21
21
  @waiting_for_object = {} # Hash[ guid => Promise<ChannelOwner> ]
22
22
  @callbacks = {} # Hash [ guid => Promise<ChannelOwner> ]
23
23
  @root_object = RootChannelOwner.new(self)
24
+ @remote = false
25
+ end
26
+
27
+ def mark_as_remote
28
+ @remote = true
29
+ end
30
+
31
+ def remote?
32
+ @remote
24
33
  end
25
34
 
26
35
  def async_run
@@ -0,0 +1,49 @@
1
+ module Playwright
2
+ define_api_implementation :FrameLocatorImpl do
3
+ def initialize(frame:, timeout_settings:, frame_selector:)
4
+ @frame = frame
5
+ @timeout_settings = timeout_settings
6
+ @frame_selector = frame_selector
7
+ end
8
+
9
+ def locator(selector)
10
+ LocatorImpl.new(
11
+ frame: @frame,
12
+ timeout_settings: @timeout_settings,
13
+ selector: "#{@frame_selector} >> control=enter-frame >> #{selector}",
14
+ )
15
+ end
16
+
17
+ def frame_locator(selector)
18
+ FrameLocatorImpl.new(
19
+ frame: @frame,
20
+ timeout_settings: @timeout_settings,
21
+ frame_selector: "#{@frame_selector} >> control=enter-frame >> #{selector}",
22
+ )
23
+ end
24
+
25
+ def first
26
+ FrameLocatorImpl.new(
27
+ frame: @frame,
28
+ timeout_settings: @timeout_settings,
29
+ frame_selector: "#{@frame_selector} >> nth=0",
30
+ )
31
+ end
32
+
33
+ def last
34
+ FrameLocatorImpl.new(
35
+ frame: @frame,
36
+ timeout_settings: @timeout_settings,
37
+ frame_selector: "#{@frame_selector} >> nth=-1",
38
+ )
39
+ end
40
+
41
+ def nth(index)
42
+ FrameLocatorImpl.new(
43
+ frame: @frame,
44
+ timeout_settings: @timeout_settings,
45
+ frame_selector: "#{@frame_selector} >> nth=#{index}",
46
+ )
47
+ end
48
+ end
49
+ end
@@ -11,17 +11,17 @@ module Playwright
11
11
  end
12
12
 
13
13
  private def with_element(timeout: nil, &block)
14
+ timeout_or_default = @timeout_settings.timeout(timeout)
14
15
  start_time = Time.now
15
16
 
16
- handle = @frame.wait_for_selector(@selector, strict: true, state: 'attached', timeout: timeout)
17
+ handle = @frame.wait_for_selector(@selector, strict: true, state: 'attached', timeout: timeout_or_default)
17
18
  unless handle
18
19
  raise "Could not resolve #{@selector} to DOM Element"
19
20
  end
20
21
 
21
- call_options = {}
22
- if timeout
23
- call_options[:timeout] = (timeout - (Time.now - start_time) * 1000).to_i
24
- end
22
+ call_options = {
23
+ timeout: (timeout_or_default - (Time.now - start_time) * 1000).to_i,
24
+ }
25
25
 
26
26
  begin
27
27
  block.call(handle, call_options)
@@ -130,6 +130,14 @@ module Playwright
130
130
  )
131
131
  end
132
132
 
133
+ def frame_locator(selector)
134
+ FrameLocatorImpl.new(
135
+ frame: @frame,
136
+ timeout_settings: @timeout_settings,
137
+ frame_selector: "#{@selector} >> #{selector}",
138
+ )
139
+ end
140
+
133
141
  def element_handle(timeout: nil)
134
142
  @frame.wait_for_selector(@selector, strict: true, state: 'attached', timeout: timeout)
135
143
  end
@@ -5,18 +5,18 @@ module Playwright
5
5
  @context = context
6
6
  end
7
7
 
8
- def start(name: nil, screenshots: nil, snapshots: nil)
8
+ def start(name: nil, title: nil, screenshots: nil, snapshots: nil)
9
9
  params = {
10
10
  name: name,
11
11
  screenshots: screenshots,
12
12
  snapshots: snapshots,
13
13
  }.compact
14
14
  @channel.send_message_to_server('tracingStart', params)
15
- @channel.send_message_to_server('tracingStartChunk')
15
+ @channel.send_message_to_server('tracingStartChunk', { title: title }.compact)
16
16
  end
17
17
 
18
- def start_chunk
19
- @channel.send_message_to_server('tracingStartChunk')
18
+ def start_chunk(title: nil)
19
+ @channel.send_message_to_server('tracingStartChunk', { title: title }.compact)
20
20
  end
21
21
 
22
22
  def stop_chunk(path: nil)
@@ -29,13 +29,10 @@ module Playwright
29
29
  end
30
30
 
31
31
  private def do_stop_chunk(path:)
32
- resp = @channel.send_message_to_server('tracingStopChunk', save: !path.nil?)
33
- artifact = ChannelOwners::Artifact.from_nullable(resp)
32
+ result = @channel.send_message_to_server_result('tracingStopChunk', save: !path.nil?, skipCompress: false)
33
+ artifact = ChannelOwners::Artifact.from_nullable(result['artifact'])
34
34
  return unless artifact
35
35
 
36
- if @context.browser.send(:remote?)
37
- artifact.update_as_remote
38
- end
39
36
  artifact.save_as(path)
40
37
  artifact.delete
41
38
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playwright
4
- VERSION = '1.16.1'
5
- COMPATIBLE_PLAYWRIGHT_VERSION = '1.16.3'
4
+ VERSION = '1.17.beta1'
5
+ COMPATIBLE_PLAYWRIGHT_VERSION = '1.17.0'
6
6
  end
@@ -22,6 +22,9 @@ module Playwright
22
22
  end
23
23
 
24
24
  def path
25
+ if @page.send(:remote_connection?)
26
+ raise 'Path is not available when using browserType.connect(). Use save_as() to save a local copy.'
27
+ end
25
28
  wait_for_artifact_and do |artifact|
26
29
  artifact.absolute_path
27
30
  end
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
@@ -10,9 +10,12 @@ 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
21
  raise NotImplementedError.new('delete is not implemented yet.')
@@ -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
+ raise NotImplementedError.new('request is not implemented yet.')
26
+ end
27
+
23
28
  def tracing # property
24
29
  wrap_impl(@impl.tracing)
25
30
  end
@@ -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.
@@ -1367,13 +1392,13 @@ module Playwright
1367
1392
  end
1368
1393
 
1369
1394
  # @nodoc
1370
- def start_css_coverage(resetOnNavigation: nil, reportAnonymousScripts: nil)
1371
- wrap_impl(@impl.start_css_coverage(resetOnNavigation: unwrap_impl(resetOnNavigation), reportAnonymousScripts: unwrap_impl(reportAnonymousScripts)))
1395
+ def stop_css_coverage
1396
+ wrap_impl(@impl.stop_css_coverage)
1372
1397
  end
1373
1398
 
1374
1399
  # @nodoc
1375
- def stop_css_coverage
1376
- wrap_impl(@impl.stop_css_coverage)
1400
+ def start_css_coverage(resetOnNavigation: nil, reportAnonymousScripts: nil)
1401
+ wrap_impl(@impl.start_css_coverage(resetOnNavigation: unwrap_impl(resetOnNavigation), reportAnonymousScripts: unwrap_impl(reportAnonymousScripts)))
1377
1402
  end
1378
1403
 
1379
1404
  # @nodoc
@@ -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
@@ -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.
@@ -44,13 +44,13 @@ module Playwright
44
44
  end
45
45
 
46
46
  # @nodoc
47
- def context=(req)
48
- wrap_impl(@impl.context=(unwrap_impl(req)))
47
+ def page=(req)
48
+ wrap_impl(@impl.page=(unwrap_impl(req)))
49
49
  end
50
50
 
51
51
  # @nodoc
52
- def page=(req)
53
- wrap_impl(@impl.page=(unwrap_impl(req)))
52
+ def context=(req)
53
+ wrap_impl(@impl.context=(unwrap_impl(req)))
54
54
  end
55
55
 
56
56
  # -- inherited from EventEmitter --
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: playwright-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.1
4
+ version: 1.17.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - YusukeIwaki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-07 00:00:00.000000000 Z
11
+ date: 2021-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -227,6 +227,7 @@ files:
227
227
  - documentation/docs/api/experimental/android_web_view.md
228
228
  - documentation/docs/api/file_chooser.md
229
229
  - documentation/docs/api/frame.md
230
+ - documentation/docs/api/frame_locator.md
230
231
  - documentation/docs/api/js_handle.md
231
232
  - documentation/docs/api/keyboard.md
232
233
  - documentation/docs/api/locator.md
@@ -308,6 +309,7 @@ files:
308
309
  - lib/playwright/event_emitter_proxy.rb
309
310
  - lib/playwright/events.rb
310
311
  - lib/playwright/file_chooser_impl.rb
312
+ - lib/playwright/frame_locator_impl.rb
311
313
  - lib/playwright/http_headers.rb
312
314
  - lib/playwright/input_files.rb
313
315
  - lib/playwright/javascript.rb
@@ -349,6 +351,7 @@ files:
349
351
  - lib/playwright_api/element_handle.rb
350
352
  - lib/playwright_api/file_chooser.rb
351
353
  - lib/playwright_api/frame.rb
354
+ - lib/playwright_api/frame_locator.rb
352
355
  - lib/playwright_api/js_handle.rb
353
356
  - lib/playwright_api/keyboard.rb
354
357
  - lib/playwright_api/locator.rb
@@ -379,12 +382,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
379
382
  version: '2.4'
380
383
  required_rubygems_version: !ruby/object:Gem::Requirement
381
384
  requirements:
382
- - - ">="
385
+ - - ">"
383
386
  - !ruby/object:Gem::Version
384
- version: '0'
387
+ version: 1.3.1
385
388
  requirements: []
386
389
  rubygems_version: 3.2.22
387
390
  signing_key:
388
391
  specification_version: 4
389
- summary: The Ruby binding of playwright driver 1.16.3
392
+ summary: The Ruby binding of playwright driver 1.17.0
390
393
  test_files: []