diff --git a/dotnet/docs/api/class-locator.mdx b/dotnet/docs/api/class-locator.mdx index 09347b2184..c332803441 100644 --- a/dotnet/docs/api/class-locator.mdx +++ b/dotnet/docs/api/class-locator.mdx @@ -1782,7 +1782,7 @@ Returns locator to the last matching element. **Usage** ```csharp -var banana = await page.GetByRole(AriaRole.Listitem).Last(1); +var banana = page.GetByRole(AriaRole.Listitem).Last; ``` **Returns** diff --git a/dotnet/docs/api/class-screencast.mdx b/dotnet/docs/api/class-screencast.mdx index 8be1a8b355..f5c0deac37 100644 --- a/dotnet/docs/api/class-screencast.mdx +++ b/dotnet/docs/api/class-screencast.mdx @@ -191,9 +191,7 @@ Starts the screencast. When [Path](/api/class-screencast.mdx#screencast-start-op Max frame height in pixels. - Specifies the dimensions of screencast frames. The actual frame is scaled to preserve the page's aspect ratio and may be smaller than these bounds. If not specified the size will be equal to page viewport scaled down to fit into 800×800. - - A page is captured only once, and all consumers share that single capture. Tracing captures screenshots this way as well, so with tracing or the `recordVideo` context option already active this option is ignored, and both the frames and any recorded video use the size of the running capture. + Specifies the dimensions of screencast frames. The actual frame is scaled to preserve the page's aspect ratio and may be smaller than these bounds. If a screencast is already active (e.g. started by tracing or video recording), the existing configuration takes precedence and the frame size may exceed these bounds or this option may be ignored. If not specified the size will be equal to page viewport scaled down to fit into 800×800. **Returns** - [Disposable]# diff --git a/dotnet/docs/codegen.mdx b/dotnet/docs/codegen.mdx index 0a5ffda372..f5eb3bd6d2 100644 --- a/dotnet/docs/codegen.mdx +++ b/dotnet/docs/codegen.mdx @@ -147,6 +147,14 @@ Run `codegen` with `--user-data-dir` to set a fixed [user data directory](https: pwsh bin/Debug/netX/playwright.ps1 codegen --user-data-dir=/path/to/your/browser/data/ github.com/microsoft/playwright ``` +#### Authenticate with HTTP credentials + +Run `codegen` with `--http-credentials` to authenticate with [HTTP Basic Authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Authentication). Unlike credentials embedded in the URL, they are sent to any origin that requests them during the recording session and are included in the generated code. + +```bash +pwsh bin/Debug/netX/playwright.ps1 codegen --http-credentials="username:password" example.com +``` + ## Record using custom setup If you would like to use codegen in some non-standard setup (for example, use [BrowserContext.RouteAsync()](/api/class-browsercontext.mdx#browser-context-route)), it is possible to call [Page.PauseAsync()](/api/class-page.mdx#page-pause) that will open a separate window with codegen controls. diff --git a/dotnet/docs/getting-started-cli.mdx b/dotnet/docs/getting-started-cli.mdx index 7081a524ca..2e526e707a 100644 --- a/dotnet/docs/getting-started-cli.mdx +++ b/dotnet/docs/getting-started-cli.mdx @@ -17,30 +17,25 @@ Playwright comes with `playwright-cli`, a command-line interface for browser aut ## Prerequisites Before you begin, make sure you have the following installed: -- Playwright for your language, **or** [Node.js](https://nodejs.org/) 20+ for the standalone `@playwright/cli` package +- [Node.js](https://nodejs.org/) 20 or newer - A coding agent: Claude Code, GitHub Copilot, or similar ## Installation -Install the standalone CLI globally (works with any language): +Install `playwright-cli` globally: ```bash npm install -g @playwright/cli@latest playwright-cli --help ``` -Or use the CLI bundled with your Playwright install: +Alternatively, install `@playwright/cli` as a local dependency and use `npx`: ```bash -# JavaScript / TypeScript -npx playwright cli --help - -# Python -python -m playwright cli --help +npm install -D @playwright/cli@latest +npx playwright-cli --help ``` -When using a bundled entry point, replace `playwright-cli` with `npx playwright cli` or `python -m playwright cli` in the commands below. - ### Installing skills Coding agents like Claude Code and GitHub Copilot can use locally installed skills for richer context about available commands: @@ -300,29 +295,11 @@ playwright-cli attach --extension This requires the [Playwright Extension](https://github.com/microsoft/playwright/blob/main/packages/extension/README.md) to be installed. -## Debugging tests - -Coding agents can pause a test at the start, attach with `playwright-cli`, and explore the live browser — useful for diagnosing and fixing failures. - -```bash -# JavaScript / TypeScript -PLAYWRIGHT_HTML_OPEN=never npx playwright test --debug=cli -# → Debugging Instructions with session name, e.g. tw-abcdef -playwright-cli attach tw-abcdef - -# Python (pytest-playwright; -s keeps the attach line visible) -pytest --playwright-debug=cli -s -playwright-cli attach tw-abcdef -``` - -Keep the test running in the background while you attach. The installed skill documents this workflow for agents. - ## Quick Reference | Action | Command | | ------------------------- | --------------------------------------------------- | | **Install CLI** | `npm install -g @playwright/cli@latest` | -| **Use bundled CLI** | `npx playwright cli …` / `python -m playwright cli …` | | **Install skills** | `playwright-cli install --skills` | | **Open a page** | `playwright-cli open https://example.com` | | **Click an element** | `playwright-cli click e15` | @@ -332,8 +309,6 @@ Keep the test running in the background while you attach. The installed skill do | **Run headed** | `playwright-cli open https://example.com --headed` | | **Use Firefox** | `playwright-cli open --browser=firefox` | | **Monitor sessions** | `playwright-cli show` | -| **Debug JS test** | `npx playwright test --debug=cli` | -| **Debug Python test** | `pytest --playwright-debug=cli -s` | ## What's Next - [Write tests using web-first assertions, page fixtures, and locators](./writing-tests.mdx) diff --git a/dotnet/docs/test-assertions.mdx b/dotnet/docs/test-assertions.mdx index 70afa39a03..7bf052f82e 100644 --- a/dotnet/docs/test-assertions.mdx +++ b/dotnet/docs/test-assertions.mdx @@ -6,7 +6,21 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import HTMLCard from '@site/src/components/HTMLCard'; -## List of assertions +## Introduction + +Playwright includes web-specific assertions that automatically retry until the expected condition is met. Consider the following example: + +```csharp +await Expect(Page.GetByTestId("status")).ToHaveTextAsync("Submitted"); +``` + +Playwright will re-test the element with the test ID of `status` until it has the `"Submitted"` text. It will re-fetch the element and check it repeatedly until the condition is met or the timeout is reached. + +By default, the timeout for assertions is 5 seconds. + +## Auto-retrying assertions + +The following assertions will retry until the assertion passes or the assertion timeout is reached. | Assertion | Description | | :- | :- | diff --git a/java/docs/api/class-screencast.mdx b/java/docs/api/class-screencast.mdx index 4ccabf4b10..28c334b809 100644 --- a/java/docs/api/class-screencast.mdx +++ b/java/docs/api/class-screencast.mdx @@ -194,9 +194,7 @@ Starts the screencast. When [setPath](/api/class-screencast.mdx#screencast-start Max frame height in pixels. - Specifies the dimensions of screencast frames. The actual frame is scaled to preserve the page's aspect ratio and may be smaller than these bounds. If not specified the size will be equal to page viewport scaled down to fit into 800×800. - - A page is captured only once, and all consumers share that single capture. Tracing captures screenshots this way as well, so with tracing or the `recordVideo` context option already active this option is ignored, and both the frames and any recorded video use the size of the running capture. + Specifies the dimensions of screencast frames. The actual frame is scaled to preserve the page's aspect ratio and may be smaller than these bounds. If a screencast is already active (e.g. started by tracing or video recording), the existing configuration takes precedence and the frame size may exceed these bounds or this option may be ignored. If not specified the size will be equal to page viewport scaled down to fit into 800×800. **Returns** - [Disposable]# diff --git a/java/docs/codegen.mdx b/java/docs/codegen.mdx index 9966510e50..d17ec5d6ef 100644 --- a/java/docs/codegen.mdx +++ b/java/docs/codegen.mdx @@ -147,6 +147,14 @@ Run `codegen` with `--user-data-dir` to set a fixed [user data directory](https: mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="codegen --user-data-dir=/path/to/your/browser/data/ github.com/microsoft/playwright" ``` +#### Authenticate with HTTP credentials + +Run `codegen` with `--http-credentials` to authenticate with [HTTP Basic Authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Authentication). Unlike credentials embedded in the URL, they are sent to any origin that requests them during the recording session and are included in the generated code. + +```bash +mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args='codegen --http-credentials="username:password" example.com' +``` + ## Record using custom setup If you would like to use codegen in some non-standard setup (for example, use [BrowserContext.route()](/api/class-browsercontext.mdx#browser-context-route)), it is possible to call [Page.pause()](/api/class-page.mdx#page-pause) that will open a separate window with codegen controls. diff --git a/java/docs/getting-started-cli.mdx b/java/docs/getting-started-cli.mdx index 6f815e4d98..7474caea16 100644 --- a/java/docs/getting-started-cli.mdx +++ b/java/docs/getting-started-cli.mdx @@ -17,30 +17,25 @@ Playwright comes with `playwright-cli`, a command-line interface for browser aut ## Prerequisites Before you begin, make sure you have the following installed: -- Playwright for your language, **or** [Node.js](https://nodejs.org/) 20+ for the standalone `@playwright/cli` package +- [Node.js](https://nodejs.org/) 20 or newer - A coding agent: Claude Code, GitHub Copilot, or similar ## Installation -Install the standalone CLI globally (works with any language): +Install `playwright-cli` globally: ```bash npm install -g @playwright/cli@latest playwright-cli --help ``` -Or use the CLI bundled with your Playwright install: +Alternatively, install `@playwright/cli` as a local dependency and use `npx`: ```bash -# JavaScript / TypeScript -npx playwright cli --help - -# Python -python -m playwright cli --help +npm install -D @playwright/cli@latest +npx playwright-cli --help ``` -When using a bundled entry point, replace `playwright-cli` with `npx playwright cli` or `python -m playwright cli` in the commands below. - ### Installing skills Coding agents like Claude Code and GitHub Copilot can use locally installed skills for richer context about available commands: @@ -300,29 +295,11 @@ playwright-cli attach --extension This requires the [Playwright Extension](https://github.com/microsoft/playwright/blob/main/packages/extension/README.md) to be installed. -## Debugging tests - -Coding agents can pause a test at the start, attach with `playwright-cli`, and explore the live browser — useful for diagnosing and fixing failures. - -```bash -# JavaScript / TypeScript -PLAYWRIGHT_HTML_OPEN=never npx playwright test --debug=cli -# → Debugging Instructions with session name, e.g. tw-abcdef -playwright-cli attach tw-abcdef - -# Python (pytest-playwright; -s keeps the attach line visible) -pytest --playwright-debug=cli -s -playwright-cli attach tw-abcdef -``` - -Keep the test running in the background while you attach. The installed skill documents this workflow for agents. - ## Quick Reference | Action | Command | | ------------------------- | --------------------------------------------------- | | **Install CLI** | `npm install -g @playwright/cli@latest` | -| **Use bundled CLI** | `npx playwright cli …` / `python -m playwright cli …` | | **Install skills** | `playwright-cli install --skills` | | **Open a page** | `playwright-cli open https://example.com` | | **Click an element** | `playwright-cli click e15` | @@ -332,8 +309,6 @@ Keep the test running in the background while you attach. The installed skill do | **Run headed** | `playwright-cli open https://example.com --headed` | | **Use Firefox** | `playwright-cli open --browser=firefox` | | **Monitor sessions** | `playwright-cli show` | -| **Debug JS test** | `npx playwright test --debug=cli` | -| **Debug Python test** | `pytest --playwright-debug=cli -s` | ## What's Next - [Write tests using web-first assertions, page fixtures, and locators](./writing-tests.mdx) diff --git a/java/docs/mock.mdx b/java/docs/mock.mdx index f4b7dfc341..2dfc07f26d 100644 --- a/java/docs/mock.mdx +++ b/java/docs/mock.mdx @@ -16,7 +16,7 @@ The following code will intercept all the calls to `*/**/api/v1/fruits` and will ```java // Intercept the route to the fruit API -page.route("https://fruit.ceo/api/breeds/image/random", route -> { +page.route("*/**/api/v1/fruits", route -> { List> data = new ArrayList>(); Hashtable dict = new Hashtable(); dict.put("name", "Strawberry"); diff --git a/java/docs/test-assertions.mdx b/java/docs/test-assertions.mdx index 1d9fc5d623..813f8edc33 100644 --- a/java/docs/test-assertions.mdx +++ b/java/docs/test-assertions.mdx @@ -6,7 +6,21 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import HTMLCard from '@site/src/components/HTMLCard'; -## List of assertions +## Introduction + +Playwright includes web-specific assertions that automatically retry until the expected condition is met. Consider the following example: + +```java +assertThat(page.getByTestId("status")).hasText("Submitted"); +``` + +Playwright will re-test the element with the test ID of `status` until it has the `"Submitted"` text. It will re-fetch the element and check it repeatedly until the condition is met or the timeout is reached. + +By default, the timeout for assertions is 5 seconds. + +## Auto-retrying assertions + +The following assertions will retry until the assertion passes or the assertion timeout is reached. | Assertion | Description | | :- | :- | @@ -39,6 +53,29 @@ import HTMLCard from '@site/src/components/HTMLCard'; | [assertThat(page).hasURL()](/api/class-pageassertions.mdx#page-assertions-to-have-url) | Page has a URL | | [assertThat(response).isOK()](/api/class-apiresponseassertions.mdx#api-response-assertions-to-be-ok) | Response has an OK status | +## Setting a custom timeout + +You can specify a custom timeout for assertions either globally or per assertion. The default timeout is 5 seconds. + +### Global timeout + +```java +import com.microsoft.playwright.assertions.PlaywrightAssertions; + +PlaywrightAssertions.setDefaultAssertionTimeout(10_000); +``` + +### Per assertion timeout + +```java +import com.microsoft.playwright.assertions.LocatorAssertions; + +import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; + +assertThat(page.getByText("Name")).isVisible( + new LocatorAssertions.IsVisibleOptions().setTimeout(10_000)); +``` + [APIRequest]: /api/class-apirequest.mdx "APIRequest" [APIRequestContext]: /api/class-apirequestcontext.mdx "APIRequestContext" diff --git a/nodejs/docs/accessibility-testing.mdx b/nodejs/docs/accessibility-testing.mdx index dfad404b78..3a1f39e910 100644 --- a/nodejs/docs/accessibility-testing.mdx +++ b/nodejs/docs/accessibility-testing.mdx @@ -341,7 +341,6 @@ test('example using custom fixture', async ({ page, makeAxeBuilder }) => { [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/actionability.mdx b/nodejs/docs/actionability.mdx index 8a2b2fedea..900585a789 100644 --- a/nodejs/docs/actionability.mdx +++ b/nodejs/docs/actionability.mdx @@ -131,7 +131,6 @@ For example, consider a scenario where Playwright will click `Sign Up` button re [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api-testing.mdx b/nodejs/docs/api-testing.mdx index dbde55037e..f0938cc717 100644 --- a/nodejs/docs/api-testing.mdx +++ b/nodejs/docs/api-testing.mdx @@ -382,7 +382,6 @@ test('global context request has isolated cookie storage', async ({ [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-android.mdx b/nodejs/docs/api/class-android.mdx index cebb0b488c..116a20d5a3 100644 --- a/nodejs/docs/api/class-android.mdx +++ b/nodejs/docs/api/class-android.mdx @@ -252,7 +252,6 @@ android.setDefaultTimeout(timeout); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-androiddevice.mdx b/nodejs/docs/api/class-androiddevice.mdx index 3e351d31f7..49d2a8ed67 100644 --- a/nodejs/docs/api/class-androiddevice.mdx +++ b/nodejs/docs/api/class-androiddevice.mdx @@ -950,7 +950,6 @@ androidDevice.on('webview', data => {}); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-androidinput.mdx b/nodejs/docs/api/class-androidinput.mdx index cb50556da2..a5fac605e5 100644 --- a/nodejs/docs/api/class-androidinput.mdx +++ b/nodejs/docs/api/class-androidinput.mdx @@ -166,7 +166,6 @@ await androidInput.type(text); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-androidsocket.mdx b/nodejs/docs/api/class-androidsocket.mdx index 0d50a6c5f6..dff843aa45 100644 --- a/nodejs/docs/api/class-androidsocket.mdx +++ b/nodejs/docs/api/class-androidsocket.mdx @@ -93,7 +93,6 @@ androidSocket.on('data', data => {}); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-androidwebview.mdx b/nodejs/docs/api/class-androidwebview.mdx index 7041c048b1..09b1237099 100644 --- a/nodejs/docs/api/class-androidwebview.mdx +++ b/nodejs/docs/api/class-androidwebview.mdx @@ -88,7 +88,6 @@ androidWebView.on('close', data => {}); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-apirequest.mdx b/nodejs/docs/api/class-apirequest.mdx index 51c73ddfbe..c56362531a 100644 --- a/nodejs/docs/api/class-apirequest.mdx +++ b/nodejs/docs/api/class-apirequest.mdx @@ -178,7 +178,6 @@ await apiRequest.newContext(options); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-apirequestcontext.mdx b/nodejs/docs/api/class-apirequestcontext.mdx index 8049655d3c..ab4dd4c323 100644 --- a/nodejs/docs/api/class-apirequestcontext.mdx +++ b/nodejs/docs/api/class-apirequestcontext.mdx @@ -676,7 +676,6 @@ apiRequestContext.tracing [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-apiresponse.mdx b/nodejs/docs/api/class-apiresponse.mdx index b041469b81..0378facd66 100644 --- a/nodejs/docs/api/class-apiresponse.mdx +++ b/nodejs/docs/api/class-apiresponse.mdx @@ -297,7 +297,6 @@ apiResponse.url(); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-apiresponseassertions.mdx b/nodejs/docs/api/class-apiresponseassertions.mdx index 1d13fb2b99..7a9f8ca9f1 100644 --- a/nodejs/docs/api/class-apiresponseassertions.mdx +++ b/nodejs/docs/api/class-apiresponseassertions.mdx @@ -69,7 +69,6 @@ await expect(response).not.toBeOK(); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-browser.mdx b/nodejs/docs/api/class-browser.mdx index 263cbaa239..f3dc631ddf 100644 --- a/nodejs/docs/api/class-browser.mdx +++ b/nodejs/docs/api/class-browser.mdx @@ -946,7 +946,6 @@ browser.on('disconnected', data => {}); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-browsercontext.mdx b/nodejs/docs/api/class-browsercontext.mdx index f7c28e01ad..ff18e106ff 100644 --- a/nodejs/docs/api/class-browsercontext.mdx +++ b/nodejs/docs/api/class-browsercontext.mdx @@ -1579,7 +1579,6 @@ await browserContext.setHTTPCredentials(httpCredentials); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-browserserver.mdx b/nodejs/docs/api/class-browserserver.mdx index 59ddeaf585..e84cbf8b05 100644 --- a/nodejs/docs/api/class-browserserver.mdx +++ b/nodejs/docs/api/class-browserserver.mdx @@ -105,7 +105,6 @@ browserServer.on('close', data => {}); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-browsertype.mdx b/nodejs/docs/api/class-browsertype.mdx index d890b9f207..f1eab13e53 100644 --- a/nodejs/docs/api/class-browsertype.mdx +++ b/nodejs/docs/api/class-browsertype.mdx @@ -735,7 +735,6 @@ browserType.name(); [BrowserContext]: /api/class-browsercontext.mdx "BrowserContext" [BrowserServer]: /api/class-browserserver.mdx "BrowserServer" [BrowserType]: /api/class-browsertype.mdx "BrowserType" -[By]: /api/class-by.mdx "By" [CDPSession]: /api/class-cdpsession.mdx "CDPSession" [Clock]: /api/class-clock.mdx "Clock" [ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage" diff --git a/nodejs/docs/api/class-by.mdx b/nodejs/docs/api/class-by.mdx deleted file mode 100644 index 64adf1abc8..0000000000 --- a/nodejs/docs/api/class-by.mdx +++ /dev/null @@ -1,565 +0,0 @@ ---- -id: class-by -title: "By" ---- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import HTMLCard from '@site/src/components/HTMLCard'; - - -[By] describes an element without being bound to a [Page] or a [Frame]. It is built with the top-level [playwright.by](/api/class-playwright.mdx#playwright-by) object and turned into a regular [Locator] with [page.get()](/api/class-page.mdx#page-get), [frame.get()](/api/class-frame.mdx#frame-get) or [locator.get()](/api/class-locator.mdx#locator-get). - -Since a [By] carries no page, it can be defined once at module scope and reused by every test, which makes it a natural fit for page objects. - -**Usage** - -```js -import { by, expect, test } from '@playwright/test'; - -const saveButton = by.role('button', { name: 'Save' }); -const todoItems = by.testId('todo-list').role('listitem'); - -test('saves a todo', async ({ page }) => { - await page.get(saveButton).click(); - await expect(page.get(todoItems)).toHaveCount(1); -}); -``` - -A [By] chain resolves to the same element as the matching [Locator] chain, so `page.get(by.testId('list').text('Row'))` and `page.getByTestId('list').getByText('Row')` are interchangeable. Chaining composes rather than replaces: `page.get(outer.get(inner))` and `page.get(outer).get(inner)` describe the same element. - - ---- - -## Methods - -### altText {/* #by-alt-text */} - -Added in: v1.63by.altText - -Matches a descendant element by its `alt` text. - -**Usage** - -```js -by.altText(text); -by.altText(text, options); -``` - -**Arguments** -- `text` [string] | [RegExp] Added in: v1.27# - - Text to locate the element for. -- `options` [Object] *(optional)* - - `exact` [boolean] *(optional)* Added in: v1.27# - - Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular expression. Note that exact match still trims whitespace. - -**Returns** -- [By]# - ---- - -### and {/* #by-and */} - -Added in: v1.63by.and - -Narrows down the match to elements that match both this and the given [By]. - -**Usage** - -```js -const saveButton = by.role('button').and(by.title('Subscribe')); -``` - -**Arguments** -- `by` [By]# - - Additional locator to match. - -**Returns** -- [By]# - ---- - -### describe {/* #by-describe */} - -Added in: v1.63by.describe - -Describes the element, the description is used in the trace viewer and the reports. - -**Usage** - -```js -by.describe(description); -``` - -**Arguments** -- `description` [string]# - - Locator description. - -**Returns** -- [By]# - ---- - -### filter {/* #by-filter */} - -Added in: v1.63by.filter - -Narrows down the match according to the options, for example filters by text. It can be chained to filter multiple times. - -**Usage** - -```js -const rowWithButton = by.get('tr') - .filter({ hasText: 'text in column 1' }) - .filter({ has: by.role('button', { name: 'column 2 button' }) }); -``` - -**Arguments** -- `options` [Object] *(optional)* - - `has` [By] *(optional)*# - - Narrows down the results to those which contain elements matching this relative [By]. The inner [By] is queried starting with the outer match, not the document root. - - `hasNot` [By] *(optional)*# - - Matches elements that do not contain an element matching this relative [By]. The inner [By] is queried starting with the outer match, not the document root. - - `hasNotText` [string] | [RegExp] *(optional)*# - - Matches elements that do not contain 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. - - `hasText` [string] | [RegExp] *(optional)*# - - 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 `
Playwright
`. - - `visible` [boolean] *(optional)*# - - Only matches visible or invisible elements. - -**Returns** -- [By]# - ---- - -### first {/* #by-first */} - -Added in: v1.63by.first - -Matches the first matching element. - -**Usage** - -```js -by.first(); -``` - -**Returns** -- [By]# - ---- - -### get {/* #by-get */} - -Added in: v1.63by.get - -Matches a descendant element by a selector or by another [By]. - -**Usage** - -```js -const firstCell = by.get('table').get('td').first(); - -const listItem = by.role('listitem'); -const unread = by.testId('inbox').get(listItem).filter({ hasText: 'Unread' }); -``` - -**Arguments** -- `selectorOrBy` [string] | [By]# - - A selector or a [By] to match inside this one. - -**Returns** -- [By]# - -**Details** - -Passing a [By] composes rather than replaces, so `outer.get(inner.get(innermost))` and `outer.get(inner).get(innermost)` describe the same element. - ---- - -### label {/* #by-label */} - -Added in: v1.63by.label - -Matches an input element by the text of the associated `