playwright-ruby-client 1.16.0 → 1.18.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/api_request_context.md +49 -0
  3. data/documentation/docs/api/download.md +1 -3
  4. data/documentation/docs/api/element_handle.md +2 -3
  5. data/documentation/docs/api/frame.md +31 -1
  6. data/documentation/docs/api/frame_locator.md +79 -0
  7. data/documentation/docs/api/locator.md +36 -49
  8. data/documentation/docs/api/page.md +34 -4
  9. data/documentation/docs/api/request.md +3 -3
  10. data/documentation/docs/api/selectors.md +1 -1
  11. data/documentation/docs/api/tracing.md +2 -2
  12. data/documentation/docs/include/api_coverage.md +18 -0
  13. data/lib/playwright/channel.rb +1 -1
  14. data/lib/playwright/channel_owners/artifact.rb +1 -6
  15. data/lib/playwright/channel_owners/browser.rb +6 -8
  16. data/lib/playwright/channel_owners/browser_context.rb +5 -3
  17. data/lib/playwright/channel_owners/browser_type.rb +0 -1
  18. data/lib/playwright/channel_owners/fetch_request.rb +2 -0
  19. data/lib/playwright/channel_owners/frame.rb +10 -6
  20. data/lib/playwright/channel_owners/local_utils.rb +14 -0
  21. data/lib/playwright/channel_owners/page.rb +13 -10
  22. data/lib/playwright/connection.rb +9 -0
  23. data/lib/playwright/frame_locator_impl.rb +50 -0
  24. data/lib/playwright/locator_impl.rb +75 -8
  25. data/lib/playwright/tracing_impl.rb +25 -14
  26. data/lib/playwright/version.rb +2 -2
  27. data/lib/playwright/video.rb +3 -0
  28. data/lib/playwright.rb +2 -1
  29. data/lib/playwright_api/android_device.rb +4 -4
  30. data/lib/playwright_api/api_request_context.rb +50 -0
  31. data/lib/playwright_api/browser_context.rb +11 -6
  32. data/lib/playwright_api/download.rb +0 -4
  33. data/lib/playwright_api/element_handle.rb +2 -3
  34. data/lib/playwright_api/frame.rb +28 -3
  35. data/lib/playwright_api/frame_locator.rb +60 -0
  36. data/lib/playwright_api/local_utils.rb +9 -0
  37. data/lib/playwright_api/locator.rb +28 -48
  38. data/lib/playwright_api/page.rb +36 -6
  39. data/lib/playwright_api/playwright.rb +9 -4
  40. data/lib/playwright_api/selectors.rb +2 -2
  41. data/lib/playwright_api/tracing.rb +4 -4
  42. data/playwright.gemspec +1 -1
  43. metadata +13 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6230bd49d8e914d2ba9f4d23910e69fcc003f983cf51abb142d4361e1332fd6
4
- data.tar.gz: 9cf6be0bde1f294a50604f22f8be756040a02af94c61fff376354c5b1ec8d9fe
3
+ metadata.gz: 36a3c1f293b4d9a4a27ac780ebce4eb4098af2cefeba6d4e66f4ddb8c49490d7
4
+ data.tar.gz: 3520c8afc689c71a27d9af6516461cb1871a206bc6c416aee5f99742217191c8
5
5
  SHA512:
6
- metadata.gz: 97bcd9185a7ac82910dcbae93c0131cf285b9c73d881705ae9b88b01fef388b999b4001e37f866f229dba2a0cb0d81af65bee34cb4301eaf16389b927aaba334
7
- data.tar.gz: 047dd6e73800e629a439341d720df9e9281e9456f5f94eeeeaf475de7d439c5b0bf97332242497937684ae919e8b603f1b532a97cf6880f16c77f4f42d400ab2
6
+ metadata.gz: 69a7ff8c2880d9ce5bad599f102e5a0c4e710eaa25f9d5c9323cbd579cfaac6a4252eef9321a0ee453f0200fb2ac985f79f00c5ddb5717549a8d78c5f3348afe
7
+ data.tar.gz: b589f69e462f5dfba205af8ee98cb58a6bcb35b4ea6742fa8bd3f3bc26e4783e9ee7cbed2fe8dced6272c64de144465d767b00859e32f602ecb08b28b2cfc399
@@ -8,3 +8,52 @@ This API is used for the Web API testing. You can use it to trigger API endpoint
8
8
  environment or the service to your e2e test. When used on [Page](./page) or a [BrowserContext](./browser_context), this API will automatically use
9
9
  the cookies from the corresponding [BrowserContext](./browser_context). This means that if you log in using this API, your e2e test will be
10
10
  logged in and vice versa.
11
+
12
+ ```python sync title=example_6db210740dd2dcb4551c2207b3204fde7127b24c7850226b273d15c0d6624ba5.py
13
+ import os
14
+ from playwright.sync_api import sync_playwright
15
+
16
+ REPO = "test-repo-1"
17
+ USER = "github-username"
18
+ API_TOKEN = os.getenv("GITHUB_API_TOKEN")
19
+
20
+ with sync_playwright() as p:
21
+ # This will launch a new browser, create a context and page. When making HTTP
22
+ # requests with the internal APIRequestContext (e.g. `context.request` or `page.request`)
23
+ # it will automatically set the cookies to the browser page and vise versa.
24
+ browser = playwright.chromium.launch()
25
+ context = browser.new_context(base_url="https://api.github.com")
26
+ api_request_context = context.request
27
+ page = context.new_page()
28
+
29
+ # Alternatively you can create a APIRequestContext manually without having a browser context attached:
30
+ # api_request_context = playwright.request.new_context(base_url="https://api.github.com")
31
+
32
+
33
+ # Create a repository.
34
+ response = api_request_context.post(
35
+ "/user/repos",
36
+ headers={
37
+ "Accept": "application/vnd.github.v3+json",
38
+ # Add GitHub personal access token.
39
+ "Authorization": f"token {API_TOKEN}",
40
+ },
41
+ data={"name": REPO},
42
+ )
43
+ assert response.ok
44
+ assert response.json()["name"] == REPO
45
+
46
+ # Delete a repository.
47
+ response = api_request_context.delete(
48
+ f"/repos/{USER}/{REPO}",
49
+ headers={
50
+ "Accept": "application/vnd.github.v3+json",
51
+ # Add GitHub personal access token.
52
+ "Authorization": f"token {API_TOKEN}",
53
+ },
54
+ )
55
+ assert response.ok
56
+ assert await response.body() == '{"status": "ok"}'
57
+
58
+ ```
59
+
@@ -19,9 +19,7 @@ end
19
19
  path = download.path
20
20
  ```
21
21
 
22
- > NOTE: Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the
23
- downloaded content. If `acceptDownloads` is not set, download events are emitted, but the actual download is not
24
- performed and user has no access to the downloaded files.
22
+
25
23
 
26
24
  ## cancel
27
25
 
@@ -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
  ```
@@ -526,7 +549,7 @@ considered not visible.
526
549
  ## locator
527
550
 
528
551
  ```
529
- def locator(selector)
552
+ def locator(selector, hasText: nil)
530
553
  ```
531
554
 
532
555
  The method returns an element locator that can be used to perform actions in the frame. Locator is resolved to the
@@ -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,79 @@
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
+ **Converting Locator to FrameLocator**
30
+
31
+ If you have a [Locator](./locator) object pointing to an `iframe` it can be converted to [FrameLocator](./frame_locator) using
32
+ [`:scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/:scope) CSS selector:
33
+
34
+ ```ruby
35
+ frame_locator = locator.frame_locator(':scope')
36
+ ```
37
+
38
+
39
+
40
+ ## first
41
+
42
+ ```
43
+ def first
44
+ ```
45
+
46
+ Returns locator to the first matching frame.
47
+
48
+ ## frame_locator
49
+
50
+ ```
51
+ def frame_locator(selector)
52
+ ```
53
+
54
+ When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
55
+ that iframe.
56
+
57
+ ## last
58
+
59
+ ```
60
+ def last
61
+ ```
62
+
63
+ Returns locator to the last matching frame.
64
+
65
+ ## locator
66
+
67
+ ```
68
+ def locator(selector, hasText: nil)
69
+ ```
70
+
71
+ The method finds an element matching the specified selector in the FrameLocator's subtree.
72
+
73
+ ## nth
74
+
75
+ ```
76
+ def nth(index)
77
+ ```
78
+
79
+ Returns locator to the n-th matching frame.
@@ -4,53 +4,10 @@ sidebar_position: 10
4
4
 
5
5
  # Locator
6
6
 
7
- Locator represents a view to the element(s) on the page. It captures the logic sufficient to retrieve the element at any
8
- given moment. Locator can be created with the [Page#locator](./page#locator) method.
9
-
10
- ```ruby
11
- locator = page.locator("text=Submit")
12
- locator.click
13
- ```
14
-
15
- The difference between the Locator and [ElementHandle](./element_handle) is that the latter points to a particular element, while Locator
16
- captures the logic of how to retrieve that element.
17
-
18
- In the example below, handle points to a particular DOM element on page. If that element changes text or is used by
19
- React to render an entirely different component, handle is still pointing to that very DOM element. This can lead to
20
- unexpected behaviors.
21
-
22
- ```ruby
23
- handle = page.query_selector("text=Submit")
24
- handle.hover
25
- handle.click
26
- ```
27
-
28
- With the locator, every time the `element` is used, up-to-date DOM element is located in the page using the selector. So
29
- in the snippet below, underlying DOM element is going to be located twice.
30
-
31
- ```ruby
32
- locator = page.locator("text=Submit")
33
- locator.hover
34
- locator.click
35
- ```
36
-
37
- **Strictness**
38
-
39
- Locators are strict. This means that all operations on locators that imply some target DOM element will throw if more
40
- than one element matches given selector.
41
-
42
- ```ruby
43
- # Throws if there are several buttons in DOM:
44
- page.locator('button').click
45
-
46
- # Works because we explicitly tell locator to pick the first element:
47
- page.locator('button').first.click
48
-
49
- # Works because count knows what to do with multiple matches:
50
- page.locator('button').count
51
- ```
52
-
7
+ Locators are the central piece of Playwright's auto-waiting and retry-ability. In a nutshell, locators represent a way
8
+ to find element(s) on the page at any moment. Locator can be created with the [Page#locator](./page#locator) method.
53
9
 
10
+ [Learn more about locators](https://playwright.dev/python/docs/locators).
54
11
 
55
12
  ## all_inner_texts
56
13
 
@@ -220,6 +177,21 @@ element.dispatch_event("dragstart", eventInit: { dataTransfer: data_transfer })
220
177
 
221
178
 
222
179
 
180
+ ## drag_to
181
+
182
+ ```
183
+ def drag_to(
184
+ target,
185
+ force: nil,
186
+ noWaitAfter: nil,
187
+ sourcePosition: nil,
188
+ targetPosition: nil,
189
+ timeout: nil,
190
+ trial: nil)
191
+ ```
192
+
193
+
194
+
223
195
  ## element_handle
224
196
 
225
197
  ```
@@ -329,6 +301,22 @@ def focus(timeout: nil)
329
301
 
330
302
  Calls [focus](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on the element.
331
303
 
304
+ ## frame_locator
305
+
306
+ ```
307
+ def frame_locator(selector)
308
+ ```
309
+
310
+ When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in
311
+ that iframe:
312
+
313
+ ```ruby
314
+ locator = page.frame_locator("text=Submit").locator("text=Submit")
315
+ locator.click
316
+ ```
317
+
318
+
319
+
332
320
  ## get_attribute
333
321
 
334
322
  ```
@@ -442,11 +430,10 @@ Returns locator to the last matching element.
442
430
  ## locator
443
431
 
444
432
  ```
445
- def locator(selector)
433
+ def locator(selector, hasText: nil)
446
434
  ```
447
435
 
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.
436
+ The method finds an element matching the specified selector in the [Locator](./locator)'s subtree.
450
437
 
451
438
  ## nth
452
439
 
@@ -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
  ```
@@ -751,7 +774,7 @@ considered not visible.
751
774
  ## locator
752
775
 
753
776
  ```
754
- def locator(selector)
777
+ def locator(selector, hasText: nil)
755
778
  ```
756
779
 
757
780
  The method returns an element locator that can be used to perform actions on the page. Locator is resolved to the
@@ -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.
@@ -127,10 +127,10 @@ def redirected_from
127
127
  Request that was redirected by the server to this one, if any.
128
128
 
129
129
  When the server responds with a redirect, Playwright creates a new [Request](./request) object. The two requests are connected by
130
- `redirectedFrom()` and `redirectedTo()` methods. When multiple server redirects has happened, it is possible to
131
- construct the whole redirect chain by repeatedly calling `redirectedFrom()`.
130
+ [redirected_from](./request#redirected_from) and [redirected_to](./request#redirected_to) methods. When multiple server redirects has happened, it is possible to
131
+ construct the whole redirect chain by repeatedly calling [redirected_from](./request#redirected_from).
132
132
 
133
- For example, if the website `http://example.com` redirects to `https://example.com`:
133
+ For example, if the website `http://github.com` redirects to `https://github.com`:
134
134
 
135
135
  ```ruby
136
136
  response = page.goto("http://github.com")
@@ -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
@@ -329,6 +331,7 @@
329
331
  * accessibility
330
332
  * keyboard
331
333
  * mouse
334
+ * ~~request~~
332
335
  * touchscreen
333
336
 
334
337
  ## BrowserContext
@@ -359,6 +362,7 @@
359
362
  * expect_event
360
363
  * expect_page
361
364
  * ~~wait_for_event~~
365
+ * ~~request~~
362
366
  * tracing
363
367
 
364
368
  ## CDPSession
@@ -393,6 +397,7 @@
393
397
  * chromium
394
398
  * devices
395
399
  * firefox
400
+ * ~~request~~
396
401
  * selectors
397
402
  * webkit
398
403
 
@@ -413,6 +418,7 @@
413
418
  * count
414
419
  * dblclick
415
420
  * dispatch_event
421
+ * drag_to
416
422
  * element_handle
417
423
  * element_handles
418
424
  * evaluate
@@ -421,6 +427,7 @@
421
427
  * fill
422
428
  * first
423
429
  * focus
430
+ * frame_locator
424
431
  * get_attribute
425
432
  * hover
426
433
  * inner_html
@@ -448,6 +455,17 @@
448
455
  * uncheck
449
456
  * wait_for
450
457
 
458
+ ## FrameLocator
459
+
460
+ * first
461
+ * frame_locator
462
+ * last
463
+ * locator
464
+ * nth
465
+
466
+ ## LocalUtils
467
+
468
+
451
469
  ## Android
452
470
 
453
471
  * devices
@@ -71,7 +71,7 @@ module Playwright
71
71
  {
72
72
  apiName: api_name,
73
73
  stack: stacks.map do |loc|
74
- { file: loc.absolute_path, line: loc.lineno, function: loc.label }
74
+ { file: loc.absolute_path || '', line: loc.lineno, function: loc.label }
75
75
  end,
76
76
  }
77
77
  end
@@ -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
@@ -361,5 +358,10 @@ module Playwright
361
358
  private def base_url
362
359
  @options[:baseURL]
363
360
  end
361
+
362
+ # called from Tracing
363
+ private def remote_connection?
364
+ @connection.remote?
365
+ end
364
366
  end
365
367
  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'])