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.
- checksums.yaml +4 -4
- data/documentation/docs/api/api_request_context.md +50 -0
- data/documentation/docs/api/browser.md +2 -0
- data/documentation/docs/api/browser_context.md +3 -3
- data/documentation/docs/api/browser_type.md +1 -0
- data/documentation/docs/api/clock.md +1 -0
- data/documentation/docs/api/credentials.md +6 -3
- data/documentation/docs/api/frame.md +18 -2
- data/documentation/docs/api/frame_locator.md +20 -0
- data/documentation/docs/api/locator.md +66 -0
- data/documentation/docs/api/page.md +44 -2
- data/documentation/docs/api/request.md +1 -1
- data/documentation/docs/api/response.md +2 -1
- data/documentation/docs/api/tracing.md +5 -3
- data/documentation/docs/api/web_mcp.md +34 -0
- data/documentation/docs/article/guides/playwright_on_alpine_linux.md +1 -1
- data/documentation/docs/include/api_coverage.md +13 -0
- data/lib/playwright/api_request_impl.rb +3 -1
- data/lib/playwright/channel.rb +2 -1
- data/lib/playwright/channel_owners/api_request_context.rb +16 -0
- data/lib/playwright/channel_owners/browser.rb +1 -0
- data/lib/playwright/channel_owners/browser_context.rb +21 -33
- data/lib/playwright/channel_owners/frame.rb +6 -5
- data/lib/playwright/channel_owners/local_utils.rb +5 -0
- data/lib/playwright/channel_owners/page.rb +12 -3
- data/lib/playwright/channel_owners/tracing.rb +45 -13
- data/lib/playwright/connection.rb +6 -2
- data/lib/playwright/credentials_impl.rb +2 -1
- data/lib/playwright/errors.rb +4 -1
- data/lib/playwright/events.rb +2 -0
- data/lib/playwright/frame_locator_impl.rb +20 -5
- data/lib/playwright/locator_impl.rb +26 -8
- data/lib/playwright/screencast.rb +4 -2
- data/lib/playwright/transport.rb +21 -5
- data/lib/playwright/utils.rb +32 -0
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright/web_mcp_impl.rb +21 -0
- data/lib/playwright_api/api_request_context.rb +47 -7
- data/lib/playwright_api/browser.rb +10 -8
- data/lib/playwright_api/browser_context.rb +17 -17
- data/lib/playwright_api/browser_type.rb +8 -7
- data/lib/playwright_api/cdp_session.rb +6 -6
- data/lib/playwright_api/clock.rb +1 -0
- data/lib/playwright_api/credentials.rb +7 -4
- data/lib/playwright_api/dialog.rb +6 -6
- data/lib/playwright_api/element_handle.rb +6 -6
- data/lib/playwright_api/frame.rb +33 -16
- data/lib/playwright_api/frame_locator.rb +20 -0
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/locator.rb +63 -3
- data/lib/playwright_api/page.rb +57 -17
- data/lib/playwright_api/playwright.rb +6 -6
- data/lib/playwright_api/request.rb +7 -7
- data/lib/playwright_api/response.rb +8 -7
- data/lib/playwright_api/route.rb +6 -6
- data/lib/playwright_api/tracing.rb +12 -10
- data/lib/playwright_api/web_mcp.rb +26 -0
- data/lib/playwright_api/web_socket.rb +6 -6
- data/lib/playwright_api/worker.rb +6 -6
- data/sig/playwright.rbs +26 -12
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3d790738449c6398b19249ce438000db7f00a06a46b8db59307f2595d849781b
|
|
4
|
+
data.tar.gz: 7010d04e7614128ad40443dae1f3745b0588915c5af4e1d8c81c21f962b9d4c5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
|
@@ -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
|
|
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
|
|
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 [
|
|
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.
|
|
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,
|
data/lib/playwright/channel.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
|