playwright-ruby-client 1.62.0 → 1.64.0

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/api_request_context.md +50 -0
  3. data/documentation/docs/api/browser.md +2 -0
  4. data/documentation/docs/api/browser_context.md +3 -3
  5. data/documentation/docs/api/browser_type.md +1 -0
  6. data/documentation/docs/api/clock.md +1 -0
  7. data/documentation/docs/api/credentials.md +6 -3
  8. data/documentation/docs/api/frame.md +18 -2
  9. data/documentation/docs/api/frame_locator.md +20 -0
  10. data/documentation/docs/api/locator.md +66 -0
  11. data/documentation/docs/api/page.md +44 -2
  12. data/documentation/docs/api/request.md +1 -1
  13. data/documentation/docs/api/response.md +2 -1
  14. data/documentation/docs/api/tracing.md +5 -3
  15. data/documentation/docs/api/web_mcp.md +34 -0
  16. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +1 -1
  17. data/documentation/docs/include/api_coverage.md +13 -0
  18. data/lib/playwright/api_request_impl.rb +3 -1
  19. data/lib/playwright/channel.rb +2 -1
  20. data/lib/playwright/channel_owners/api_request_context.rb +16 -0
  21. data/lib/playwright/channel_owners/browser.rb +1 -0
  22. data/lib/playwright/channel_owners/browser_context.rb +21 -33
  23. data/lib/playwright/channel_owners/frame.rb +6 -5
  24. data/lib/playwright/channel_owners/local_utils.rb +5 -0
  25. data/lib/playwright/channel_owners/page.rb +12 -3
  26. data/lib/playwright/channel_owners/tracing.rb +45 -13
  27. data/lib/playwright/connection.rb +6 -2
  28. data/lib/playwright/credentials_impl.rb +2 -1
  29. data/lib/playwright/errors.rb +4 -1
  30. data/lib/playwright/events.rb +2 -0
  31. data/lib/playwright/frame_locator_impl.rb +20 -5
  32. data/lib/playwright/locator_impl.rb +26 -8
  33. data/lib/playwright/screencast.rb +4 -2
  34. data/lib/playwright/transport.rb +21 -5
  35. data/lib/playwright/utils.rb +32 -0
  36. data/lib/playwright/version.rb +2 -2
  37. data/lib/playwright/web_mcp_impl.rb +21 -0
  38. data/lib/playwright_api/api_request_context.rb +47 -7
  39. data/lib/playwright_api/browser.rb +10 -8
  40. data/lib/playwright_api/browser_context.rb +17 -17
  41. data/lib/playwright_api/browser_type.rb +8 -7
  42. data/lib/playwright_api/cdp_session.rb +6 -6
  43. data/lib/playwright_api/clock.rb +1 -0
  44. data/lib/playwright_api/credentials.rb +7 -4
  45. data/lib/playwright_api/dialog.rb +6 -6
  46. data/lib/playwright_api/element_handle.rb +6 -6
  47. data/lib/playwright_api/frame.rb +33 -16
  48. data/lib/playwright_api/frame_locator.rb +20 -0
  49. data/lib/playwright_api/js_handle.rb +6 -6
  50. data/lib/playwright_api/locator.rb +63 -3
  51. data/lib/playwright_api/page.rb +57 -17
  52. data/lib/playwright_api/playwright.rb +6 -6
  53. data/lib/playwright_api/request.rb +7 -7
  54. data/lib/playwright_api/response.rb +8 -7
  55. data/lib/playwright_api/route.rb +6 -6
  56. data/lib/playwright_api/tracing.rb +12 -10
  57. data/lib/playwright_api/web_mcp.rb +26 -0
  58. data/lib/playwright_api/web_socket.rb +6 -6
  59. data/lib/playwright_api/worker.rb +6 -6
  60. data/sig/playwright.rbs +26 -12
  61. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c78e6a1f2ee45aadb2b8a027d08a0264560172b843419e23376c80f74095ccd
4
- data.tar.gz: b31e8c1c972865e68312f65ee23a821535f14592affadcc65580b10169819b81
3
+ metadata.gz: 3d790738449c6398b19249ce438000db7f00a06a46b8db59307f2595d849781b
4
+ data.tar.gz: 7010d04e7614128ad40443dae1f3745b0588915c5af4e1d8c81c21f962b9d4c5
5
5
  SHA512:
6
- metadata.gz: de6ea998c746c0fa3107850695144b7204105c01daa6209f646c2a172bd59eb906e169b4b7ed7dca436e8084611496def05fc81bb23134d8475bedbc480d6fd5
7
- data.tar.gz: 907612d4a87117af9d0c57ada0ec4144f7451f7a75176b2b93d3cf896ff6ce8492f7e72ff8a2c04ce1d5d2871fdf9af2f967de9e5175010574d09c276b160300
6
+ metadata.gz: c1ff297b16ee61f37ece9c223280dc7ea31c1ecbe5aab4ec130348e6c0c74ca5ab86769328c2810daee6166bb4153a7a703d3bcac99472cdc43920089a60a37c
7
+ data.tar.gz: 9a899659118c9b797a368c956538496fad57df2bb6b33d282af420095eecea459a323d2f046ba61d67e6c7d0bed9cb181fdcc4d2b7e57ac1d7bd8a05f0215e71
@@ -57,6 +57,53 @@ playwright.chromium.launch do |browser|
57
57
  end
58
58
  ```
59
59
 
60
+ ## add_cookies
61
+
62
+ ```
63
+ def add_cookies(cookies)
64
+ ```
65
+
66
+
67
+ Adds cookies into this request context. They will be sent with matching subsequent requests. For [BrowserContext#request](./browser_context#request)
68
+ and [Page#request](./page#request), this is equivalent to calling [BrowserContext#add_cookies](./browser_context#add_cookies) on the corresponding browser context.
69
+
70
+ **Usage**
71
+
72
+ ```ruby
73
+ request.add_cookies([cookie_object1, cookie_object2])
74
+ ```
75
+
76
+ ## clear_cookies
77
+
78
+ ```
79
+ def clear_cookies(domain: nil, name: nil, path: nil)
80
+ ```
81
+
82
+
83
+ Removes cookies from this request context. Accepts optional filter. For [BrowserContext#request](./browser_context#request)
84
+ and [Page#request](./page#request), this is equivalent to calling [BrowserContext#clear_cookies](./browser_context#clear_cookies) on the corresponding browser context.
85
+
86
+ **Usage**
87
+
88
+ ```ruby
89
+ request.clear_cookies
90
+ request.clear_cookies(name: "session-id")
91
+ request.clear_cookies(domain: "my-origin.com")
92
+ request.clear_cookies(path: "/api/v1")
93
+ request.clear_cookies(name: "session-id", domain: "my-origin.com")
94
+ ```
95
+
96
+ ## cookies
97
+
98
+ ```
99
+ def cookies(urls: nil)
100
+ ```
101
+
102
+
103
+ If no URLs are specified, this method returns all cookies. If URLs are specified, only cookies that affect those URLs
104
+ are returned. For [BrowserContext#request](./browser_context#request) and [Page#request](./page#request), this is equivalent to calling
105
+ [BrowserContext#cookies](./browser_context#cookies) on the corresponding browser context.
106
+
60
107
  ## delete
61
108
 
62
109
  ```
@@ -298,3 +345,6 @@ The method will populate request cookies from the context and update
298
345
  context cookies from the response. The method will automatically follow redirects.
299
346
 
300
347
  ## tracing
348
+
349
+
350
+ Tracing recorder for requests made through this API request context.
@@ -113,6 +113,7 @@ def new_context(
113
113
  record_har_path: nil,
114
114
  record_har_url_filter: nil,
115
115
  record_video_dir: nil,
116
+ record_video_fps: nil,
116
117
  record_video_size: nil,
117
118
  reducedMotion: nil,
118
119
  screen: nil,
@@ -174,6 +175,7 @@ def new_page(
174
175
  record_har_path: nil,
175
176
  record_har_url_filter: nil,
176
177
  record_video_dir: nil,
178
+ record_video_fps: nil,
177
179
  record_video_size: nil,
178
180
  reducedMotion: nil,
179
181
  screen: nil,
@@ -434,11 +434,11 @@ alias: `offline=`
434
434
  ## storage_state
435
435
 
436
436
  ```
437
- def storage_state(credentials: nil, indexedDB: nil, path: nil)
437
+ def storage_state(credentials: nil, indexedDB: nil, opfs: nil, path: nil)
438
438
  ```
439
439
 
440
440
 
441
- Returns storage state for this browser context, contains current cookies, local storage snapshot, IndexedDB snapshot and virtual WebAuthn credentials.
441
+ Returns storage state for this browser context, contains current cookies, local storage snapshot, IndexedDB snapshot, origin private file system snapshot and virtual WebAuthn credentials.
442
442
 
443
443
  ## set_storage_state
444
444
 
@@ -448,7 +448,7 @@ def set_storage_state(storageState)
448
448
  alias: `storage_state=`
449
449
 
450
450
 
451
- Clears the existing cookies, local storage, IndexedDB entries and virtual WebAuthn credentials, and sets the new storage
451
+ Clears the existing cookies, local storage, IndexedDB entries, origin private file system entries and virtual WebAuthn credentials, and sets the new storage
452
452
  state. When the storage state contains credentials, the virtual WebAuthn authenticator is installed (equivalent to
453
453
  [Credentials#install](./credentials#install)), preventing all real authenticators from working in this context.
454
454
 
@@ -177,6 +177,7 @@ def launch_persistent_context(
177
177
  record_har_path: nil,
178
178
  record_har_url_filter: nil,
179
179
  record_video_dir: nil,
180
+ record_video_fps: nil,
180
181
  record_video_size: nil,
181
182
  reducedMotion: nil,
182
183
  screen: nil,
@@ -36,6 +36,7 @@ def install(time: nil)
36
36
 
37
37
  Install fake implementations for the following time-related functions:
38
38
  - `Date`
39
+ - `Temporal.Now`
39
40
  - `setTimeout`
40
41
  - `clearTimeout`
41
42
  - `setInterval`
@@ -57,6 +57,7 @@ context.credentials.create(
57
57
  userHandle: credential["userHandle"],
58
58
  privateKey: credential["privateKey"],
59
59
  publicKey: credential["publicKey"],
60
+ signCount: credential["signCount"],
60
61
  )
61
62
  context.credentials.install
62
63
 
@@ -67,7 +68,7 @@ page.goto("https://example.com/login")
67
68
 
68
69
  **Usage: save credentials in the storage state, restore later**
69
70
 
70
- See [authentication guide](https://playwright.dev/python/docs/auth) for examples of using saving and resotring the storage state.
71
+ See [authentication guide](https://playwright.dev/python/docs/auth) for examples of using saving and restoring the storage state.
71
72
 
72
73
  **Defaults**
73
74
 
@@ -95,6 +96,7 @@ def create(
95
96
  id: nil,
96
97
  privateKey: nil,
97
98
  publicKey: nil,
99
+ signCount: nil,
98
100
  userHandle: nil)
99
101
  ```
100
102
 
@@ -106,7 +108,8 @@ seeded credential is discoverable (resident), so the page can resolve it from bo
106
108
  username-then-passkey and usernameless passkey flows. The returned object carries the private and public keys, so it can be persisted to disk and re-seeded in a later test.
107
109
 
108
110
  To **import a known credential**, supply all four of `id`, `userHandle`, `privateKey` and
109
- `publicKey` together.
111
+ `publicKey` together. Pass `signCount` as well to continue from the
112
+ signature counter the relying party has already seen.
110
113
 
111
114
  Call [Credentials#install](./credentials#install) before navigating to a page that uses WebAuthn.
112
115
 
@@ -132,5 +135,5 @@ Returns every credential currently held by the authenticator, optionally filtere
132
135
  `id`. This includes both credentials seeded with [Credentials#create](./credentials#create) and credentials
133
136
  the page registered itself by calling `navigator.credentials.create()`.
134
137
 
135
- Each returned credential includes its private and public keys, so a passkey the app just
138
+ Each returned credential includes its private and public keys and the current signature counter, so a passkey the app just
136
139
  registered can be saved and re-seeded into a later test with [Credentials#create](./credentials#create) — see the second example in the class overview.
@@ -116,7 +116,7 @@ When all steps combined have not finished during the specified `timeout`, this m
116
116
  ## content
117
117
 
118
118
  ```
119
- def content
119
+ def content(includeShadow: nil)
120
120
  ```
121
121
 
122
122
 
@@ -391,13 +391,17 @@ puts frame == content_frame # => true
391
391
  ## frame_locator
392
392
 
393
393
  ```
394
- def frame_locator(selector)
394
+ def frame_locator(selector = nil)
395
395
  ```
396
396
 
397
397
 
398
398
  When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements
399
399
  in that iframe.
400
400
 
401
+ When called without `selector`, the search starts in this frame or in any of the iframes inside it,
402
+ so that you don't need to locate each iframe first. Note that the rest of the locator is resolved inside a single
403
+ frame, just like any other locator. If it matches elements inside multiple frames, an error is thrown.
404
+
401
405
  **Usage**
402
406
 
403
407
  Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe id="my-frame">`:
@@ -407,6 +411,13 @@ locator = frame.frame_locator("#my-iframe").get_by_text("Submit")
407
411
  locator.click
408
412
  ```
409
413
 
414
+ Following snippet locates a button, either in the frame or in one of the iframes inside it:
415
+
416
+ ```ruby
417
+ locator = frame.frame_locator.get_by_role('button')
418
+ locator.click
419
+ ```
420
+
410
421
  ## get_attribute
411
422
 
412
423
  ```
@@ -1225,3 +1236,8 @@ Waits for the frame to navigate to the given URL.
1225
1236
  frame.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
1226
1237
  frame.wait_for_url("**/target.html")
1227
1238
  ```
1239
+
1240
+ ## webmcp
1241
+
1242
+
1243
+ Tools that the frame registers through the experimental [WebMCP](./web_mcp) browser API. See [WebMCP](./web_mcp) for details.
@@ -24,6 +24,26 @@ page.locator('.result-frame').content_frame.get_by_role('button').click
24
24
  page.locator('.result-frame').first.content_frame.get_by_role('button').click
25
25
  ```
26
26
 
27
+ **Any frame**
28
+
29
+ Calling [Page#frame_locator](./page#frame_locator) or [Frame#frame_locator](./frame#frame_locator) without a selector creates a frame locator that
30
+ starts the search in any frame of the subtree - so that you don't
31
+ need to locate the iframe first.
32
+
33
+ ```ruby
34
+ # Finds the button in any frame on the page:
35
+ page.frame_locator.get_by_role('button').click
36
+
37
+ # Finds the iframe anywhere on the page and clicks the button inside it:
38
+ page.frame_locator.locator('#my-frame').content_frame.get_by_role('button').click
39
+ ```
40
+
41
+ Only the start of the search is affected - the rest of the locator is resolved inside a single frame, just like any
42
+ other locator. Following the strictness rules above, an error is thrown when elements are matched in multiple frames.
43
+
44
+ Such a frame locator does not point to a particular `iframe`, so [FrameLocator#owner](./frame_locator#owner),
45
+ [FrameLocator#first](./frame_locator#first), [FrameLocator#last](./frame_locator#last) and [FrameLocator#nth](./frame_locator#nth) are not supported on it.
46
+
27
47
  **Converting Locator to FrameLocator**
28
48
 
29
49
  If you have a [Locator](./locator) object pointing to an `iframe` it can be converted to [FrameLocator](./frame_locator) using [Locator#content_frame](./locator#content_frame).
@@ -1135,6 +1135,26 @@ def normalize
1135
1135
  Returns a new locator that uses best practices for referencing the matched element, prioritizing test ids,
1136
1136
  aria roles, and other user-facing attributes over CSS selectors. This is useful for converting implementation-detail selectors into more resilient, human-readable locators.
1137
1137
 
1138
+ **Usage**
1139
+
1140
+ An agent can pick an element by its ref from an [Page#aria_snapshot](./page#aria_snapshot) taken in the `"ai"` mode. Refs only
1141
+ work for the latest snapshot. Normalize the ref locator and convert it to a string to get resilient locator code
1142
+ in your language, the same way `codegen` does.
1143
+
1144
+ Consider the following aria snapshot.
1145
+
1146
+ ```yaml
1147
+ - button "Submit" [ref=e2]
1148
+ ```
1149
+
1150
+ You can turn the ref into locator code:
1151
+
1152
+ ```ruby
1153
+ normalized = page.get_by_ref("e2").normalize
1154
+ puts normalized.to_s
1155
+ # get_by_role("button", name="Submit")
1156
+ ```
1157
+
1138
1158
  ## nth
1139
1159
 
1140
1160
  ```
@@ -1531,6 +1551,34 @@ If the element is detached from the DOM at any moment during the action, this me
1531
1551
  When all steps combined have not finished during the specified `timeout`, this method throws a
1532
1552
  `TimeoutError`. Passing zero timeout disables this.
1533
1553
 
1554
+ ## visible
1555
+
1556
+ ```
1557
+ def visible
1558
+ ```
1559
+
1560
+
1561
+ Returns a locator that matches only [visible](https://playwright.dev/python/docs/actionability#visible) elements, ignoring the invisible ones. This is the recommended way to distinguish elements by visibility, as opposed to the `:visible` CSS pseudo-class.
1562
+
1563
+ Note that visibility is checked every time the locator is used, and not at the moment of the [Locator#visible](./locator#visible) call.
1564
+
1565
+ **Usage**
1566
+
1567
+ Consider a page with two buttons, the first invisible and the second visible.
1568
+
1569
+ ```html
1570
+ <button style='display: none'>Invisible</button>
1571
+ <button>Visible</button>
1572
+ ```
1573
+
1574
+ This will only find the second button, because it is visible, and then click it.
1575
+
1576
+ ```ruby
1577
+ page.locator('button').visible.click
1578
+ ```
1579
+
1580
+ To match invisible elements instead, use [Locator#filter](./locator#filter) with the `visible` option set to `false`.
1581
+
1534
1582
  ## wait_for
1535
1583
 
1536
1584
  ```
@@ -1570,3 +1618,21 @@ If `expression` throws or rejects, this method throws.
1570
1618
  Wait for an attribute to appear:
1571
1619
 
1572
1620
  Passing argument to `expression`:
1621
+
1622
+ ## within
1623
+
1624
+ ```
1625
+ def within(locator)
1626
+ ```
1627
+
1628
+
1629
+ Returns a locator that matches this locator's elements inside each element matched by `locator`.
1630
+
1631
+ Note that relative locators, such as [Locator#nth](./locator#nth) or [Locator#first](./locator#first), are resolved separately inside each matched parent. In the example below, `page.getByRole('cell').nth(2)` picks the third cell of every row, not the third cell in the whole table.
1632
+
1633
+ **Usage**
1634
+
1635
+ ```ruby
1636
+ third_column = page.get_by_role("cell").nth(2).within(page.get_by_role("row"))
1637
+ expect(third_column).to have_text(["Apple", "Banana", "Cherry"])
1638
+ ```
@@ -177,7 +177,7 @@ manually via [`event: Page.dialog`] event.
177
177
  ## content
178
178
 
179
179
  ```
180
- def content
180
+ def content(includeShadow: nil)
181
181
  ```
182
182
 
183
183
 
@@ -585,13 +585,17 @@ frame = page.frame(url: /.*domain.*/)
585
585
  ## frame_locator
586
586
 
587
587
  ```
588
- def frame_locator(selector)
588
+ def frame_locator(selector = nil)
589
589
  ```
590
590
 
591
591
 
592
592
  When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements
593
593
  in that iframe.
594
594
 
595
+ When called without `selector`, the search starts in any frame on the page - the main frame or any of
596
+ the iframes - so that you don't need to locate each iframe first. Note that the rest of the locator is resolved
597
+ inside a single frame, just like any other locator. If it matches elements inside multiple frames, an error is thrown.
598
+
595
599
  **Usage**
596
600
 
597
601
  Following snippet locates element with text "Submit" in the iframe with id `my-frame`,
@@ -602,6 +606,13 @@ locator = page.frame_locator("#my-iframe").get_by_text("Submit")
602
606
  locator.click
603
607
  ```
604
608
 
609
+ Following snippet locates a button, either in the main frame or in one of the iframes:
610
+
611
+ ```ruby
612
+ locator = page.frame_locator.get_by_role('button')
613
+ locator.click
614
+ ```
615
+
605
616
  ## frames
606
617
 
607
618
  ```
@@ -688,6 +699,30 @@ You can fill the input after locating it by the placeholder text:
688
699
  page.get_by_placeholder("name@example.com").fill("playwright@microsoft.com")
689
700
  ```
690
701
 
702
+ ## get_by_ref
703
+
704
+ ```
705
+ def get_by_ref(ref)
706
+ ```
707
+
708
+
709
+ Locate element by its aria ref. Refs like `[ref=e2]` are reported by [Page#aria_snapshot](./page#aria_snapshot) when called with
710
+ the `"ai"` mode, and resolve against the latest snapshot taken in the element's frame.
711
+
712
+ **Usage**
713
+
714
+ Consider the following aria snapshot.
715
+
716
+ ```yaml
717
+ - button "Submit" [ref=e2]
718
+ ```
719
+
720
+ You can locate the button by its ref:
721
+
722
+ ```ruby
723
+ page.get_by_ref("e2").click
724
+ ```
725
+
691
726
  ## get_by_role
692
727
 
693
728
  ```
@@ -2041,3 +2076,10 @@ API testing helper associated with this page. This method returns the same insta
2041
2076
  **Usage**
2042
2077
 
2043
2078
  ## touchscreen
2079
+
2080
+ ## webmcp
2081
+
2082
+
2083
+ Tools that the main frame registers through the experimental [WebMCP](./web_mcp) browser API. Shortcut for [Frame#webmcp](./frame#webmcp) of [Page#main_frame](./page#main_frame), see [WebMCP](./web_mcp) for details.
2084
+
2085
+ **Usage**
@@ -205,7 +205,7 @@ def resource_type
205
205
 
206
206
  Contains the request's resource type as it was perceived by the rendering engine. ResourceType will be one of the
207
207
  following: `document`, `stylesheet`, `image`, `media`, `font`, `script`, `texttrack`, `xhr`, `fetch`, `eventsource`,
208
- `websocket`, `manifest`, `other`.
208
+ `websocket`, `manifest`, `beacon`, `ping`, `cspreport`, `other`.
209
209
 
210
210
  ## response
211
211
 
@@ -70,8 +70,9 @@ def headers_array
70
70
  ```
71
71
 
72
72
 
73
- An array with all the request HTTP headers associated with this response. Unlike [Response#all_headers](./response#all_headers), header names are NOT lower-cased.
73
+ An array with all the response HTTP headers associated with this response. Unlike [Response#all_headers](./response#all_headers), header names are NOT lower-cased.
74
74
  Headers with multiple entries, such as `Set-Cookie`, appear in the array multiple times.
75
+ Some browser network stacks combine multiple field values before reporting them, so separate entries are not always available.
75
76
 
76
77
  ## header_value
77
78
 
@@ -26,16 +26,18 @@ end
26
26
 
27
27
  ```
28
28
  def start(
29
+ ariaSnapshots: nil,
29
30
  live: nil,
30
31
  name: nil,
31
32
  screenshots: nil,
33
+ screenSnapshots: nil,
32
34
  snapshots: nil,
33
35
  sources: nil,
34
36
  title: nil)
35
37
  ```
36
38
 
37
39
 
38
- Start tracing.
40
+ Start tracing. Disposing the returned `Disposable` stops tracing without saving the trace, similarly to calling [Tracing#stop](./tracing#stop) without a path.
39
41
 
40
42
  **NOTE**: You probably want to [enable tracing in your config file](https://playwright.dev/docs/api/class-testoptions#test-options-trace) instead of using `Tracing.start`.
41
43
 
@@ -57,7 +59,7 @@ def start_chunk(name: nil, title: nil)
57
59
  ```
58
60
 
59
61
 
60
- Start a new trace chunk. If you'd like to record multiple traces on the same [BrowserContext](./browser_context), use [Tracing#start](./tracing#start) once, and then create multiple trace chunks with [Tracing#start_chunk](./tracing#start_chunk) and [Tracing#stop_chunk](./tracing#stop_chunk).
62
+ Start a new trace chunk. Disposing the returned `Disposable` stops the chunk without saving it, similarly to calling [Tracing#stop_chunk](./tracing#stop_chunk) without a path. If you'd like to record multiple traces on the same [BrowserContext](./browser_context), use [Tracing#start](./tracing#start) once, and then create multiple trace chunks with [Tracing#start_chunk](./tracing#start_chunk) and [Tracing#stop_chunk](./tracing#stop_chunk).
61
63
 
62
64
  **Usage**
63
65
 
@@ -86,7 +88,7 @@ def start_har(path, content: nil, mode: nil, urlFilter: nil)
86
88
 
87
89
  Start recording a HAR (HTTP Archive) of network activity in this context. The HAR file is written to disk when [Tracing#stop_har](./tracing#stop_har) is called, or when the returned `Disposable` is disposed.
88
90
 
89
- Only one HAR recording can be active at a time per [BrowserContext](./browser_context).
91
+ Only one HAR recording can be active at a time per [Tracing](./tracing) instance.
90
92
 
91
93
  **Usage**
92
94
 
@@ -0,0 +1,34 @@
1
+ ---
2
+ sidebar_position: 10
3
+ ---
4
+
5
+ # WebMCP
6
+
7
+
8
+ [WebMCP](./web_mcp) exposes the tools that a frame registers through the experimental [WebMCP](./web_mcp) browser API, `navigator.modelContext`. It lists the tools and calls them.
9
+
10
+ Instances are accessed through [Frame#webmcp](./frame#webmcp). [Page#webmcp](./page#webmcp) is the instance of the main frame.
11
+
12
+ **NOTE**: WebMCP is an experimental browser feature. Chromium enables it with the `--enable-features=WebMCP` launch argument, Firefox with the `dom.modelcontext.enabled` and `dom.modelcontext.testing.enabled` preferences. WebKit does not implement it.
13
+
14
+ Tool names, descriptions, input schemas and results are provided by the page, so treat them as untrusted input.
15
+
16
+ ## call_tool
17
+
18
+ ```
19
+ def call_tool(name, input: nil, timeout: nil)
20
+ ```
21
+
22
+
23
+ Calls a tool registered by the frame and returns its result. The result is whatever the tool's `execute` function resolved to, typically an object with a `content` array. A result with `isError: true` is returned as is. The method throws when the tool is not registered or its `execute` function throws.
24
+
25
+ ## tools
26
+
27
+ ```
28
+ def tools(timeout: nil)
29
+ ```
30
+
31
+
32
+ Returns the tools currently registered by the frame. Throws if the browser was launched without WebMCP support, see the note above for the launch options that enable it.
33
+
34
+ [Page#webmcp](./page#webmcp) covers the main frame only, child frames list their tools through their own [Frame#webmcp](./frame#webmcp).
@@ -83,7 +83,7 @@ If custom Docker image is preferred, build it as follows:
83
83
  FROM mcr.microsoft.com/playwright
84
84
 
85
85
  WORKDIR /root
86
- ARG PLAYWRIGHT_CORE_VERSION=1.62.1
86
+ ARG PLAYWRIGHT_CORE_VERSION=1.64.0
87
87
  RUN npm install "playwright-core@$PLAYWRIGHT_CORE_VERSION" && ./node_modules/.bin/playwright-core install
88
88
 
89
89
  ENV PORT 8888
@@ -201,6 +201,7 @@
201
201
  * wait_for_selector
202
202
  * wait_for_timeout
203
203
  * wait_for_url
204
+ * webmcp
204
205
 
205
206
  ## Worker
206
207
 
@@ -285,6 +286,7 @@
285
286
  * get_by_alt_text
286
287
  * get_by_label
287
288
  * get_by_placeholder
289
+ * get_by_ref
288
290
  * get_by_role
289
291
  * get_by_test_id
290
292
  * get_by_text
@@ -371,6 +373,7 @@
371
373
  * request
372
374
  * screencast
373
375
  * touchscreen
376
+ * webmcp
374
377
 
375
378
  ## BrowserContext
376
379
 
@@ -530,8 +533,10 @@
530
533
  * text_content
531
534
  * type
532
535
  * uncheck
536
+ * visible
533
537
  * wait_for
534
538
  * wait_for_function
539
+ * within
535
540
 
536
541
  ## FrameLocator
537
542
 
@@ -567,6 +572,9 @@
567
572
 
568
573
  ## APIRequestContext
569
574
 
575
+ * add_cookies
576
+ * clear_cookies
577
+ * cookies
570
578
  * delete
571
579
  * dispose
572
580
  * fetch
@@ -660,3 +668,8 @@
660
668
  * create
661
669
  * delete
662
670
  * get
671
+
672
+ ## WebMCP
673
+
674
+ * call_tool
675
+ * tools
@@ -3,6 +3,8 @@ require 'json'
3
3
 
4
4
  module Playwright
5
5
  define_api_implementation :APIRequestImpl do
6
+ include Utils::PrepareHttpCredentials
7
+
6
8
  def initialize(playwright)
7
9
  @playwright = playwright
8
10
  end
@@ -24,7 +26,7 @@ module Playwright
24
26
  clientCertificates: prepare_client_certificates(clientCertificates),
25
27
  extraHTTPHeaders: extraHTTPHeaders ? HttpHeaders.new(extraHTTPHeaders).as_serialized : nil,
26
28
  failOnStatusCode: failOnStatusCode,
27
- httpCredentials: httpCredentials,
29
+ httpCredentials: prepare_http_credentials(httpCredentials),
28
30
  ignoreHTTPSErrors: ignoreHTTPSErrors,
29
31
  maxRedirects: maxRedirects,
30
32
  proxy: proxy,
@@ -75,7 +75,8 @@ module Playwright
75
75
  wallTime: (Time.now.to_f * 1000).to_i,
76
76
  apiName: api_name,
77
77
  stack: stacks.map do |loc|
78
- { file: loc.absolute_path || '', line: loc.lineno, function: loc.label }
78
+ # Ruby backtraces do not provide a column, but the trace protocol requires one.
79
+ { file: loc.absolute_path || '', line: loc.lineno, column: 0, function: loc.label }
79
80
  end,
80
81
  }
81
82
  end
@@ -3,6 +3,8 @@ require 'cgi/escape'
3
3
 
4
4
  module Playwright
5
5
  define_channel_owner :APIRequestContext do
6
+ include Utils::ClearCookiesParameters
7
+
6
8
  private def after_initialize
7
9
  @tracing = ChannelOwners::Tracing.from(@initializer['tracing'])
8
10
  @timeout_settings = TimeoutSettings.new
@@ -10,6 +12,20 @@ module Playwright
10
12
 
11
13
  attr_reader :tracing
12
14
 
15
+ def cookies(urls: nil)
16
+ @channel.send_message_to_server('cookies', urls: urls.nil? ? [] : Array(urls))
17
+ end
18
+
19
+ def add_cookies(cookies)
20
+ @channel.send_message_to_server('addCookies', cookies: cookies)
21
+ nil
22
+ end
23
+
24
+ def clear_cookies(domain: nil, name: nil, path: nil)
25
+ @channel.send_message_to_server('clearCookies', clear_cookies_params(domain: domain, name: name, path: path))
26
+ nil
27
+ end
28
+
13
29
  private def _update_timeout_settings(timeout_settings)
14
30
  @timeout_settings = timeout_settings
15
31
  end
@@ -156,6 +156,7 @@ module Playwright
156
156
 
157
157
  private def setup_browser_context(context)
158
158
  context.tracing.send(:update_traces_dir, @traces_dir)
159
+ context.request.tracing.send(:update_traces_dir, @traces_dir)
159
160
  @browser_type.send(:playwright_selectors_browser_contexts) << context
160
161
  end
161
162