playwright-ruby-client 1.16.0 → 1.18.beta1

Sign up to get free protection for your applications and to get access to all the features.
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'])