Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,271 changes: 1,211 additions & 60 deletions dotnet/docs/api-testing.mdx

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions dotnet/docs/api/class-apirequestcontext.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,9 @@ await ApiRequestContext.StorageStateAsync(options);
- `IndexedDB` [bool]? *(optional)* <font size="2">Added in: v1.51</font><a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="api-request-context-storage-state-option-indexed-db"/><a href="#api-request-context-storage-state-option-indexed-db" class="list-anchor">#</a>

Set to `true` to include IndexedDB in the storage state snapshot.
- `Opfs` [bool]? *(optional)* <font size="2">Added in: v1.63</font><a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="api-request-context-storage-state-option-opfs"/><a href="#api-request-context-storage-state-option-opfs" class="list-anchor">#</a>

Set to `true` to include the origin private file system in the storage state snapshot.
- `Path` [string]? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="api-request-context-storage-state-option-path"/><a href="#api-request-context-storage-state-option-path" class="list-anchor">#</a>

The file path to save the storage state to. If [Path](/api/class-apirequestcontext.mdx#api-request-context-storage-state-option-path) is a relative path, then it is resolved relative to current working directory. If no path is provided, storage state is still returned, but won't be saved to the disk.
Expand Down
6 changes: 0 additions & 6 deletions dotnet/docs/api/class-browser.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,6 @@ await browser.CloseAsync();
- `Permissions` [IEnumerable]?&lt;[string]&gt; *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-new-context-option-permissions"/><a href="#browser-new-context-option-permissions" class="list-anchor">#</a>

A list of permissions to grant to all pages in this context. See [BrowserContext.GrantPermissionsAsync()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
- `PierceFrames` [bool]? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-new-context-option-pierce-frames"/><a href="#browser-new-context-option-pierce-frames" class="list-anchor">#</a>

If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [Page.PierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `Proxy` Proxy? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-new-context-option-proxy"/><a href="#browser-new-context-option-proxy" class="list-anchor">#</a>
- `Server` [string]

Expand Down Expand Up @@ -536,9 +533,6 @@ await Browser.NewPageAsync(options);
- `Permissions` [IEnumerable]?&lt;[string]&gt; *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-new-page-option-permissions"/><a href="#browser-new-page-option-permissions" class="list-anchor">#</a>

A list of permissions to grant to all pages in this context. See [BrowserContext.GrantPermissionsAsync()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
- `PierceFrames` [bool]? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-new-page-option-pierce-frames"/><a href="#browser-new-page-option-pierce-frames" class="list-anchor">#</a>

If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [Page.PierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `Proxy` Proxy? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-new-page-option-proxy"/><a href="#browser-new-page-option-proxy" class="list-anchor">#</a>
- `Server` [string]

Expand Down
13 changes: 11 additions & 2 deletions dotnet/docs/api/class-browsercontext.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,7 @@ await BrowserContext.SetOfflineAsync(offline);

<font size="2" style={{position: "relative", top: "-20px"}}>Added in: v1.59</font><x-search>browserContext.SetStorageStateAsync</x-search>

Clears the existing cookies, local storage, IndexedDB entries and virtual WebAuthn credentials, and sets the new storage state. When the storage state contains credentials, the virtual WebAuthn authenticator is installed (equivalent to [Credentials.InstallAsync()](/api/class-credentials.mdx#credentials-install)), preventing all real authenticators from working in this context.
Clears the existing cookies, local storage, IndexedDB entries, origin private file system entries and virtual WebAuthn credentials, and sets the new storage state. When the storage state contains credentials, the virtual WebAuthn authenticator is installed (equivalent to [Credentials.InstallAsync()](/api/class-credentials.mdx#credentials-install)), preventing all real authenticators from working in this context.

**Usage**

Expand All @@ -926,7 +926,7 @@ await context.SetStorageStateAsync("state.json");

<font size="2" style={{position: "relative", top: "-20px"}}>Added before v1.9</font><x-search>browserContext.StorageStateAsync</x-search>

Returns storage state for this browser context, contains current cookies, local storage snapshot, IndexedDB snapshot and virtual WebAuthn credentials.
Returns storage state for this browser context, contains current cookies, local storage snapshot, IndexedDB snapshot, origin private file system snapshot and virtual WebAuthn credentials.

**Usage**

Expand All @@ -942,6 +942,15 @@ await BrowserContext.StorageStateAsync(options);
- `IndexedDB` [bool]? *(optional)* <font size="2">Added in: v1.51</font><a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-context-storage-state-option-indexed-db"/><a href="#browser-context-storage-state-option-indexed-db" class="list-anchor">#</a>

Set to `true` to include [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) in the storage state snapshot. If your application uses IndexedDB to store authentication tokens, like Firebase Authentication, enable this.
- `Opfs` [bool]? *(optional)* <font size="2">Added in: v1.63</font><a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-context-storage-state-option-opfs"/><a href="#browser-context-storage-state-option-opfs" class="list-anchor">#</a>

Set to `true` to include the [origin private file system](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system) in the storage state snapshot.

:::note

OPFS is currently not supported in ephemeral WebKit contexts.
:::

- `Path` [string]? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-context-storage-state-option-path"/><a href="#browser-context-storage-state-option-path" class="list-anchor">#</a>

The file path to save the storage state to. If [Path](/api/class-browsercontext.mdx#browser-context-storage-state-option-path) is a relative path, then it is resolved relative to current working directory. If no path is provided, storage state is still returned, but won't be saved to the disk.
Expand Down
3 changes: 0 additions & 3 deletions dotnet/docs/api/class-browsertype.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -461,9 +461,6 @@ await BrowserType.LaunchPersistentContextAsync(userDataDir, options);
- `Permissions` [IEnumerable]?&lt;[string]&gt; *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-type-launch-persistent-context-option-permissions"/><a href="#browser-type-launch-persistent-context-option-permissions" class="list-anchor">#</a>

A list of permissions to grant to all pages in this context. See [BrowserContext.GrantPermissionsAsync()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
- `PierceFrames` [bool]? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-type-launch-persistent-context-option-pierce-frames"/><a href="#browser-type-launch-persistent-context-option-pierce-frames" class="list-anchor">#</a>

If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [Page.PierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `Proxy` Proxy? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="browser-type-launch-persistent-context-option-proxy"/><a href="#browser-type-launch-persistent-context-option-proxy" class="list-anchor">#</a>
- `Server` [string]

Expand Down
41 changes: 11 additions & 30 deletions dotnet/docs/api/class-frame.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ Console.WriteLine(frame == contentFrame); // -> True

When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in that iframe.

When called without [selector](/api/class-frame.mdx#frame-frame-locator-option-selector), the search starts in this frame or in any of the iframes inside it, so that you don't need to locate each iframe first. Note that the rest of the locator is resolved inside a single frame, just like any other locator. If it matches elements inside multiple frames, an error is thrown.

**Usage**

Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe id="my-frame">`:
Expand All @@ -337,10 +339,17 @@ var locator = frame.FrameLocator("#my-iframe").GetByText("Submit");
await locator.ClickAsync();
```

Following snippet locates a button, either in the frame or in one of the iframes inside it:

```csharp
var locator = frame.FrameLocator().GetByRole(AriaRole.Button);
await locator.ClickAsync();
```

**Arguments**
- `selector` [string]<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="frame-frame-locator-option-selector"/><a href="#frame-frame-locator-option-selector" class="list-anchor">#</a>
- `selector` [string]? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="frame-frame-locator-option-selector"/><a href="#frame-frame-locator-option-selector" class="list-anchor">#</a>

A selector to use when resolving DOM element.
A selector that matches the frame element. When not specified, locator is matched in this frame or in any of the iframes inside it.

**Returns**
- [FrameLocator]<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="frame-frame-locator-return"/><a href="#frame-frame-locator-return" class="list-anchor">#</a>
Expand Down Expand Up @@ -883,34 +892,6 @@ Frame.ParentFrame

---

### PierceFrames {/* #frame-pierce-frames */}

<font size="2" style={{position: "relative", top: "-20px"}}>Added in: v1.63</font><x-search>frame.PierceFrames</x-search>

When working with iframes, you can create a frame locator that will search for elements in this frame and in all iframes inside it, so that you don't need to locate each iframe first.

Note that all elements matching the locator must belong to a single frame. For example, if the frame contains two iframes, each with a `Submit` button, piercing frames and locating a button will throw an error because it matches elements from multiple frames.

**Usage**

Following snippet locates a button, either in the frame or in one of the iframes inside it:

```csharp
var locator = frame.PierceFrames.GetByRole(AriaRole.Button);
await locator.ClickAsync();
```

**Arguments**
- `options` `FramePierceFramesOptions?` *(optional)*
- `Pierce` [bool]? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="frame-pierce-frames-option-pierce"/><a href="#frame-pierce-frames-option-pierce" class="list-anchor">#</a>

Whether to pierce frames. Pass `false` to opt out of frame piercing enabled by the [PierceFrames](/api/class-browser.mdx#browser-new-context-option-pierce-frames) context option. Defaults to `true`.

**Returns**
- [FrameLocator]<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="frame-pierce-frames-return"/><a href="#frame-pierce-frames-return" class="list-anchor">#</a>

---

### SetContentAsync {/* #frame-set-content */}

<font size="2" style={{position: "relative", top: "-20px"}}>Added before v1.9</font><x-search>frame.SetContentAsync</x-search>
Expand Down
16 changes: 16 additions & 0 deletions dotnet/docs/api/class-framelocator.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ await page.Locator(".result-frame").ContentFrame.GetByRole(AriaRole.Button).Clic
await page.Locator(".result-frame").First.ContentFrame.getByRole(AriaRole.Button).ClickAsync();
```

**Any frame**

Calling [Page.FrameLocator()](/api/class-page.mdx#page-frame-locator) or [Frame.FrameLocator()](/api/class-frame.mdx#frame-frame-locator) without a selector creates a frame locator that starts the search in any frame of the subtree - so that you don't need to locate the iframe first.

```csharp
// Finds the button in any frame on the page:
await page.FrameLocator().GetByRole(AriaRole.Button).ClickAsync();

// Finds the iframe with id "my-frame" anywhere on the page, and clicks the button inside it:
await page.FrameLocator().Locator("#my-frame").ContentFrame.GetByRole(AriaRole.Button).ClickAsync();
```

Only the start of the search is affected - the rest of the locator is resolved inside a single frame, just like any other locator. Following the strictness rules above, an error is thrown when elements are matched in multiple frames.

Such a frame locator does not point to a particular `iframe`, so [FrameLocator.Owner](/api/class-framelocator.mdx#frame-locator-owner), [FrameLocator.First](/api/class-framelocator.mdx#frame-locator-first), [FrameLocator.Last](/api/class-framelocator.mdx#frame-locator-last) and [FrameLocator.Nth()](/api/class-framelocator.mdx#frame-locator-nth) are not supported on it.

**Converting Locator to FrameLocator**

If you have a [Locator] object pointing to an `iframe` it can be converted to [FrameLocator] using [Locator.ContentFrame](/api/class-locator.mdx#locator-content-frame).
Expand Down
32 changes: 31 additions & 1 deletion dotnet/docs/api/class-locator.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ await rowLocator
Matches elements containing specified text somewhere inside, possibly in a child or a descendant element. When passed a [string], matching is case-insensitive and searches for a substring. For example, `"Playwright"` matches `<article><div>Playwright</div></article>`.
- `Visible` [bool]? *(optional)* <font size="2">Added in: v1.51</font><a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="locator-filter-option-visible"/><a href="#locator-filter-option-visible" class="list-anchor">#</a>

Only matches visible or invisible elements.
Only matches visible or invisible elements. Prefer the [Locator.Visible](/api/class-locator.mdx#locator-visible) shortcut when matching only visible elements.

**Returns**
- [Locator]<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="locator-filter-return"/><a href="#locator-filter-return" class="list-anchor">#</a>
Expand Down Expand Up @@ -2511,6 +2511,36 @@ When all steps combined have not finished during the specified [Timeout](/api/cl

---

### Visible {/* #locator-visible */}

<font size="2" style={{position: "relative", top: "-20px"}}>Added in: v1.63</font><x-search>locator.Visible</x-search>

Returns a locator that matches only [visible](../actionability.mdx#visible) elements, ignoring the invisible ones. This is the recommended way to distinguish elements by visibility, as opposed to the `:visible` CSS pseudo-class.

Note that visibility is checked every time the locator is used, and not at the moment of the [Locator.Visible](/api/class-locator.mdx#locator-visible) call.

**Usage**

Consider a page with two buttons, the first invisible and the second visible.

```html
<button style='display: none'>Invisible</button>
<button>Visible</button>
```

This will only find the second button, because it is visible, and then click it.

```csharp
await page.Locator("button").Visible.ClickAsync();
```

To match invisible elements instead, use [Locator.Filter()](/api/class-locator.mdx#locator-filter) with the [Visible](/api/class-locator.mdx#locator-filter-option-visible) option set to `false`.

**Returns**
- [Locator]<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="locator-visible-return"/><a href="#locator-visible-return" class="list-anchor">#</a>

---

### WaitForAsync {/* #locator-wait-for */}

<font size="2" style={{position: "relative", top: "-20px"}}>Added in: v1.16</font><x-search>locator.WaitForAsync</x-search>
Expand Down
41 changes: 11 additions & 30 deletions dotnet/docs/api/class-page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,8 @@ Page.FrameByUrl(url);

When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements in that iframe.

When called without [selector](/api/class-page.mdx#page-frame-locator-option-selector), the search starts in any frame on the page - the main frame or any of the iframes - so that you don't need to locate each iframe first. Note that the rest of the locator is resolved inside a single frame, just like any other locator. If it matches elements inside multiple frames, an error is thrown.

**Usage**

Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe id="my-frame">`:
Expand All @@ -846,10 +848,17 @@ var locator = page.FrameLocator("#my-iframe").GetByText("Submit");
await locator.ClickAsync();
```

Following snippet locates a button, either in the main frame or in one of the iframes:

```csharp
var locator = page.FrameLocator().GetByRole(AriaRole.Button);
await locator.ClickAsync();
```

**Arguments**
- `selector` [string]<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="page-frame-locator-option-selector"/><a href="#page-frame-locator-option-selector" class="list-anchor">#</a>
- `selector` [string]? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="page-frame-locator-option-selector"/><a href="#page-frame-locator-option-selector" class="list-anchor">#</a>

A selector to use when resolving DOM element.
A selector that matches the frame element. When not specified, locator is matched in any frame on the page.

**Returns**
- [FrameLocator]<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="page-frame-locator-return"/><a href="#page-frame-locator-return" class="list-anchor">#</a>
Expand Down Expand Up @@ -1626,34 +1635,6 @@ Console.WriteLine(locator);

---

### PierceFrames {/* #page-pierce-frames */}

<font size="2" style={{position: "relative", top: "-20px"}}>Added in: v1.63</font><x-search>page.PierceFrames</x-search>

When working with iframes, you can create a frame locator that will search for elements in the main frame and in all iframes on the page, so that you don't need to locate each iframe first.

Note that all elements matching the locator must belong to a single frame. For example, if the page contains two iframes, each with a `Submit` button, piercing frames and locating a button will throw an error because it matches elements from multiple frames.

**Usage**

Following snippet locates a button, either in the main frame or in one of the iframes:

```csharp
var locator = page.PierceFrames.GetByRole(AriaRole.Button);
await locator.ClickAsync();
```

**Arguments**
- `options` `PagePierceFramesOptions?` *(optional)*
- `Pierce` [bool]? *(optional)*<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="page-pierce-frames-option-pierce"/><a href="#page-pierce-frames-option-pierce" class="list-anchor">#</a>

Whether to pierce frames. Pass `false` to opt out of frame piercing enabled by the [PierceFrames](/api/class-browser.mdx#browser-new-context-option-pierce-frames) context option. Defaults to `true`.

**Returns**
- [FrameLocator]<a aria-hidden="true" tabIndex="-1" class="list-anchor-link" id="page-pierce-frames-return"/><a href="#page-pierce-frames-return" class="list-anchor">#</a>

---

### ReloadAsync {/* #page-reload */}

<font size="2" style={{position: "relative", top: "-20px"}}>Added before v1.9</font><x-search>page.ReloadAsync</x-search>
Expand Down
3 changes: 2 additions & 1 deletion dotnet/docs/auth.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,15 @@ Environment.SetEnvironmentVariable("SESSION_STORAGE", sessionStorage);

// Set session storage in a new context
var loadedSessionStorage = Environment.GetEnvironmentVariable("SESSION_STORAGE");
var escapedSessionStorage = loadedSessionStorage.Replace("\\", "\\\\").Replace("'", "\\'");
await context.AddInitScriptAsync(@"(storage => {
if (window.location.hostname === 'example.com') {
const entries = JSON.parse(storage);
for (const [key, value] of Object.entries(entries)) {
window.sessionStorage.setItem(key, value);
}
}
})('" + loadedSessionStorage + "')");
})('" + escapedSessionStorage + "')");
```


Expand Down
Loading