diff --git a/.github/actions/enable-microphone-access/action.yml b/.github/actions/enable-microphone-access/action.yml index b94f480647..d706b17544 100644 --- a/.github/actions/enable-microphone-access/action.yml +++ b/.github/actions/enable-microphone-access/action.yml @@ -19,7 +19,7 @@ runs: elif [[ "$version" == "12" || "$version" == "13" ]]; then sqlite3 $HOME/Library/Application\ Support/com.apple.TCC/TCC.db "INSERT OR REPLACE INTO access VALUES('kTCCServiceMicrophone','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159);" else - echo "macOS version is unsupported. Version is $version, exiting" - exit 1 + echo "Skipping unsupported macOS version $version" + exit 0 fi echo "Successfully allowed microphone access" diff --git a/.github/workflows/tests_secondary.yml b/.github/workflows/tests_secondary.yml index 8d4bbd1c78..04747ca5c2 100644 --- a/.github/workflows/tests_secondary.yml +++ b/.github/workflows/tests_secondary.yml @@ -50,10 +50,15 @@ jobs: strategy: fail-fast: false matrix: - # Intel: macos-13, macos-14-large - # Arm64: macos-13-xlarge, macos-14 + # Intel: macos-13, macos-14-large, macos-15-large + # Arm64: macos-13-xlarge, macos-14 macos-15 os: [macos-13, macos-13-xlarge, macos-14-large, macos-14] browser: [chromium, firefox, webkit] + include: + - os: macos-15-large + browser: webkit + - os: macos-15 + browser: webkit runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index 4796c77121..b7955069a2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🎭 Playwright -[![npm version](https://img.shields.io/npm/v/playwright.svg)](https://www.npmjs.com/package/playwright) [![Chromium version](https://img.shields.io/badge/chromium-130.0.6723.6-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-130.0-blue.svg?logo=firefoxbrowser)](https://www.mozilla.org/en-US/firefox/new/) [![WebKit version](https://img.shields.io/badge/webkit-18.0-blue.svg?logo=safari)](https://webkit.org/) [![Join Discord](https://img.shields.io/badge/join-discord-infomational)](https://aka.ms/playwright/discord) +[![npm version](https://img.shields.io/npm/v/playwright.svg)](https://www.npmjs.com/package/playwright) [![Chromium version](https://img.shields.io/badge/chromium-130.0.6723.19-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-130.0-blue.svg?logo=firefoxbrowser)](https://www.mozilla.org/en-US/firefox/new/) [![WebKit version](https://img.shields.io/badge/webkit-18.0-blue.svg?logo=safari)](https://webkit.org/) [![Join Discord](https://img.shields.io/badge/join-discord-infomational)](https://aka.ms/playwright/discord) ## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright) @@ -8,7 +8,7 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr | | Linux | macOS | Windows | | :--- | :---: | :---: | :---: | -| Chromium 130.0.6723.6 | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Chromium 130.0.6723.19 | :white_check_mark: | :white_check_mark: | :white_check_mark: | | WebKit 18.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: | | Firefox 130.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: | diff --git a/docs/src/api/class-androiddevice.md b/docs/src/api/class-androiddevice.md index cff6c2e5de..729b36f922 100644 --- a/docs/src/api/class-androiddevice.md +++ b/docs/src/api/class-androiddevice.md @@ -177,7 +177,9 @@ Launches a process in the shell on the device and returns a socket to communicat ### param: AndroidDevice.open.command * since: v1.9 -- `command` <[string]> Shell command to execute. +- `command` <[string]> + +Shell command to execute. ## async method: AndroidDevice.pinchClose * since: v1.9 @@ -445,7 +447,7 @@ Either a predicate that receives an event or an options object. Optional. * since: v1.9 - returns: <[AndroidWebView]> -This method waits until [AndroidWebView] matching the [`option: selector`] is opened and returns it. If there is already an open [AndroidWebView] matching the [`option: selector`], returns immediately. +This method waits until [AndroidWebView] matching the [`param: selector`] is opened and returns it. If there is already an open [AndroidWebView] matching the [`param: selector`], returns immediately. ### param: AndroidDevice.webView.selector * since: v1.9 diff --git a/docs/src/api/class-apirequestcontext.md b/docs/src/api/class-apirequestcontext.md index f56087d1bd..40742e2a1f 100644 --- a/docs/src/api/class-apirequestcontext.md +++ b/docs/src/api/class-apirequestcontext.md @@ -247,7 +247,7 @@ var data = new Dictionary() { await Request.FetchAsync("https://example.com/api/createBook", new() { Method = "post", DataObject = data }); ``` -The common way to send file(s) in the body of a request is to upload them as form fields with `multipart/form-data` encoding. Use [FormData] to construct request body and pass it to the request as [`option: multipart`] parameter: +The common way to send file(s) in the body of a request is to upload them as form fields with `multipart/form-data` encoding, by specifiying the `multipart` parameter: ```js const form = new FormData(); @@ -300,6 +300,7 @@ multipart.Set("fileField", file); await Request.FetchAsync("https://example.com/api/uploadScript", new() { Method = "post", Multipart = multipart }); ``` + ### param: APIRequestContext.fetch.urlOrRequest * since: v1.16 - `urlOrRequest` <[string]|[Request]> diff --git a/docs/src/api/class-browsercontext.md b/docs/src/api/class-browsercontext.md index 90ee0337d3..b504bf457b 100644 --- a/docs/src/api/class-browsercontext.md +++ b/docs/src/api/class-browsercontext.md @@ -1198,7 +1198,7 @@ Enabling routing disables http cache. - `url` <[string]|[RegExp]|[function]\([URL]\):[boolean]> A glob pattern, regex pattern or predicate receiving [URL] to match while routing. -When a [`option: baseURL`] via the context options was provided and the passed URL is a path, +When a [`option: Browser.newContext.baseURL`] via the context options was provided and the passed URL is a path, it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor. ### param: BrowserContext.route.handler @@ -1342,7 +1342,7 @@ await context.RouteWebSocketAsync("/ws", async ws => { * since: v1.48 - `url` <[string]|[RegExp]|[function]\([URL]\):[boolean]> -Only WebSockets with the url matching this pattern will be routed. A string pattern can be relative to the [`option: baseURL`] from the context options. +Only WebSockets with the url matching this pattern will be routed. A string pattern can be relative to the [`option: Browser.newContext.baseURL`] context option. ### param: BrowserContext.routeWebSocket.handler * since: v1.48 diff --git a/docs/src/api/class-frame.md b/docs/src/api/class-frame.md index bf3666b9be..e286c63bfa 100644 --- a/docs/src/api/class-frame.md +++ b/docs/src/api/class-frame.md @@ -1304,7 +1304,7 @@ Returns whether the element is [enabled](../actionability.md#enabled). * discouraged: Use locator-based [`method: Locator.isHidden`] instead. Read more about [locators](../locators.md). - returns: <[boolean]> -Returns whether the element is hidden, the opposite of [visible](../actionability.md#visible). [`option: selector`] that does not match any elements is considered hidden. +Returns whether the element is hidden, the opposite of [visible](../actionability.md#visible). [`param: selector`] that does not match any elements is considered hidden. ### param: Frame.isHidden.selector = %%-input-selector-%% * since: v1.8 @@ -1322,7 +1322,7 @@ Returns whether the element is hidden, the opposite of [visible](../actionabilit * discouraged: Use locator-based [`method: Locator.isVisible`] instead. Read more about [locators](../locators.md). - returns: <[boolean]> -Returns whether the element is [visible](../actionability.md#visible). [`option: selector`] that does not match any elements is considered not visible. +Returns whether the element is [visible](../actionability.md#visible). [`param: selector`] that does not match any elements is considered not visible. ### param: Frame.isVisible.selector = %%-input-selector-%% * since: v1.8 diff --git a/docs/src/api/class-locator.md b/docs/src/api/class-locator.md index 86de53841c..3a9504ad59 100644 --- a/docs/src/api/class-locator.md +++ b/docs/src/api/class-locator.md @@ -54,7 +54,7 @@ foreach (var li in await page.GetByRole("listitem").AllAsync()) Returns an array of `node.innerText` values for all matching nodes. :::warning[Asserting text] -If you need to assert text on the page, prefer [`method: LocatorAssertions.toHaveText`] with [`option: useInnerText`] option to avoid flakiness. See [assertions guide](../test-assertions.md) for more details. +If you need to assert text on the page, prefer [`method: LocatorAssertions.toHaveText`] with [`option: LocatorAssertions.toHaveText.useInnerText`] option to avoid flakiness. See [assertions guide](../test-assertions.md) for more details. ::: **Usage** @@ -1291,7 +1291,7 @@ Returns the [`element.innerHTML`](https://developer.mozilla.org/en-US/docs/Web/A Returns the [`element.innerText`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText). :::warning[Asserting text] -If you need to assert text on the page, prefer [`method: LocatorAssertions.toHaveText`] with [`option: useInnerText`] option to avoid flakiness. See [assertions guide](../test-assertions.md) for more details. +If you need to assert text on the page, prefer [`method: LocatorAssertions.toHaveText`] with [`option: LocatorAssertions.toHaveText.useInnerText`] option to avoid flakiness. See [assertions guide](../test-assertions.md) for more details. ::: ### option: Locator.innerText.timeout = %%-input-timeout-%% diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md index b437b9313e..b376edfb1d 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md @@ -2333,10 +2333,57 @@ last redirect. If cannot go forward, returns `null`. Navigate to the next page in history. -## async method: Page.forceGarbageCollection -* since: v1.47 +## async method: Page.requestGC +* since: v1.48 -Force the browser to perform garbage collection. +Request the page to perform garbage collection. Note that there is no guarantee that all unreachable objects will be collected. + +This is useful to help detect memory leaks. For example, if your page has a large object `'suspect'` that might be leaked, you can check that it does not leak by using a [`WeakRef`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef). + +```js +// 1. In your page, save a WeakRef for the "suspect". +await page.evaluate(() => globalThis.suspectWeakRef = new WeakRef(suspect)); +// 2. Request garbage collection. +await page.requestGC(); +// 3. Check that weak ref does not deref to the original object. +expect(await page.evaluate(() => !globalThis.suspectWeakRef.deref())).toBe(true); +``` + +```java +// 1. In your page, save a WeakRef for the "suspect". +page.evaluate("globalThis.suspectWeakRef = new WeakRef(suspect)"); +// 2. Request garbage collection. +page.requestGC(); +// 3. Check that weak ref does not deref to the original object. +assertTrue(page.evaluate("!globalThis.suspectWeakRef.deref()")); +``` + +```python async +# 1. In your page, save a WeakRef for the "suspect". +await page.evaluate("globalThis.suspectWeakRef = new WeakRef(suspect)") +# 2. Request garbage collection. +await page.request_gc() +# 3. Check that weak ref does not deref to the original object. +assert await page.evaluate("!globalThis.suspectWeakRef.deref()") +``` + +```python sync +# 1. In your page, save a WeakRef for the "suspect". +page.evaluate("globalThis.suspectWeakRef = new WeakRef(suspect)") +# 2. Request garbage collection. +page.request_gc() +# 3. Check that weak ref does not deref to the original object. +assert page.evaluate("!globalThis.suspectWeakRef.deref()") +``` + +```csharp +// 1. In your page, save a WeakRef for the "suspect". +await Page.EvaluateAsync("globalThis.suspectWeakRef = new WeakRef(suspect)"); +// 2. Request garbage collection. +await Page.RequestGCAsync(); +// 3. Check that weak ref does not deref to the original object. +Assert.True(await Page.EvaluateAsync("!globalThis.suspectWeakRef.deref()")); +``` ### option: Page.goForward.waitUntil = %%-navigation-wait-until-%% * since: v1.8 @@ -2382,7 +2429,7 @@ Headless mode doesn't support navigation to a PDF document. See the - `url` <[string]> URL to navigate page to. The url should include scheme, e.g. `https://`. -When a [`option: baseURL`] via the context options was provided and the passed URL is a path, +When a [`option: Browser.newContext.baseURL`] via the context options was provided and the passed URL is a path, it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor. ### option: Page.goto.waitUntil = %%-navigation-wait-until-%% @@ -2589,7 +2636,7 @@ Returns whether the element is [enabled](../actionability.md#enabled). * discouraged: Use locator-based [`method: Locator.isHidden`] instead. Read more about [locators](../locators.md). - returns: <[boolean]> -Returns whether the element is hidden, the opposite of [visible](../actionability.md#visible). [`option: selector`] that does not match any elements is considered hidden. +Returns whether the element is hidden, the opposite of [visible](../actionability.md#visible). [`param: selector`] that does not match any elements is considered hidden. ### param: Page.isHidden.selector = %%-input-selector-%% * since: v1.8 @@ -2608,7 +2655,7 @@ Returns whether the element is hidden, the opposite of [visible](../actionabilit * discouraged: Use locator-based [`method: Locator.isVisible`] instead. Read more about [locators](../locators.md). - returns: <[boolean]> -Returns whether the element is [visible](../actionability.md#visible). [`option: selector`] that does not match any elements is considered not visible. +Returns whether the element is [visible](../actionability.md#visible). [`param: selector`] that does not match any elements is considered not visible. ### param: Page.isVisible.selector = %%-input-selector-%% * since: v1.8 @@ -2714,8 +2761,7 @@ User can inspect selectors or perform manual steps while paused. Resume will con the place it was paused. :::note -This method requires Playwright to be started in a headed mode, with a falsy [`option: headless`] value in -the [`method: BrowserType.launch`]. +This method requires Playwright to be started in a headed mode, with a falsy [`option: BrowserType.launch.headless`] option. ::: ## async method: Page.pdf @@ -3092,11 +3138,9 @@ Things to keep in mind: :::warning Running the handler will alter your page state mid-test. For example it will change the currently focused element and move the mouse. Make sure that actions that run after the handler are self-contained and do not rely on the focus and mouse state being unchanged. -
-
+ For example, consider a test that calls [`method: Locator.focus`] followed by [`method: Keyboard.press`]. If your handler clicks a button between these two actions, the focused element most likely will be wrong, and key press will happen on the unexpected element. Use [`method: Locator.press`] instead to avoid this problem. -
-
+ Another example is a series of mouse actions, where [`method: Mouse.move`] is followed by [`method: Mouse.down`]. Again, when the handler runs between these two actions, the mouse position will be wrong during the mouse down. Prefer self-contained actions like [`method: Locator.click`] that do not rely on the state being unchanged by a handler. ::: @@ -3564,7 +3608,7 @@ Enabling routing disables http cache. - `url` <[string]|[RegExp]|[function]\([URL]\):[boolean]> A glob pattern, regex pattern or predicate receiving [URL] to match while routing. -When a [`option: baseURL`] via the context options was provided and the passed URL is a path, +When a [`option: Browser.newContext.baseURL`] via the context options was provided and the passed URL is a path, it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor. ### param: Page.route.handler @@ -3708,7 +3752,7 @@ await page.RouteWebSocketAsync("/ws", async ws => { * since: v1.48 - `url` <[string]|[RegExp]|[function]\([URL]\):[boolean]> -Only WebSockets with the url matching this pattern will be routed. A string pattern can be relative to the [`option: baseURL`] from the context options. +Only WebSockets with the url matching this pattern will be routed. A string pattern can be relative to the [`option: Browser.newContext.baseURL`] context option. ### param: Page.routeWebSocket.handler * since: v1.48 @@ -4049,12 +4093,16 @@ await page.GotoAsync("https://www.microsoft.com"); ### param: Page.setViewportSize.width * since: v1.10 * langs: csharp, java -- `width` <[int]> page width in pixels. +- `width` <[int]> + +Page width in pixels. ### param: Page.setViewportSize.height * since: v1.10 * langs: csharp, java -- `height` <[int]> page height in pixels. +- `height` <[int]> + +Page height in pixels. ## async method: Page.tap * since: v1.8 @@ -4072,7 +4120,7 @@ When all steps combined have not finished during the specified [`option: timeout [TimeoutError]. Passing zero timeout disables this. :::note -[`method: Page.tap`] the method will throw if [`option: hasTouch`] option of the browser context is false. +[`method: Page.tap`] the method will throw if [`option: Browser.newContext.hasTouch`] option of the browser context is false. ::: ### param: Page.tap.selector = %%-input-selector-%% @@ -4859,7 +4907,7 @@ await page.RunAndWaitForRequestAsync(async () => - `urlOrPredicate` <[string]|[RegExp]|[function]\([Request]\):[boolean]> Request URL string, regex or predicate receiving [Request] object. -When a [`option: baseURL`] via the context options was provided and the passed URL is a path, +When a [`option: Browser.newContext.baseURL`] via the context options was provided and the passed URL is a path, it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor. ### param: Page.waitForRequest.urlOrPredicate @@ -5003,7 +5051,7 @@ await page.RunAndWaitForResponseAsync(async () => - `urlOrPredicate` <[string]|[RegExp]|[function]\([Response]\):[boolean]> Request URL string, regex or predicate receiving [Response] object. -When a [`option: baseURL`] via the context options was provided and the passed URL is a path, +When a [`option: Browser.newContext.baseURL`] via the context options was provided and the passed URL is a path, it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor. ### param: Page.waitForResponse.urlOrPredicate @@ -5012,7 +5060,7 @@ it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/We - `urlOrPredicate` <[string]|[RegExp]|[function]\([Response]\):[boolean]|[Promise]<[boolean]>> Request URL string, regex or predicate receiving [Response] object. -When a [`option: baseURL`] via the context options was provided and the passed URL is a path, +When a [`option: Browser.newContext.baseURL`] via the context options was provided and the passed URL is a path, it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor. ### option: Page.waitForResponse.timeout diff --git a/docs/src/api/class-touchscreen.md b/docs/src/api/class-touchscreen.md index f37a12102c..bd6e1ed9f0 100644 --- a/docs/src/api/class-touchscreen.md +++ b/docs/src/api/class-touchscreen.md @@ -10,7 +10,7 @@ touchscreen can only be used in browser contexts that have been initialized with Dispatches a `touchstart` and `touchend` event with a single touch at the position ([`param: x`],[`param: y`]). :::note -[`method: Page.tap`] the method will throw if [`option: hasTouch`] option of the browser context is false. +[`method: Page.tap`] the method will throw if [`option: Browser.newContext.hasTouch`] option of the browser context is false. ::: ### param: Touchscreen.tap.x diff --git a/docs/src/api/class-tracing.md b/docs/src/api/class-tracing.md index 6e7541e4cb..065896925f 100644 --- a/docs/src/api/class-tracing.md +++ b/docs/src/api/class-tracing.md @@ -121,7 +121,7 @@ await context.Tracing.StopAsync(new() - `name` <[string]> If specified, intermediate trace files are going to be saved into the files with the -given name prefix inside the [`option: tracesDir`] folder specified in [`method: BrowserType.launch`]. +given name prefix inside the [`option: BrowserType.launch.tracesDir`] directory specified in [`method: BrowserType.launch`]. To specify the final trace zip file name, you need to pass `path` option to [`method: Tracing.stop`] instead. @@ -277,7 +277,7 @@ Trace name to be shown in the Trace Viewer. - `name` <[string]> If specified, intermediate trace files are going to be saved into the files with the -given name prefix inside the [`option: tracesDir`] folder specified in [`method: BrowserType.launch`]. +given name prefix inside the [`option: BrowserType.launch.tracesDir`] directory specified in [`method: BrowserType.launch`]. To specify the final trace zip file name, you need to pass `path` option to [`method: Tracing.stopChunk`] instead. diff --git a/docs/src/api/params.md b/docs/src/api/params.md index 4a0e3af657..1f9c03d77a 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md @@ -699,7 +699,7 @@ Logger sink for Playwright logging. - `content` ?<[HarContentPolicy]<"omit"|"embed"|"attach">> Optional setting to control resource content management. If `omit` is specified, content is not persisted. If `attach` is specified, resources are persisted as separate files or entries in the ZIP archive. If `embed` is specified, content is stored inline the HAR file as per HAR specification. Defaults to `attach` for `.zip` output files and to `embed` for all other file extensions. - `path` <[path]> Path on the filesystem to write the HAR file to. If the file name ends with `.zip`, `content: 'attach'` is used by default. - `mode` ?<[HarMode]<"full"|"minimal">> When set to `minimal`, only record information necessary for routing from HAR. This omits sizes, timing, page, cookies, security and other types of HAR information that are not used when replaying from HAR. Defaults to `full`. - - `urlFilter` ?<[string]|[RegExp]> A glob or regex pattern to filter requests that are stored in the HAR. When a [`option: baseURL`] via the context options was provided and the passed URL is a path, it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor. Defaults to none. + - `urlFilter` ?<[string]|[RegExp]> A glob or regex pattern to filter requests that are stored in the HAR. When a [`option: Browser.newContext.baseURL`] via the context options was provided and the passed URL is a path, it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor. Defaults to none. Enables [HAR](http://www.softwareishard.com/blog/har-12-spec) recording for all pages into `recordHar.path` file. If not specified, the HAR is not recorded. Make sure to await [`method: BrowserContext.close`] for the HAR to be @@ -765,8 +765,6 @@ not recorded. Make sure to call [`method: BrowserContext.close`] for videos to b * langs: csharp, java, python - alias-python: record_video_size - `recordVideoSize` <[Object]> - If `viewport` is not configured explicitly the video size defaults to 800x450. Actual picture of each page will be - scaled down if necessary to fit the specified size. - `width` <[int]> Video frame width. - `height` <[int]> Video frame height. @@ -1046,7 +1044,7 @@ Close the browser process on SIGHUP. Defaults to `true`. Whether to run browser in headless mode. More details for [Chromium](https://developers.google.com/web/updates/2017/04/headless-chrome) and [Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode). Defaults to `true` unless the -[`option: devtools`] option is `true`. +[`option: BrowserType.launch.devtools`] option is `true`. ## js-python-browser-option-firefoxuserprefs * langs: js, python diff --git a/docs/src/debug.md b/docs/src/debug.md index aff5077d3c..b812d0f670 100644 --- a/docs/src/debug.md +++ b/docs/src/debug.md @@ -451,7 +451,7 @@ will reset pre-configured user agent and device emulation. Playwright runs browsers in headless mode by default. To change this behavior, use `headless: false` as a launch option. -You can also use the [`option: slowMo`] option +You can also use the [`option: BrowserType.launch.slowMo`] option to slow down execution (by N milliseconds per operation) and follow along while debugging. ```js diff --git a/docs/src/dialogs.md b/docs/src/dialogs.md index 20037245ee..0aaa69aade 100644 --- a/docs/src/dialogs.md +++ b/docs/src/dialogs.md @@ -80,7 +80,7 @@ If there is no listener for [`event: Page.dialog`], all dialogs are automaticall ## beforeunload dialog -When [`method: Page.close`] is invoked with the truthy [`option: runBeforeUnload`] value, the page runs its unload handlers. This is the only case when [`method: Page.close`] does not wait for the page to actually close, because it might be that the page stays open in the end of the operation. +When [`method: Page.close`] is invoked with the truthy [`option: Page.close.runBeforeUnload`] value, the page runs its unload handlers. This is the only case when [`method: Page.close`] does not wait for the page to actually close, because it might be that the page stays open in the end of the operation. You can register a dialog handler to handle the `beforeunload` dialog yourself: diff --git a/docs/src/downloads.md b/docs/src/downloads.md index 9bce4f9d98..824b714d11 100644 --- a/docs/src/downloads.md +++ b/docs/src/downloads.md @@ -7,7 +7,7 @@ title: "Downloads" For every attachment downloaded by the page, [`event: Page.download`] event is emitted. All these attachments are downloaded into a temporary folder. You can obtain the download url, file name and payload stream using the [Download] object from the event. -You can specify where to persist downloaded files using the [`option: downloadsPath`] option in [`method: BrowserType.launch`]. +You can specify where to persist downloaded files using the [`option: BrowserType.launch.downloadsPath`] option in [`method: BrowserType.launch`]. :::note Downloaded files are deleted when the browser context that produced them is closed. diff --git a/docs/src/intro-java.md b/docs/src/intro-java.md index 424562ab83..4e1503f2a3 100644 --- a/docs/src/intro-java.md +++ b/docs/src/intro-java.md @@ -112,7 +112,7 @@ public class App { } ``` -By default, Playwright runs the browsers in headless mode. To see the browser UI, pass the `setHeadless(false)` flag while launching the browser. You can also use [`option: slowMo`] to slow down execution. Learn more in the debugging tools [section](./debug.md). +By default, Playwright runs the browsers in headless mode. To see the browser UI, [`option: BrowserType.launch.headless`] option to `false`. You can also use [`option: BrowserType.launch.slowMo`] to slow down execution. Learn more in the debugging tools [section](./debug.md). ```java playwright.firefox().launch(new BrowserType.LaunchOptions().setHeadless(false).setSlowMo(50)); diff --git a/docs/src/library-csharp.md b/docs/src/library-csharp.md index c659cbf1ee..db501645ea 100644 --- a/docs/src/library-csharp.md +++ b/docs/src/library-csharp.md @@ -48,7 +48,7 @@ Now run it. dotnet run ``` -By default, Playwright runs the browsers in headless mode. To see the browser UI, pass the `Headless = false` flag while launching the browser. You can also use [`option: slowMo`] to slow down execution. Learn more in the debugging tools [section](./debug.md). +By default, Playwright runs the browsers in headless mode. To see the browser UI, set [`option: BrowserType.launch.headless`] option to `false`. You can also use [`option: BrowserType.launch.slowMo`] to slow down execution. Learn more in the debugging tools [section](./debug.md). ```csharp await using var browser = await playwright.Firefox.LaunchAsync(new() diff --git a/docs/src/library-python.md b/docs/src/library-python.md index 8391ea92ef..f9063ea13a 100644 --- a/docs/src/library-python.md +++ b/docs/src/library-python.md @@ -75,7 +75,7 @@ with sync_playwright() as p: browser.close() ``` -By default, Playwright runs the browsers in headless mode. To see the browser UI, pass the `headless=False` flag while launching the browser. You can also use [`option: slowMo`] to slow down execution. Learn more in the debugging tools [section](./debug.md). +By default, Playwright runs the browsers in headless mode. To see the browser UI, set [`option: BrowserType.launch.headless`] option to `False`. You can also use [`option: BrowserType.launch.slowMo`] to slow down execution. Learn more in the debugging tools [section](./debug.md). ```py firefox.launch(headless=False, slow_mo=50) diff --git a/docs/src/release-notes-csharp.md b/docs/src/release-notes-csharp.md index b6a249b0eb..994d047794 100644 --- a/docs/src/release-notes-csharp.md +++ b/docs/src/release-notes-csharp.md @@ -21,8 +21,8 @@ The Network tab in the trace viewer has several nice improvements: - The `mcr.microsoft.com/playwright/dotnet:v1.47.0` now serves a Playwright image based on Ubuntu 24.04 Noble. To use the 22.04 jammy-based image, please use `mcr.microsoft.com/playwright/dotnet:v1.47.0-jammy` instead. - The `:latest`/`:focal`/`:jammy` tag for Playwright Docker images is no longer being published. Pin to a specific version for better stability and reproducibility. -- TLS client certificates can now be passed from memory by passing [`option: cert`] and [`option: key`] as byte arrays instead of file paths. -- [`option: noWaitAfter`] in [`method: Locator.selectOption`] was deprecated. +- TLS client certificates can now be passed from memory by passing [`option: Browser.newContext.clientCertificates.cert`] and [`option: Browser.newContext.clientCertificates.key`] as byte arrays instead of file paths. +- [`option: Locator.selectOption.noWaitAfter`] in [`method: Locator.selectOption`] was deprecated. - We've seen reports of WebGL in Webkit misbehaving on GitHub Actions `macos-13`. We recommend upgrading GitHub Actions to `macos-14`. ### Browser Versions @@ -284,7 +284,7 @@ await Expect(Page.GetByRole(AriaRole.Heading, new() { Name = "Light and easy" }) ### New APIs -- [`method: Page.pdf`] accepts two new options [`option: tagged`] and [`option: outline`]. +- [`method: Page.pdf`] accepts two new options [`option: Page.pdf.tagged`] and [`option: Page.pdf.outline`]. ### Announcements @@ -307,7 +307,7 @@ This version was also tested against the following stable channels: - New method [`method: Page.unrouteAll`] removes all routes registered by [`method: Page.route`] and [`method: Page.routeFromHAR`]. Optionally allows to wait for ongoing routes to finish, or ignore any errors from them. - New method [`method: BrowserContext.unrouteAll`] removes all routes registered by [`method: BrowserContext.route`] and [`method: BrowserContext.routeFromHAR`]. Optionally allows to wait for ongoing routes to finish, or ignore any errors from them. -- New option [`option: style`] in [`method: Page.screenshot`] and [`method: Locator.screenshot`] to add custom CSS to the page before taking a screenshot. +- New options [`option: Page.screenshot.style`] in [`method: Page.screenshot`] and [`option: Locator.screenshot.style`] in [`method: Locator.screenshot`] to add custom CSS to the page before taking a screenshot. ### Browser Versions @@ -345,8 +345,8 @@ await Expect(Page.GetByPlaceholder("Search docs")).ToHaveValueAsync("locator"); ### New APIs -- Option [`option: reason`] in [`method: Page.close`], [`method: BrowserContext.close`] and [`method: Browser.close`]. Close reason is reported for all operations interrupted by the closure. -- Option [`option: firefoxUserPrefs`] in [`method: BrowserType.launchPersistentContext`]. +- Options [`option: Page.close.reason`] in [`method: Page.close`], [`option: BrowserContext.close.reason`] in [`method: BrowserContext.close`] and [`option: Browser.close.reason`] in [`method: Browser.close`]. Close reason is reported for all operations interrupted by the closure. +- Option [`option: BrowserType.launchPersistentContext.firefoxUserPrefs`] in [`method: BrowserType.launchPersistentContext`]. ### Other Changes @@ -517,7 +517,7 @@ This version was also tested against the following stable channels: await Page.GetByRole(AriaRole.Button, new() { Name = "Dismiss" }).ClickAsync(); await newEmail.ClickAsync(); ``` -* Use new options [`option: hasNot`] and [`option: hasNotText`] in [`method: Locator.filter`] +* Use new options [`option: Locator.filter.hasNot`] and [`option: Locator.filter.hasNotText`] in [`method: Locator.filter`] to find elements that **do not match** certain conditions. ```csharp @@ -534,10 +534,10 @@ This version was also tested against the following stable channels: ### New APIs - [`method: Locator.or`] -- New option [`option: hasNot`] in [`method: Locator.filter`] -- New option [`option: hasNotText`] in [`method: Locator.filter`] +- New option [`option: Locator.filter.hasNot`] in [`method: Locator.filter`] +- New option [`option: Locator.filter.hasNotText`] in [`method: Locator.filter`] - [`method: LocatorAssertions.toBeAttached`] -- New option [`option: timeout`] in [`method: Route.fetch`] +- New option [`option: Route.fetch.timeout`] in [`method: Route.fetch`] ### ⚠️ Breaking change @@ -560,9 +560,9 @@ This version was also tested against the following stable channels: ### New APIs -- New options [`option: updateMode`] and [`option: updateContent`] in [`method: Page.routeFromHAR`] and [`method: BrowserContext.routeFromHAR`]. +- New options [`option: Page.routeFromHAR.updateMode`] and [`option: Page.routeFromHAR.updateContent`] in [`method: Page.routeFromHAR`] and [`method: BrowserContext.routeFromHAR`]. - Chaining existing locator objects, see [locator docs](./locators.md#matching-inside-a-locator) for details. -- New option [`option: name`] in method [`method: Tracing.startChunk`]. +- New option [`option: Tracing.startChunk.name`] in method [`method: Tracing.startChunk`]. ### Browser Versions diff --git a/docs/src/release-notes-java.md b/docs/src/release-notes-java.md index 89a49f7451..c50d5a67c4 100644 --- a/docs/src/release-notes-java.md +++ b/docs/src/release-notes-java.md @@ -21,8 +21,8 @@ The Network tab in the trace viewer has several nice improvements: - The `mcr.microsoft.com/playwright/java:v1.47.0` now serves a Playwright image based on Ubuntu 24.04 Noble. To use the 22.02 jammy-based image, please use `mcr.microsoft.com/playwright/java:v1.47.0-jammy` instead. - The `:latest`/`:focal`/`:jammy` tag for Playwright Docker images is no longer being published. Pin to a specific version for better stability and reproducibility. -- TLS client certificates can now be passed from memory by passing [`option: cert`] and [`option: key`] as byte arrays instead of file paths. -- [`option: noWaitAfter`] in [`method: Locator.selectOption`] was deprecated. +- TLS client certificates can now be passed from memory by passing [`option: Browser.newContext.clientCertificates.cert`] and [`option: Browser.newContext.clientCertificates.key`] as byte arrays instead of file paths. +- [`option: Locator.selectOption.noWaitAfter`] in [`method: Locator.selectOption`] was deprecated. - We've seen reports of WebGL in Webkit misbehaving on GitHub Actions `macos-13`. We recommend upgrading GitHub Actions to `macos-14`. ### Browser Versions @@ -349,7 +349,7 @@ assertThat(page.getByRole(AriaRole.HEADING, new Page.GetByRoleOptions().setName( ### New APIs -- [`method: Page.pdf`] accepts two new options [`option: tagged`] and [`option: outline`]. +- [`method: Page.pdf`] accepts two new options [`option: Page.pdf.tagged`] and [`option: Page.pdf.outline`]. ### Announcements @@ -372,7 +372,7 @@ This version was also tested against the following stable channels: - New method [`method: Page.unrouteAll`] removes all routes registered by [`method: Page.route`] and [`method: Page.routeFromHAR`]. - New method [`method: BrowserContext.unrouteAll`] removes all routes registered by [`method: BrowserContext.route`] and [`method: BrowserContext.routeFromHAR`]. -- New option [`option: style`] in [`method: Page.screenshot`] and [`method: Locator.screenshot`] to add custom CSS to the page before taking a screenshot. +- New options [`option: Page.screenshot.style`] in [`method: Page.screenshot`] and [`option: Locator.screenshot.style`] in [`method: Locator.screenshot`] to add custom CSS to the page before taking a screenshot. ### Browser Versions @@ -410,8 +410,8 @@ assertThat(page.getByPlaceholder("Search docs")).hasValue("locator"); ### New APIs -- Option [`option: reason`] in [`method: Page.close`], [`method: BrowserContext.close`] and [`method: Browser.close`]. Close reason is reported for all operations interrupted by the closure. -- Option [`option: firefoxUserPrefs`] in [`method: BrowserType.launchPersistentContext`]. +- Options [`option: Page.close.reason`] in [`method: Page.close`], [`option: BrowserContext.close.reason`] in [`method: BrowserContext.close`] and [`option: Browser.close.reason`] in [`method: Browser.close`]. Close reason is reported for all operations interrupted by the closure. +- Option [`option: BrowserType.launchPersistentContext.firefoxUserPrefs`] in [`method: BrowserType.launchPersistentContext`]. ### Other Changes @@ -597,7 +597,7 @@ This version was also tested against the following stable channels: page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Dismiss")).click(); newEmail.click(); ``` -* Use new options [`option: hasNot`] and [`option: hasNotText`] in [`method: Locator.filter`] +* Use new options [`option: Locator.filter.hasNot`] and [`option: Locator.filter.hasNotText`] in [`method: Locator.filter`] to find elements that **do not match** certain conditions. ```java @@ -616,10 +616,10 @@ This version was also tested against the following stable channels: ### New APIs - [`method: Locator.or`] -- New option [`option: hasNot`] in [`method: Locator.filter`] -- New option [`option: hasNotText`] in [`method: Locator.filter`] +- New option [`option: Locator.filter.hasNot`] in [`method: Locator.filter`] +- New option [`option: Locator.filter.hasNotText`] in [`method: Locator.filter`] - [`method: LocatorAssertions.toBeAttached`] -- New option [`option: timeout`] in [`method: Route.fetch`] +- New option [`option: Route.fetch.timeout`] in [`method: Route.fetch`] ### Other highlights @@ -646,9 +646,9 @@ This version was also tested against the following stable channels: ### New APIs -- New options [`option: updateMode`] and [`option: updateContent`] in [`method: Page.routeFromHAR`] and [`method: BrowserContext.routeFromHAR`]. +- New options [`option: Page.routeFromHAR.updateMode`] and [`option: Page.routeFromHAR.updateContent`] in [`method: Page.routeFromHAR`] and [`method: BrowserContext.routeFromHAR`]. - Chaining existing locator objects, see [locator docs](./locators.md#matching-inside-a-locator) for details. -- New option [`option: name`] in method [`method: Tracing.startChunk`]. +- New option [`option: Tracing.startChunk.name`] in method [`method: Tracing.startChunk`]. ### Browser Versions diff --git a/docs/src/release-notes-js.md b/docs/src/release-notes-js.md index a89b79c5ce..4676a9dfb1 100644 --- a/docs/src/release-notes-js.md +++ b/docs/src/release-notes-js.md @@ -44,16 +44,16 @@ test('query params', async ({ request }) => { ); // ... }); -``` +``` ### Miscellaneous - The `mcr.microsoft.com/playwright:v1.47.0` now serves a Playwright image based on Ubuntu 24.04 Noble. To use the 22.04 jammy-based image, please use `mcr.microsoft.com/playwright:v1.47.0-jammy` instead. -- New option [`option: behavior`] in [`method: Page.removeAllListeners`], [`method: Browser.removeAllListeners`] and [`method: BrowserContext.removeAllListeners`] to wait for ongoing listeners to complete. -- TLS client certificates can now be passed from memory by passing [`option: cert`] and [`option: key`] as buffers instead of file paths. +- New options [`option: Page.removeAllListeners.behavior`], [`option: Browser.removeAllListeners.behavior`] and [`option: BrowserContext.removeAllListeners.behavior`] to wait for ongoing listeners to complete. +- TLS client certificates can now be passed from memory by passing [`option: Browser.newContext.clientCertificates.cert`] and [`option: Browser.newContext.clientCertificates.key`] as buffers instead of file paths. - Attachments with a `text/html` content type can now be opened in a new tab in the HTML report. This is useful for including third-party reports or other HTML content in the Playwright test report and distributing it to your team. -- [`option: noWaitAfter`] in [`method: Locator.selectOption`] was deprecated. +- [`option: Locator.selectOption.noWaitAfter`] option in [`method: Locator.selectOption`] was deprecated. - We've seen reports of WebGL in Webkit misbehaving on GitHub Actions `macos-13`. We recommend upgrading GitHub Actions to `macos-14`. ### Browser Versions @@ -528,7 +528,7 @@ This version was also tested against the following stable channels: - New method [`method: Page.unrouteAll`] removes all routes registered by [`method: Page.route`] and [`method: Page.routeFromHAR`]. Optionally allows to wait for ongoing routes to finish, or ignore any errors from them. - New method [`method: BrowserContext.unrouteAll`] removes all routes registered by [`method: BrowserContext.route`] and [`method: BrowserContext.routeFromHAR`]. Optionally allows to wait for ongoing routes to finish, or ignore any errors from them. -- New option [`option: style`] in [`method: Page.screenshot`] and [`method: Locator.screenshot`] to add custom CSS to the page before taking a screenshot. +- New options [`option: Page.screenshot.style`] in [`method: Page.screenshot`] and [`option: Locator.screenshot.style`] in [`method: Locator.screenshot`] to add custom CSS to the page before taking a screenshot. - New option `stylePath` for methods [`method: PageAssertions.toHaveScreenshot#1`] and [`method: LocatorAssertions.toHaveScreenshot#1`] to apply a custom stylesheet while making the screenshot. - New `fileName` option for [Blob reporter](./test-reporters#blob-reporter), to specify the name of the report to be created. @@ -577,8 +577,8 @@ test('test', async ({ page }) => { ### New APIs -- Option [`option: reason`] in [`method: Page.close`], [`method: BrowserContext.close`] and [`method: Browser.close`]. Close reason is reported for all operations interrupted by the closure. -- Option [`option: firefoxUserPrefs`] in [`method: BrowserType.launchPersistentContext`]. +- Options [`option: Page.close.reason`] in [`method: Page.close`], [`option: BrowserContext.close.reason`] in [`method: BrowserContext.close`] and [`option: Browser.close.reason`] in [`method: Browser.close`]. Close reason is reported for all operations interrupted by the closure. +- Option [`option: BrowserType.launchPersistentContext.firefoxUserPrefs`] in [`method: BrowserType.launchPersistentContext`]. ### Other Changes @@ -1047,7 +1047,7 @@ This version was also tested against the following stable channels: await page.getByRole('button', { name: 'Dismiss' }).click(); await newEmail.click(); ``` -* Use new options [`option: hasNot`] and [`option: hasNotText`] in [`method: Locator.filter`] +* Use new options [`option: Locator.filter.hasNot`] and [`option: Locator.filter.hasNotText`] in [`method: Locator.filter`] to find elements that **do not match** certain conditions. ```js @@ -1064,10 +1064,10 @@ This version was also tested against the following stable channels: ### New APIs - [`method: Locator.or`] -- New option [`option: hasNot`] in [`method: Locator.filter`] -- New option [`option: hasNotText`] in [`method: Locator.filter`] +- New option [`option: Locator.filter.hasNot`] in [`method: Locator.filter`] +- New option [`option: Locator.filter.hasNotText`] in [`method: Locator.filter`] - [`method: LocatorAssertions.toBeAttached`] -- New option [`option: timeout`] in [`method: Route.fetch`] +- New option [`option: Route.fetch.timeout`] in [`method: Route.fetch`] - [`method: Reporter.onExit`] ### ⚠️ Breaking change @@ -1107,10 +1107,10 @@ npx playwright test --ui ### New APIs -- New options [`option: updateMode`] and [`option: updateContent`] in [`method: Page.routeFromHAR`] and [`method: BrowserContext.routeFromHAR`]. +- New options [`option: Page.routeFromHAR.updateMode`] and [`option: Page.routeFromHAR.updateContent`] in [`method: Page.routeFromHAR`] and [`method: BrowserContext.routeFromHAR`]. - Chaining existing locator objects, see [locator docs](./locators.md#matching-inside-a-locator) for details. - New property [`property: TestInfo.testId`]. -- New option [`option: name`] in method [`method: Tracing.startChunk`]. +- New option [`option: Tracing.startChunk.name`] in method [`method: Tracing.startChunk`]. ### ⚠️ Breaking change in component tests diff --git a/docs/src/release-notes-python.md b/docs/src/release-notes-python.md index 7defa1c0d1..033c269750 100644 --- a/docs/src/release-notes-python.md +++ b/docs/src/release-notes-python.md @@ -21,8 +21,8 @@ The Network tab in the trace viewer has several nice improvements: - The `mcr.microsoft.com/playwright/python:v1.47.0` now serves a Playwright image based on Ubuntu 24.04 Noble. To use the 22.04 jammy-based image, please use `mcr.microsoft.com/playwright/python:v1.47.0-jammy` instead. - The `:latest`/`:focal`/`:jammy` tag for Playwright Docker images is no longer being published. Pin to a specific version for better stability and reproducibility. -- TLS client certificates can now be passed from memory by passing [`option: cert`] and [`option: key`] as bytes instead of file paths. -- [`option: noWaitAfter`] in [`method: Locator.selectOption`] was deprecated. +- TLS client certificates can now be passed from memory by passing [`option: Browser.newContext.clientCertificates.cert`] and [`option: Browser.newContext.clientCertificates.key`] as bytes instead of file paths. +- [`option: Locator.selectOption.noWaitAfter`] in [`method: Locator.selectOption`] was deprecated. - We've seen reports of WebGL in Webkit misbehaving on GitHub Actions `macos-13`. We recommend upgrading GitHub Actions to `macos-14`. ### Browser Versions @@ -260,7 +260,7 @@ expect(page.get_by_role("heading", name="Light and easy")).to_be_visible() ### New APIs -- [`method: Page.pdf`] accepts two new options [`option: tagged`] and [`option: outline`]. +- [`method: Page.pdf`] accepts two new options [`option: Page.pdf.tagged`] and [`option: Page.pdf.outline`]. ### Announcements @@ -283,7 +283,7 @@ This version was also tested against the following stable channels: - New method [`method: Page.unrouteAll`] removes all routes registered by [`method: Page.route`] and [`method: Page.routeFromHAR`]. Optionally allows to wait for ongoing routes to finish, or ignore any errors from them. - New method [`method: BrowserContext.unrouteAll`] removes all routes registered by [`method: BrowserContext.route`] and [`method: BrowserContext.routeFromHAR`]. Optionally allows to wait for ongoing routes to finish, or ignore any errors from them. -- New option [`option: style`] in [`method: Page.screenshot`] and [`method: Locator.screenshot`] to add custom CSS to the page before taking a screenshot. +- New options [`option: Page.screenshot.style`] in [`method: Page.screenshot`] and [`option: Locator.screenshot.style`] in [`method: Locator.screenshot`] to add custom CSS to the page before taking a screenshot. ### Browser Versions @@ -324,8 +324,8 @@ def test_example(page: Page) -> None: ### New APIs -- Option [`option: reason`] in [`method: Page.close`], [`method: BrowserContext.close`] and [`method: Browser.close`]. Close reason is reported for all operations interrupted by the closure. -- Option [`option: firefoxUserPrefs`] in [`method: BrowserType.launchPersistentContext`]. +- Options [`option: Page.close.reason`] in [`method: Page.close`], [`option: BrowserContext.close.reason`] in [`method: BrowserContext.close`] and [`option: Browser.close.reason`] in [`method: Browser.close`]. Close reason is reported for all operations interrupted by the closure. +- Option [`option: BrowserType.launchPersistentContext.firefoxUserPrefs`] in [`method: BrowserType.launchPersistentContext`]. ### Other Changes @@ -504,7 +504,7 @@ This version was also tested against the following stable channels: page.get_by_role("button", name="Dismiss").click() new_email.click() ``` -* Use new options [`option: hasNot`] and [`option: hasNotText`] in [`method: Locator.filter`] +* Use new options [`option: Locator.filter.hasNot`] and [`option: Locator.filter.hasNotText`] in [`method: Locator.filter`] to find elements that **do not match** certain conditions. ```python @@ -520,10 +520,10 @@ This version was also tested against the following stable channels: ### New APIs - [`method: Locator.or`] -- New option [`option: hasNot`] in [`method: Locator.filter`] -- New option [`option: hasNotText`] in [`method: Locator.filter`] +- New option [`option: Locator.filter.hasNot`] in [`method: Locator.filter`] +- New option [`option: Locator.filter.hasNotText`] in [`method: Locator.filter`] - [`method: LocatorAssertions.toBeAttached`] -- New option [`option: timeout`] in [`method: Route.fetch`] +- New option [`option: Route.fetch.timeout`] in [`method: Route.fetch`] ### ⚠️ Breaking change @@ -547,9 +547,9 @@ This version was also tested against the following stable channels: ### New APIs - Custom expect message, see [test assertions documentation](./test-assertions.md#custom-expect-message). -- New options [`option: updateMode`] and [`option: updateContent`] in [`method: Page.routeFromHAR`] and [`method: BrowserContext.routeFromHAR`]. +- New options [`option: Page.routeFromHAR.updateMode`] and [`option: Page.routeFromHAR.updateContent`] in [`method: Page.routeFromHAR`] and [`method: BrowserContext.routeFromHAR`]. - Chaining existing locator objects, see [locator docs](./locators.md#matching-inside-a-locator) for details. -- New option [`option: name`] in method [`method: Tracing.startChunk`]. +- New option [`option: Tracing.startChunk.name`] in method [`method: Tracing.startChunk`]. ### Browser Versions diff --git a/docs/src/selenium-grid.md b/docs/src/selenium-grid.md index 636bfb6d43..88a08684f2 100644 --- a/docs/src/selenium-grid.md +++ b/docs/src/selenium-grid.md @@ -10,8 +10,6 @@ Playwright can connect to [Selenium Grid Hub](https://www.selenium.dev/documenta :::warning There is a risk of Playwright integration with Selenium Grid Hub breaking in the future. Make sure you weight risks against benefits before using it. -
-
More details diff --git a/docs/src/test-api/class-test.md b/docs/src/test-api/class-test.md index b6ae7d1522..4706d462f0 100644 --- a/docs/src/test-api/class-test.md +++ b/docs/src/test-api/class-test.md @@ -1713,7 +1713,8 @@ Whether to box the step in the report. Defaults to `false`. When the step is box ### option: Test.step.location * since: v1.48 - `location` <[Location]> -Specifies a custom location for the step to be shown in test reports. By default, location of the [`method: Test.step`] call is shown. + +Specifies a custom location for the step to be shown in test reports and trace viewer. By default, location of the [`method: Test.step`] call is shown. ## method: Test.use * since: v1.10 diff --git a/docs/src/test-api/class-testconfig.md b/docs/src/test-api/class-testconfig.md index 4130bdd66d..d013f5e4ea 100644 --- a/docs/src/test-api/class-testconfig.md +++ b/docs/src/test-api/class-testconfig.md @@ -41,12 +41,12 @@ export default defineConfig({ - type: ?<[Object]> - `timeout` ?<[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms. - `toHaveScreenshot` ?<[Object]> Configuration for the [`method: PageAssertions.toHaveScreenshot#1`] method. - - `animations` ?<[ScreenshotAnimations]<"allow"|"disabled">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disabled"`. - - `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`. + - `animations` ?<[ScreenshotAnimations]<"allow"|"disabled">> See [`option: Page.screenshot.animations`] in [`method: Page.screenshot`]. Defaults to `"disabled"`. + - `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: Page.screenshot.caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`. - `maxDiffPixels` ?<[int]> An acceptable amount of pixels that could be different, unset by default. - `maxDiffPixelRatio` ?<[float]> An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default. - - `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: scale`] in [`method: Page.screenshot`]. Defaults to `"css"`. - - `stylePath` ?<[string]|[Array]<[string]>> See [`option: style`] in [`method: Page.screenshot`]. + - `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: Page.screenshot.scale`] in [`method: Page.screenshot`]. Defaults to `"css"`. + - `stylePath` ?<[string]|[Array]<[string]>> See [`option: Page.screenshot.style`] in [`method: Page.screenshot`]. - `threshold` ?<[float]> An acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`. - `toMatchSnapshot` ?<[Object]> Configuration for the [`method: SnapshotAssertions.toMatchSnapshot#1`] method. - `maxDiffPixels` ?<[int]> An acceptable amount of pixels that could be different, unset by default. diff --git a/docs/src/test-api/class-testinfo.md b/docs/src/test-api/class-testinfo.md index 38c706adf7..93cbc93b75 100644 --- a/docs/src/test-api/class-testinfo.md +++ b/docs/src/test-api/class-testinfo.md @@ -216,7 +216,9 @@ Test function as passed to `test(title, testFunction)`. Tags that apply to the test. Learn more about [tags](../test-annotations.md#tag-tests). -Note that any changes made to this list while the test is running will not be visible to test reporters. +:::note +Any changes made to this list while the test is running will not be visible to test reporters. +::: ## property: TestInfo.testId * since: v1.32 diff --git a/docs/src/test-api/class-testproject.md b/docs/src/test-api/class-testproject.md index 5e7c911a65..d93286fa26 100644 --- a/docs/src/test-api/class-testproject.md +++ b/docs/src/test-api/class-testproject.md @@ -94,10 +94,10 @@ export default defineConfig({ - `threshold` ?<[float]> an acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`. - `maxDiffPixels` ?<[int]> an acceptable amount of pixels that could be different, unset by default. - `maxDiffPixelRatio` ?<[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default. - - `animations` ?<[ScreenshotAnimations]<"allow"|"disabled">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disabled"`. - - `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`. - - `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: scale`] in [`method: Page.screenshot`]. Defaults to `"css"`. - - `stylePath` ?<[string]|[Array]<[string]>> See [`option: style`] in [`method: Page.screenshot`]. + - `animations` ?<[ScreenshotAnimations]<"allow"|"disabled">> See [`option: Page.screenshot.animations`] in [`method: Page.screenshot`]. Defaults to `"disabled"`. + - `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: Page.screenshot.caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`. + - `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: Page.screenshot.scale`] in [`method: Page.screenshot`]. Defaults to `"css"`. + - `stylePath` ?<[string]|[Array]<[string]>> See [`option: Page.screenshot.style`] in [`method: Page.screenshot`]. - `toMatchSnapshot` ?<[Object]> Configuration for the [`method: SnapshotAssertions.toMatchSnapshot#1`] method. - `threshold` ?<[float]> an acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`. - `maxDiffPixels` ?<[int]> an acceptable amount of pixels that could be different, unset by default. diff --git a/docs/src/trace-viewer.md b/docs/src/trace-viewer.md index 207646c1d7..55338c41b9 100644 --- a/docs/src/trace-viewer.md +++ b/docs/src/trace-viewer.md @@ -31,7 +31,7 @@ In the Actions tab you can see what locator was used for every action and how lo ### Screenshots -When tracing with the [`option: screenshots`] option turned on (default), each trace records a screencast and renders it as a film strip. You can hover over the film strip to see a magnified image of for each action and state which helps you easily find the action you want to inspect. +When tracing with the [`option: Tracing.start.screenshots`] option turned on (default), each trace records a screencast and renders it as a film strip. You can hover over the film strip to see a magnified image of for each action and state which helps you easily find the action you want to inspect. Double click on an action to see the time range for that action. You can use the slider in the timeline to increase the actions selected and these will be shown in the Actions tab and all console logs and network logs will be filtered to only show the logs for the actions selected. @@ -40,7 +40,7 @@ Double click on an action to see the time range for that action. You can use the ### Snapshots -When tracing with the [`option: snapshots`] option turned on (default), Playwright captures a set of complete DOM snapshots for each action. Depending on the type of the action, it will capture: +When tracing with the [`option: Tracing.start.snapshots`] option turned on (default), Playwright captures a set of complete DOM snapshots for each action. Depending on the type of the action, it will capture: | Type | Description | |------|-------------| @@ -48,8 +48,6 @@ When tracing with the [`option: snapshots`] option turned on (default), Playwrig |Action|A snapshot at the moment of the performed input. This type of snapshot is especially useful when exploring where exactly Playwright clicked.| |After|A snapshot after the action.| -
- Here is what the typical Action snapshot looks like: ![action tab in trace viewer](https://github.com/microsoft/playwright/assets/13063165/7168d549-eb0a-4964-9c93-483f03711fa9) diff --git a/packages/playwright-core/browsers.json b/packages/playwright-core/browsers.json index d8605f9ed9..aea7b53ef7 100644 --- a/packages/playwright-core/browsers.json +++ b/packages/playwright-core/browsers.json @@ -3,9 +3,9 @@ "browsers": [ { "name": "chromium", - "revision": "1136", + "revision": "1137", "installByDefault": true, - "browserVersion": "130.0.6723.6" + "browserVersion": "130.0.6723.19" }, { "name": "chromium-tip-of-tree", @@ -27,7 +27,7 @@ }, { "name": "webkit", - "revision": "2082", + "revision": "2083", "installByDefault": true, "revisionOverrides": { "mac10.14": "1446", diff --git a/packages/playwright-core/src/client/page.ts b/packages/playwright-core/src/client/page.ts index 66842cad0b..6654294edd 100644 --- a/packages/playwright-core/src/client/page.ts +++ b/packages/playwright-core/src/client/page.ts @@ -478,8 +478,8 @@ export class Page extends ChannelOwner implements api.Page return Response.fromNullable((await this._channel.goForward({ ...options, waitUntil })).response); } - async forceGarbageCollection() { - await this._channel.forceGarbageCollection(); + async requestGC() { + await this._channel.requestGC(); } async emulateMedia(options: { media?: 'screen' | 'print' | null, colorScheme?: 'dark' | 'light' | 'no-preference' | null, reducedMotion?: 'reduce' | 'no-preference' | null, forcedColors?: 'active' | 'none' | null } = {}) { diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 9b36ad8883..4069b906c7 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -1137,8 +1137,8 @@ scheme.PageGoForwardParams = tObject({ scheme.PageGoForwardResult = tObject({ response: tOptional(tChannel(['Response'])), }); -scheme.PageForceGarbageCollectionParams = tOptional(tObject({})); -scheme.PageForceGarbageCollectionResult = tOptional(tObject({})); +scheme.PageRequestGCParams = tOptional(tObject({})); +scheme.PageRequestGCResult = tOptional(tObject({})); scheme.PageRegisterLocatorHandlerParams = tObject({ selector: tString, noWaitAfter: tOptional(tBoolean), diff --git a/packages/playwright-core/src/server/bidi/bidiFirefox.ts b/packages/playwright-core/src/server/bidi/bidiFirefox.ts index 737fc97eaa..204cabdef7 100644 --- a/packages/playwright-core/src/server/bidi/bidiFirefox.ts +++ b/packages/playwright-core/src/server/bidi/bidiFirefox.ts @@ -26,6 +26,7 @@ import type { ConnectionTransport } from '../transport'; import type * as types from '../types'; import { BidiBrowser } from './bidiBrowser'; import { kBrowserCloseMessageId } from './bidiConnection'; +import { createProfile } from './third_party/firefoxPrefs'; export class BidiFirefox extends BrowserType { constructor(parent: SdkObject) { @@ -72,6 +73,13 @@ export class BidiFirefox extends BrowserType { transport.send({ method: 'browser.close', params: {}, id: kBrowserCloseMessageId }); } + override async prepareUserDataDir(options: types.LaunchOptions, userDataDir: string): Promise { + await createProfile({ + path: userDataDir, + preferences: options.firefoxUserPrefs || {}, + }); + } + override defaultArgs(options: types.LaunchOptions, isPersistent: boolean, userDataDir: string): string[] { const { args = [], headless } = options; const userDataDirArg = args.find(arg => arg.startsWith('-profile') || arg.startsWith('--profile')); diff --git a/packages/playwright-core/src/server/bidi/bidiPage.ts b/packages/playwright-core/src/server/bidi/bidiPage.ts index a50217975a..56bb43cb1a 100644 --- a/packages/playwright-core/src/server/bidi/bidiPage.ts +++ b/packages/playwright-core/src/server/bidi/bidiPage.ts @@ -340,7 +340,7 @@ export class BidiPage implements PageDelegate { }).then(() => true).catch(() => false); } - async forceGarbageCollection(): Promise { + async requestGC(): Promise { throw new Error('Method not implemented.'); } diff --git a/packages/playwright-core/src/server/bidi/third_party/firefoxPrefs.ts b/packages/playwright-core/src/server/bidi/third_party/firefoxPrefs.ts new file mode 100644 index 0000000000..7c08bebe6d --- /dev/null +++ b/packages/playwright-core/src/server/bidi/third_party/firefoxPrefs.ts @@ -0,0 +1,282 @@ +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +import fs from 'fs'; +import path from 'path'; + +/* eslint-disable curly, indent */ + +interface ProfileOptions { + preferences: Record; + path: string; +} + +export async function createProfile(options: ProfileOptions): Promise { + if (!fs.existsSync(options.path)) { + await fs.promises.mkdir(options.path, { + recursive: true, + }); + } + await writePreferences({ + preferences: { + ...defaultProfilePreferences(options.preferences), + ...options.preferences, + }, + path: options.path, + }); +} + +function defaultProfilePreferences( + extraPrefs: Record +): Record { + const server = 'dummy.test'; + + const defaultPrefs = { + // Make sure Shield doesn't hit the network. + 'app.normandy.api_url': '', + // Disable Firefox old build background check + 'app.update.checkInstallTime': false, + // Disable automatically upgrading Firefox + 'app.update.disabledForTesting': true, + + // Increase the APZ content response timeout to 1 minute + 'apz.content_response_timeout': 60000, + + // Prevent various error message on the console + // jest-puppeteer asserts that no error message is emitted by the console + 'browser.contentblocking.features.standard': + '-tp,tpPrivate,cookieBehavior0,-cm,-fp', + + // Enable the dump function: which sends messages to the system + // console + // https://bugzilla.mozilla.org/show_bug.cgi?id=1543115 + 'browser.dom.window.dump.enabled': true, + // Disable topstories + 'browser.newtabpage.activity-stream.feeds.system.topstories': false, + // Always display a blank page + 'browser.newtabpage.enabled': false, + // Background thumbnails in particular cause grief: and disabling + // thumbnails in general cannot hurt + 'browser.pagethumbnails.capturing_disabled': true, + + // Disable safebrowsing components. + 'browser.safebrowsing.blockedURIs.enabled': false, + 'browser.safebrowsing.downloads.enabled': false, + 'browser.safebrowsing.malware.enabled': false, + 'browser.safebrowsing.phishing.enabled': false, + + // Disable updates to search engines. + 'browser.search.update': false, + // Do not restore the last open set of tabs if the browser has crashed + 'browser.sessionstore.resume_from_crash': false, + // Skip check for default browser on startup + 'browser.shell.checkDefaultBrowser': false, + + // Disable newtabpage + 'browser.startup.homepage': 'about:blank', + // Do not redirect user when a milstone upgrade of Firefox is detected + 'browser.startup.homepage_override.mstone': 'ignore', + // Start with a blank page about:blank + 'browser.startup.page': 0, + + // Do not allow background tabs to be zombified on Android: otherwise for + // tests that open additional tabs: the test harness tab itself might get + // unloaded + 'browser.tabs.disableBackgroundZombification': false, + // Do not warn when closing all other open tabs + 'browser.tabs.warnOnCloseOtherTabs': false, + // Do not warn when multiple tabs will be opened + 'browser.tabs.warnOnOpen': false, + + // Do not automatically offer translations, as tests do not expect this. + 'browser.translations.automaticallyPopup': false, + + // Disable the UI tour. + 'browser.uitour.enabled': false, + // Turn off search suggestions in the location bar so as not to trigger + // network connections. + 'browser.urlbar.suggest.searches': false, + // Disable first run splash page on Windows 10 + 'browser.usedOnWindows10.introURL': '', + // Do not warn on quitting Firefox + 'browser.warnOnQuit': false, + + // Defensively disable data reporting systems + 'datareporting.healthreport.documentServerURI': `http://${server}/dummy/healthreport/`, + 'datareporting.healthreport.logging.consoleEnabled': false, + 'datareporting.healthreport.service.enabled': false, + 'datareporting.healthreport.service.firstRun': false, + 'datareporting.healthreport.uploadEnabled': false, + + // Do not show datareporting policy notifications which can interfere with tests + 'datareporting.policy.dataSubmissionEnabled': false, + 'datareporting.policy.dataSubmissionPolicyBypassNotification': true, + + // DevTools JSONViewer sometimes fails to load dependencies with its require.js. + // This doesn't affect Puppeteer but spams console (Bug 1424372) + 'devtools.jsonview.enabled': false, + + // Disable popup-blocker + 'dom.disable_open_during_load': false, + + // Enable the support for File object creation in the content process + // Required for |Page.setFileInputFiles| protocol method. + 'dom.file.createInChild': true, + + // Disable the ProcessHangMonitor + 'dom.ipc.reportProcessHangs': false, + + // Disable slow script dialogues + 'dom.max_chrome_script_run_time': 0, + 'dom.max_script_run_time': 0, + + // Only load extensions from the application and user profile + // AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION + 'extensions.autoDisableScopes': 0, + 'extensions.enabledScopes': 5, + + // Disable metadata caching for installed add-ons by default + 'extensions.getAddons.cache.enabled': false, + + // Disable installing any distribution extensions or add-ons. + 'extensions.installDistroAddons': false, + + // Disabled screenshots extension + 'extensions.screenshots.disabled': true, + + // Turn off extension updates so they do not bother tests + 'extensions.update.enabled': false, + + // Turn off extension updates so they do not bother tests + 'extensions.update.notifyUser': false, + + // Make sure opening about:addons will not hit the network + 'extensions.webservice.discoverURL': `http://${server}/dummy/discoveryURL`, + + // Allow the application to have focus even it runs in the background + 'focusmanager.testmode': true, + + // Disable useragent updates + 'general.useragent.updates.enabled': false, + + // Always use network provider for geolocation tests so we bypass the + // macOS dialog raised by the corelocation provider + 'geo.provider.testing': true, + + // Do not scan Wifi + 'geo.wifi.scan': false, + + // No hang monitor + 'hangmonitor.timeout': 0, + + // Show chrome errors and warnings in the error console + 'javascript.options.showInConsole': true, + + // Disable download and usage of OpenH264: and Widevine plugins + 'media.gmp-manager.updateEnabled': false, + + // Disable the GFX sanity window + 'media.sanity-test.disabled': true, + + // Disable experimental feature that is only available in Nightly + 'network.cookie.sameSite.laxByDefault': false, + + // Do not prompt for temporary redirects + 'network.http.prompt-temp-redirect': false, + + // Disable speculative connections so they are not reported as leaking + // when they are hanging around + 'network.http.speculative-parallel-limit': 0, + + // Do not automatically switch between offline and online + 'network.manage-offline-status': false, + + // Make sure SNTP requests do not hit the network + 'network.sntp.pools': server, + + // Disable Flash. + 'plugin.state.flash': 0, + + 'privacy.trackingprotection.enabled': false, + + // Can be removed once Firefox 89 is no longer supported + // https://bugzilla.mozilla.org/show_bug.cgi?id=1710839 + 'remote.enabled': true, + + // Don't do network connections for mitm priming + 'security.certerrors.mitm.priming.enabled': false, + + // Local documents have access to all other local documents, + // including directory listings + 'security.fileuri.strict_origin_policy': false, + + // Do not wait for the notification button security delay + 'security.notification_enable_delay': 0, + + // Ensure blocklist updates do not hit the network + 'services.settings.server': `http://${server}/dummy/blocklist/`, + + // Do not automatically fill sign-in forms with known usernames and + // passwords + 'signon.autofillForms': false, + + // Disable password capture, so that tests that include forms are not + // influenced by the presence of the persistent doorhanger notification + 'signon.rememberSignons': false, + + // Disable first-run welcome page + 'startup.homepage_welcome_url': 'about:blank', + + // Disable first-run welcome page + 'startup.homepage_welcome_url.additional': '', + + // Disable browser animations (tabs, fullscreen, sliding alerts) + 'toolkit.cosmeticAnimations.enabled': false, + + // Prevent starting into safe mode after application crashes + 'toolkit.startup.max_resumed_crashes': -1, + }; + + return Object.assign(defaultPrefs, extraPrefs); +} + +/** + * Populates the user.js file with custom preferences as needed to allow + * Firefox's CDP support to properly function. These preferences will be + * automatically copied over to prefs.js during startup of Firefox. To be + * able to restore the original values of preferences a backup of prefs.js + * will be created. + * + * @param prefs - List of preferences to add. + * @param profilePath - Firefox profile to write the preferences to. + */ +async function writePreferences(options: ProfileOptions): Promise { + const prefsPath = path.join(options.path, 'prefs.js'); + const lines = Object.entries(options.preferences).map(([key, value]) => { + return `user_pref(${JSON.stringify(key)}, ${JSON.stringify(value)});`; + }); + + // Use allSettled to prevent corruption + const result = await Promise.allSettled([ + fs.promises.writeFile(path.join(options.path, 'user.js'), lines.join('\n')), + // Create a backup of the preferences file if it already exitsts. + fs.promises.access(prefsPath, fs.constants.F_OK).then( + async () => { + await fs.promises.copyFile( + prefsPath, + path.join(options.path, 'prefs.js.playwright') + ); + }, + // Swallow only if file does not exist + () => {} + ), + ]); + for (const command of result) { + if (command.status === 'rejected') { + throw command.reason; + } + } +} diff --git a/packages/playwright-core/src/server/browserType.ts b/packages/playwright-core/src/server/browserType.ts index abc15a20f4..ec8524c247 100644 --- a/packages/playwright-core/src/server/browserType.ts +++ b/packages/playwright-core/src/server/browserType.ts @@ -192,6 +192,7 @@ export abstract class BrowserType extends SdkObject { userDataDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), `playwright_${this._name}dev_profile-`)); tempDirectories.push(userDataDir); } + await this.prepareUserDataDir(options, userDataDir); const browserArguments = []; if (ignoreAllDefaultArgs) @@ -328,6 +329,9 @@ export abstract class BrowserType extends SdkObject { return undefined; } + async prepareUserDataDir(options: types.LaunchOptions, userDataDir: string): Promise { + } + abstract defaultArgs(options: types.LaunchOptions, isPersistent: boolean, userDataDir: string): string[]; abstract connectToTransport(transport: ConnectionTransport, options: BrowserOptions): Promise; abstract amendEnvironment(env: Env, userDataDir: string, executable: string, browserArguments: string[]): Env; diff --git a/packages/playwright-core/src/server/chromium/crPage.ts b/packages/playwright-core/src/server/chromium/crPage.ts index bba14ff00e..c1ff803338 100644 --- a/packages/playwright-core/src/server/chromium/crPage.ts +++ b/packages/playwright-core/src/server/chromium/crPage.ts @@ -247,7 +247,7 @@ export class CRPage implements PageDelegate { return this._go(+1); } - async forceGarbageCollection(): Promise { + async requestGC(): Promise { await this._mainFrameSession._client.send('HeapProfiler.collectGarbage'); } diff --git a/packages/playwright-core/src/server/deviceDescriptorsSource.json b/packages/playwright-core/src/server/deviceDescriptorsSource.json index bd9b4021ed..b6538d81d6 100644 --- a/packages/playwright-core/src/server/deviceDescriptorsSource.json +++ b/packages/playwright-core/src/server/deviceDescriptorsSource.json @@ -110,7 +110,7 @@ "defaultBrowserType": "webkit" }, "Galaxy S5": { - "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 360, "height": 640 @@ -121,7 +121,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S5 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 640, "height": 360 @@ -132,7 +132,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S8": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 360, "height": 740 @@ -143,7 +143,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S8 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 740, "height": 360 @@ -154,7 +154,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S9+": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 320, "height": 658 @@ -165,7 +165,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S9+ landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 658, "height": 320 @@ -176,7 +176,7 @@ "defaultBrowserType": "chromium" }, "Galaxy Tab S4": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Safari/537.36", "viewport": { "width": 712, "height": 1138 @@ -187,7 +187,7 @@ "defaultBrowserType": "chromium" }, "Galaxy Tab S4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Safari/537.36", "viewport": { "width": 1138, "height": 712 @@ -1098,7 +1098,7 @@ "defaultBrowserType": "webkit" }, "LG Optimus L70": { - "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 384, "height": 640 @@ -1109,7 +1109,7 @@ "defaultBrowserType": "chromium" }, "LG Optimus L70 landscape": { - "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 640, "height": 384 @@ -1120,7 +1120,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 550": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 640, "height": 360 @@ -1131,7 +1131,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 550 landscape": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 360, "height": 640 @@ -1142,7 +1142,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 950": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 360, "height": 640 @@ -1153,7 +1153,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 950 landscape": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 640, "height": 360 @@ -1164,7 +1164,7 @@ "defaultBrowserType": "chromium" }, "Nexus 10": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Safari/537.36", "viewport": { "width": 800, "height": 1280 @@ -1175,7 +1175,7 @@ "defaultBrowserType": "chromium" }, "Nexus 10 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Safari/537.36", "viewport": { "width": 1280, "height": 800 @@ -1186,7 +1186,7 @@ "defaultBrowserType": "chromium" }, "Nexus 4": { - "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 384, "height": 640 @@ -1197,7 +1197,7 @@ "defaultBrowserType": "chromium" }, "Nexus 4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 640, "height": 384 @@ -1208,7 +1208,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 360, "height": 640 @@ -1219,7 +1219,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 640, "height": 360 @@ -1230,7 +1230,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5X": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 412, "height": 732 @@ -1241,7 +1241,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5X landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 732, "height": 412 @@ -1252,7 +1252,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 412, "height": 732 @@ -1263,7 +1263,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 732, "height": 412 @@ -1274,7 +1274,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6P": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 412, "height": 732 @@ -1285,7 +1285,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6P landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 732, "height": 412 @@ -1296,7 +1296,7 @@ "defaultBrowserType": "chromium" }, "Nexus 7": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Safari/537.36", "viewport": { "width": 600, "height": 960 @@ -1307,7 +1307,7 @@ "defaultBrowserType": "chromium" }, "Nexus 7 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Safari/537.36", "viewport": { "width": 960, "height": 600 @@ -1362,7 +1362,7 @@ "defaultBrowserType": "webkit" }, "Pixel 2": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 411, "height": 731 @@ -1373,7 +1373,7 @@ "defaultBrowserType": "chromium" }, "Pixel 2 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 731, "height": 411 @@ -1384,7 +1384,7 @@ "defaultBrowserType": "chromium" }, "Pixel 2 XL": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 411, "height": 823 @@ -1395,7 +1395,7 @@ "defaultBrowserType": "chromium" }, "Pixel 2 XL landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 823, "height": 411 @@ -1406,7 +1406,7 @@ "defaultBrowserType": "chromium" }, "Pixel 3": { - "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 393, "height": 786 @@ -1417,7 +1417,7 @@ "defaultBrowserType": "chromium" }, "Pixel 3 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 786, "height": 393 @@ -1428,7 +1428,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4": { - "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 353, "height": 745 @@ -1439,7 +1439,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 745, "height": 353 @@ -1450,7 +1450,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4a (5G)": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "screen": { "width": 412, "height": 892 @@ -1465,7 +1465,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4a (5G) landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "screen": { "height": 892, "width": 412 @@ -1480,7 +1480,7 @@ "defaultBrowserType": "chromium" }, "Pixel 5": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "screen": { "width": 393, "height": 851 @@ -1495,7 +1495,7 @@ "defaultBrowserType": "chromium" }, "Pixel 5 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "screen": { "width": 851, "height": 393 @@ -1510,7 +1510,7 @@ "defaultBrowserType": "chromium" }, "Pixel 7": { - "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "screen": { "width": 412, "height": 915 @@ -1525,7 +1525,7 @@ "defaultBrowserType": "chromium" }, "Pixel 7 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "screen": { "width": 915, "height": 412 @@ -1540,7 +1540,7 @@ "defaultBrowserType": "chromium" }, "Moto G4": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 360, "height": 640 @@ -1551,7 +1551,7 @@ "defaultBrowserType": "chromium" }, "Moto G4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Mobile Safari/537.36", "viewport": { "width": 640, "height": 360 @@ -1562,7 +1562,7 @@ "defaultBrowserType": "chromium" }, "Desktop Chrome HiDPI": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Safari/537.36", "screen": { "width": 1792, "height": 1120 @@ -1577,7 +1577,7 @@ "defaultBrowserType": "chromium" }, "Desktop Edge HiDPI": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Safari/537.36 Edg/130.0.6723.6", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Safari/537.36 Edg/130.0.6723.19", "screen": { "width": 1792, "height": 1120 @@ -1622,7 +1622,7 @@ "defaultBrowserType": "webkit" }, "Desktop Chrome": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Safari/537.36", "screen": { "width": 1920, "height": 1080 @@ -1637,7 +1637,7 @@ "defaultBrowserType": "chromium" }, "Desktop Edge": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.6 Safari/537.36 Edg/130.0.6723.6", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.19 Safari/537.36 Edg/130.0.6723.19", "screen": { "width": 1920, "height": 1080 diff --git a/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts b/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts index 265e37bd45..5e3b73a73f 100644 --- a/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts @@ -139,8 +139,8 @@ export class PageDispatcher extends Dispatcher { - await this._page.forceGarbageCollection(); + async requestGC(params: channels.PageRequestGCParams, metadata: CallMetadata): Promise { + await this._page.requestGC(); } async registerLocatorHandler(params: channels.PageRegisterLocatorHandlerParams, metadata: CallMetadata): Promise { diff --git a/packages/playwright-core/src/server/firefox/ffPage.ts b/packages/playwright-core/src/server/firefox/ffPage.ts index 9dfffc1eb3..61790feae4 100644 --- a/packages/playwright-core/src/server/firefox/ffPage.ts +++ b/packages/playwright-core/src/server/firefox/ffPage.ts @@ -399,7 +399,7 @@ export class FFPage implements PageDelegate { return success; } - async forceGarbageCollection(): Promise { + async requestGC(): Promise { await this._session.send('Heap.collectGarbage'); } diff --git a/packages/playwright-core/src/server/injected/recorder/recorder.ts b/packages/playwright-core/src/server/injected/recorder/recorder.ts index 757b413704..defe73192f 100644 --- a/packages/playwright-core/src/server/injected/recorder/recorder.ts +++ b/packages/playwright-core/src/server/injected/recorder/recorder.ts @@ -205,7 +205,7 @@ class InspectTool implements RecorderTool { class RecordActionTool implements RecorderTool { private _recorder: Recorder; - private _performingAction: actions.PerformOnRecordAction | null = null; + private _performingActions = new Set(); private _hoveredModel: HighlightModel | null = null; private _hoveredElement: HTMLElement | null = null; private _activeModel: HighlightModel | null = null; @@ -333,21 +333,21 @@ class RecordActionTool implements RecorderTool { onPointerDown(event: PointerEvent) { if (this._shouldIgnoreMouseEvent(event)) return; - if (!this._performingAction) + if (!this._performingActions.size) consumeEvent(event); } onPointerUp(event: PointerEvent) { if (this._shouldIgnoreMouseEvent(event)) return; - if (!this._performingAction) + if (!this._performingActions.size) consumeEvent(event); } onMouseDown(event: MouseEvent) { if (this._shouldIgnoreMouseEvent(event)) return; - if (!this._performingAction) + if (!this._performingActions.size) consumeEvent(event); this._activeModel = this._hoveredModel; } @@ -355,7 +355,7 @@ class RecordActionTool implements RecorderTool { onMouseUp(event: MouseEvent) { if (this._shouldIgnoreMouseEvent(event)) return; - if (!this._performingAction) + if (!this._performingActions.size) consumeEvent(event); } @@ -509,12 +509,13 @@ class RecordActionTool implements RecorderTool { private _actionInProgress(event: Event): boolean { // If Playwright is performing action for us, bail. const isKeyEvent = event instanceof KeyboardEvent; - if (this._performingAction?.name === 'press' && isKeyEvent && event.key === this._performingAction.key) - return true; - const isMouseOrPointerEvent = event instanceof MouseEvent || event instanceof PointerEvent; - if (isMouseOrPointerEvent && (this._performingAction?.name === 'click' || this._performingAction?.name === 'check' || this._performingAction?.name === 'uncheck')) - return true; + for (const action of this._performingActions) { + if (isKeyEvent && action.name === 'press' && event.key === action.key) + return true; + if (isMouseOrPointerEvent && (action.name === 'click' || action.name === 'check' || action.name === 'uncheck')) + return true; + } // Consume event if action is not being executed. consumeEvent(event); @@ -540,9 +541,9 @@ class RecordActionTool implements RecorderTool { this._hoveredModel = null; this._activeModel = null; this._recorder.updateHighlight(null, false); - this._performingAction = action; + this._performingActions.add(action); void this._recorder.performAction(action).then(() => { - this._performingAction = null; + this._performingActions.delete(action); // If that was a keyboard action, it similarly requires new selectors for active model. this._onFocus(false); diff --git a/packages/playwright-core/src/server/page.ts b/packages/playwright-core/src/server/page.ts index 04728b681e..3fb72bb0c3 100644 --- a/packages/playwright-core/src/server/page.ts +++ b/packages/playwright-core/src/server/page.ts @@ -54,7 +54,7 @@ export interface PageDelegate { reload(): Promise; goBack(): Promise; goForward(): Promise; - forceGarbageCollection(): Promise; + requestGC(): Promise; addInitScript(initScript: InitScript): Promise; removeNonInternalInitScripts(): Promise; closePage(runBeforeUnload: boolean): Promise; @@ -431,8 +431,8 @@ export class Page extends SdkObject { }), this._timeoutSettings.navigationTimeout(options)); } - forceGarbageCollection(): Promise { - return this._delegate.forceGarbageCollection(); + requestGC(): Promise { + return this._delegate.requestGC(); } registerLocatorHandler(selector: string, noWaitAfter: boolean | undefined) { diff --git a/packages/playwright-core/src/server/registry/index.ts b/packages/playwright-core/src/server/registry/index.ts index 4e942967a4..7778d81218 100644 --- a/packages/playwright-core/src/server/registry/index.ts +++ b/packages/playwright-core/src/server/registry/index.ts @@ -100,6 +100,8 @@ const DOWNLOAD_PATHS: Record = { 'mac13-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip', 'mac14': 'builds/chromium/%s/chromium-mac.zip', 'mac14-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip', + 'mac15': 'builds/chromium/%s/chromium-mac.zip', + 'mac15-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip', 'win64': 'builds/chromium/%s/chromium-win64.zip', }, 'chromium-tip-of-tree': { @@ -127,6 +129,8 @@ const DOWNLOAD_PATHS: Record = { 'mac13-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip', 'mac14': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip', 'mac14-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip', + 'mac15': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip', + 'mac15-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip', 'win64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-win64.zip', }, 'firefox': { @@ -154,6 +158,8 @@ const DOWNLOAD_PATHS: Record = { 'mac13-arm64': 'builds/firefox/%s/firefox-mac-arm64.zip', 'mac14': 'builds/firefox/%s/firefox-mac.zip', 'mac14-arm64': 'builds/firefox/%s/firefox-mac-arm64.zip', + 'mac15': 'builds/firefox/%s/firefox-mac.zip', + 'mac15-arm64': 'builds/firefox/%s/firefox-mac-arm64.zip', 'win64': 'builds/firefox/%s/firefox-win64.zip', }, 'firefox-beta': { @@ -181,6 +187,8 @@ const DOWNLOAD_PATHS: Record = { 'mac13-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-arm64.zip', 'mac14': 'builds/firefox-beta/%s/firefox-beta-mac.zip', 'mac14-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-arm64.zip', + 'mac15': 'builds/firefox-beta/%s/firefox-beta-mac.zip', + 'mac15-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-arm64.zip', 'win64': 'builds/firefox-beta/%s/firefox-beta-win64.zip', }, 'webkit': { @@ -208,6 +216,8 @@ const DOWNLOAD_PATHS: Record = { 'mac13-arm64': 'builds/webkit/%s/webkit-mac-13-arm64.zip', 'mac14': 'builds/webkit/%s/webkit-mac-14.zip', 'mac14-arm64': 'builds/webkit/%s/webkit-mac-14-arm64.zip', + 'mac15': 'builds/webkit/%s/webkit-mac-15.zip', + 'mac15-arm64': 'builds/webkit/%s/webkit-mac-15-arm64.zip', 'win64': 'builds/webkit/%s/webkit-win64.zip', }, 'ffmpeg': { @@ -235,6 +245,8 @@ const DOWNLOAD_PATHS: Record = { 'mac13-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip', 'mac14': 'builds/ffmpeg/%s/ffmpeg-mac.zip', 'mac14-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip', + 'mac15': 'builds/ffmpeg/%s/ffmpeg-mac.zip', + 'mac15-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip', 'win64': 'builds/ffmpeg/%s/ffmpeg-win64.zip', }, 'android': { @@ -262,6 +274,8 @@ const DOWNLOAD_PATHS: Record = { 'mac13-arm64': 'builds/android/%s/android.zip', 'mac14': 'builds/android/%s/android.zip', 'mac14-arm64': 'builds/android/%s/android.zip', + 'mac15': 'builds/android/%s/android.zip', + 'mac15-arm64': 'builds/android/%s/android.zip', 'win64': 'builds/android/%s/android.zip', }, // TODO(bidi): implement downloads. diff --git a/packages/playwright-core/src/server/trace/test/inMemorySnapshotter.ts b/packages/playwright-core/src/server/trace/test/inMemorySnapshotter.ts index af07910159..f7461599aa 100644 --- a/packages/playwright-core/src/server/trace/test/inMemorySnapshotter.ts +++ b/packages/playwright-core/src/server/trace/test/inMemorySnapshotter.ts @@ -17,8 +17,8 @@ import type { BrowserContext } from '../../browserContext'; import type { Page } from '../../page'; import type { FrameSnapshot } from '@trace/snapshot'; -import type { SnapshotRenderer } from '../../../../../trace-viewer/src/snapshotRenderer'; -import { SnapshotStorage } from '../../../../../trace-viewer/src/snapshotStorage'; +import type { SnapshotRenderer } from '../../../../../trace-viewer/src/sw/snapshotRenderer'; +import { SnapshotStorage } from '../../../../../trace-viewer/src/sw/snapshotStorage'; import type { SnapshotterBlob, SnapshotterDelegate } from '../recorder/snapshotter'; import { Snapshotter } from '../recorder/snapshotter'; import type { ElementHandle } from '../../dom'; diff --git a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts index 6d45e7c6f5..a49148e061 100644 --- a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts +++ b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts @@ -40,13 +40,9 @@ export type TraceViewerRedirectOptions = { grep?: string; grepInvert?: string; project?: string[]; - workers?: number | string; - headed?: boolean; - timeout?: number; reporter?: string[]; webApp?: string; isServer?: boolean; - updateSnapshots?: 'all' | 'none' | 'missing'; }; export type TraceViewerAppOptions = { @@ -126,14 +122,6 @@ export async function installRootRedirect(server: HttpServer, traceUrls: string[ params.append('grepInvert', options.grepInvert); for (const project of options.project || []) params.append('project', project); - if (options.workers) - params.append('workers', String(options.workers)); - if (options.timeout) - params.append('timeout', String(options.timeout)); - if (options.headed) - params.append('headed', ''); - if (options.updateSnapshots) - params.append('updateSnapshots', options.updateSnapshots); for (const reporter of options.reporter || []) params.append('reporter', reporter); diff --git a/packages/playwright-core/src/server/webkit/wkPage.ts b/packages/playwright-core/src/server/webkit/wkPage.ts index 320df04ce2..3ba773241a 100644 --- a/packages/playwright-core/src/server/webkit/wkPage.ts +++ b/packages/playwright-core/src/server/webkit/wkPage.ts @@ -767,7 +767,7 @@ export class WKPage implements PageDelegate { }); } - async forceGarbageCollection(): Promise { + async requestGC(): Promise { await this._session.send('Heap.gc'); } diff --git a/packages/playwright-core/src/utils/hostPlatform.ts b/packages/playwright-core/src/utils/hostPlatform.ts index faf65bd082..9664418e3d 100644 --- a/packages/playwright-core/src/utils/hostPlatform.ts +++ b/packages/playwright-core/src/utils/hostPlatform.ts @@ -25,6 +25,7 @@ export type HostPlatform = 'win64' | 'mac12' | 'mac12-arm64' | 'mac13' | 'mac13-arm64' | 'mac14' | 'mac14-arm64' | + 'mac15' | 'mac15-arm64' | 'ubuntu18.04-x64' | 'ubuntu18.04-arm64' | 'ubuntu20.04-x64' | 'ubuntu20.04-arm64' | 'ubuntu22.04-x64' | 'ubuntu22.04-arm64' | @@ -47,9 +48,9 @@ function calculatePlatform(): { hostPlatform: HostPlatform, isOfficiallySupporte macVersion = 'mac10.15'; } else { // ver[0] >= 20 - const LAST_STABLE_MAC_MAJOR_VERSION = 14; + const LAST_STABLE_MACOS_MAJOR_VERSION = 15; // Best-effort support for MacOS beta versions. - macVersion = 'mac' + Math.min(ver[0] - 9, LAST_STABLE_MAC_MAJOR_VERSION); + macVersion = 'mac' + Math.min(ver[0] - 9, LAST_STABLE_MACOS_MAJOR_VERSION); // BigSur is the first version that might run on Apple Silicon. if (os.cpus().some(cpu => cpu.model.includes('Apple'))) macVersion += '-arm64'; diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index e0c640db6f..4e4b632462 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -29,9 +29,10 @@ type ElementHandleWaitForSelectorOptionsNotHidden = ElementHandleWaitForSelector }; /** - * Page provides methods to interact with a single tab in a {@link Browser}, or an - * [extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium. One {@link - * Browser} instance might have multiple {@link Page} instances. + * Page provides methods to interact with a single tab in a [Browser](https://playwright.dev/docs/api/class-browser), + * or an [extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium. One + * [Browser](https://playwright.dev/docs/api/class-browser) instance might have multiple + * [Page](https://playwright.dev/docs/api/class-page) instances. * * This example creates a page, navigates it to a URL, and then saves a screenshot: * @@ -72,7 +73,8 @@ type ElementHandleWaitForSelectorOptionsNotHidden = ElementHandleWaitForSelector */ export interface Page { /** - * Returns the value of the `pageFunction` invocation. + * Returns the value of the + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression) invocation. * * If the function passed to the * [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate) returns a [Promise], @@ -88,7 +90,7 @@ export interface Page { * * **Usage** * - * Passing argument to `pageFunction`: + * Passing argument to [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression): * * ```js * const result = await page.evaluate(([x, y]) => { @@ -105,7 +107,7 @@ export interface Page { * console.log(await page.evaluate(`1 + ${x}`)); // prints "11" * ``` * - * {@link ElementHandle} instances can be passed as an argument to the + * [ElementHandle](https://playwright.dev/docs/api/class-elementhandle) instances can be passed as an argument to the * [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate): * * ```js @@ -117,11 +119,13 @@ export interface Page { * ``` * * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression). */ evaluate(pageFunction: PageFunction, arg: Arg): Promise; /** - * Returns the value of the `pageFunction` invocation. + * Returns the value of the + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression) invocation. * * If the function passed to the * [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate) returns a [Promise], @@ -137,7 +141,7 @@ export interface Page { * * **Usage** * - * Passing argument to `pageFunction`: + * Passing argument to [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression): * * ```js * const result = await page.evaluate(([x, y]) => { @@ -154,7 +158,7 @@ export interface Page { * console.log(await page.evaluate(`1 + ${x}`)); // prints "11" * ``` * - * {@link ElementHandle} instances can be passed as an argument to the + * [ElementHandle](https://playwright.dev/docs/api/class-elementhandle) instances can be passed as an argument to the * [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate): * * ```js @@ -166,18 +170,21 @@ export interface Page { * ``` * * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression). */ evaluate(pageFunction: PageFunction, arg?: any): Promise; /** - * Returns the value of the `pageFunction` invocation as a {@link JSHandle}. + * Returns the value of the + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-handle-option-expression) invocation as a + * [JSHandle](https://playwright.dev/docs/api/class-jshandle). * * The only difference between * [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate) and * [page.evaluateHandle(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate-handle) is that * [page.evaluateHandle(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate-handle) returns - * {@link JSHandle}. + * [JSHandle](https://playwright.dev/docs/api/class-jshandle). * * If the function passed to the * [page.evaluateHandle(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate-handle) returns @@ -198,7 +205,7 @@ export interface Page { * const aHandle = await page.evaluateHandle('document'); // Handle for the 'document' * ``` * - * {@link JSHandle} instances can be passed as an argument to the + * [JSHandle](https://playwright.dev/docs/api/class-jshandle) instances can be passed as an argument to the * [page.evaluateHandle(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate-handle): * * ```js @@ -209,17 +216,20 @@ export interface Page { * ``` * * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-handle-option-expression). */ evaluateHandle(pageFunction: PageFunction, arg: Arg): Promise>; /** - * Returns the value of the `pageFunction` invocation as a {@link JSHandle}. + * Returns the value of the + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-handle-option-expression) invocation as a + * [JSHandle](https://playwright.dev/docs/api/class-jshandle). * * The only difference between * [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate) and * [page.evaluateHandle(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate-handle) is that * [page.evaluateHandle(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate-handle) returns - * {@link JSHandle}. + * [JSHandle](https://playwright.dev/docs/api/class-jshandle). * * If the function passed to the * [page.evaluateHandle(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate-handle) returns @@ -240,7 +250,7 @@ export interface Page { * const aHandle = await page.evaluateHandle('document'); // Handle for the 'document' * ``` * - * {@link JSHandle} instances can be passed as an argument to the + * [JSHandle](https://playwright.dev/docs/api/class-jshandle) instances can be passed as an argument to the * [page.evaluateHandle(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate-handle): * * ```js @@ -251,7 +261,8 @@ export interface Page { * ``` * * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-handle-option-expression). */ evaluateHandle(pageFunction: PageFunction, arg?: any): Promise>; @@ -288,8 +299,11 @@ export interface Page { * [browserContext.addInitScript(script[, arg])](https://playwright.dev/docs/api/class-browsercontext#browser-context-add-init-script) * and [page.addInitScript(script[, arg])](https://playwright.dev/docs/api/class-page#page-add-init-script) is not * defined. + * * @param script Script to be evaluated in the page. - * @param arg Optional argument to pass to `script` (only supported when passing a function). + * @param arg Optional argument to pass to + * [`script`](https://playwright.dev/docs/api/class-page#page-add-init-script-option-script) (only supported when + * passing a function). */ addInitScript(script: PageFunction | { path?: string, content?: string }, arg?: Arg): Promise; @@ -339,12 +353,15 @@ export interface Page { * **NOTE** This method does not wait for the element to pass actionability checks and therefore can lead to the flaky tests. * Use * [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate), - * other {@link Locator} helper methods or web-first assertions instead. + * other [Locator](https://playwright.dev/docs/api/class-locator) helper methods or web-first assertions instead. * * The method finds an element matching the specified selector within the page and passes it as a first argument to - * `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`. + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). If no + * elements match the selector, the method throws an error. Returns the value of + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). * - * If `pageFunction` returns a [Promise], then + * If [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression) returns a + * [Promise], then * [page.$eval(selector, pageFunction[, arg, options])](https://playwright.dev/docs/api/class-page#page-eval-on-selector) * would wait for the promise to resolve and return its value. * @@ -360,7 +377,8 @@ export interface Page { * * @param selector A selector to query for. * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). * @param options */ $eval(selector: K, pageFunction: PageFunctionOn, arg: Arg): Promise; @@ -368,12 +386,15 @@ export interface Page { * **NOTE** This method does not wait for the element to pass actionability checks and therefore can lead to the flaky tests. * Use * [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate), - * other {@link Locator} helper methods or web-first assertions instead. + * other [Locator](https://playwright.dev/docs/api/class-locator) helper methods or web-first assertions instead. * * The method finds an element matching the specified selector within the page and passes it as a first argument to - * `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`. + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). If no + * elements match the selector, the method throws an error. Returns the value of + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). * - * If `pageFunction` returns a [Promise], then + * If [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression) returns a + * [Promise], then * [page.$eval(selector, pageFunction[, arg, options])](https://playwright.dev/docs/api/class-page#page-eval-on-selector) * would wait for the promise to resolve and return its value. * @@ -389,7 +410,8 @@ export interface Page { * * @param selector A selector to query for. * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). * @param options */ $eval(selector: string, pageFunction: PageFunctionOn, arg: Arg): Promise; @@ -397,12 +419,15 @@ export interface Page { * **NOTE** This method does not wait for the element to pass actionability checks and therefore can lead to the flaky tests. * Use * [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate), - * other {@link Locator} helper methods or web-first assertions instead. + * other [Locator](https://playwright.dev/docs/api/class-locator) helper methods or web-first assertions instead. * * The method finds an element matching the specified selector within the page and passes it as a first argument to - * `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`. + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). If no + * elements match the selector, the method throws an error. Returns the value of + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). * - * If `pageFunction` returns a [Promise], then + * If [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression) returns a + * [Promise], then * [page.$eval(selector, pageFunction[, arg, options])](https://playwright.dev/docs/api/class-page#page-eval-on-selector) * would wait for the promise to resolve and return its value. * @@ -418,7 +443,8 @@ export interface Page { * * @param selector A selector to query for. * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). * @param options */ $eval(selector: K, pageFunction: PageFunctionOn, arg?: any): Promise; @@ -426,12 +452,15 @@ export interface Page { * **NOTE** This method does not wait for the element to pass actionability checks and therefore can lead to the flaky tests. * Use * [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate), - * other {@link Locator} helper methods or web-first assertions instead. + * other [Locator](https://playwright.dev/docs/api/class-locator) helper methods or web-first assertions instead. * * The method finds an element matching the specified selector within the page and passes it as a first argument to - * `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`. + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). If no + * elements match the selector, the method throws an error. Returns the value of + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). * - * If `pageFunction` returns a [Promise], then + * If [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression) returns a + * [Promise], then * [page.$eval(selector, pageFunction[, arg, options])](https://playwright.dev/docs/api/class-page#page-eval-on-selector) * would wait for the promise to resolve and return its value. * @@ -447,7 +476,8 @@ export interface Page { * * @param selector A selector to query for. * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-option-expression). * @param options */ $eval(selector: string, pageFunction: PageFunctionOn, arg?: any): Promise; @@ -455,12 +485,18 @@ export interface Page { /** * **NOTE** In most cases, * [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all), - * other {@link Locator} helper methods and web-first assertions do a better job. + * other [Locator](https://playwright.dev/docs/api/class-locator) helper methods and web-first assertions do a better + * job. * * The method finds all elements matching the specified selector within the page and passes an array of matched - * elements as a first argument to `pageFunction`. Returns the result of `pageFunction` invocation. + * elements as a first argument to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression). Returns + * the result of + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression) + * invocation. * - * If `pageFunction` returns a [Promise], then + * If [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression) returns + * a [Promise], then * [page.$$eval(selector, pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all) * would wait for the promise to resolve and return its value. * @@ -472,18 +508,25 @@ export interface Page { * * @param selector A selector to query for. * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression). */ $$eval(selector: K, pageFunction: PageFunctionOn, arg: Arg): Promise; /** * **NOTE** In most cases, * [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all), - * other {@link Locator} helper methods and web-first assertions do a better job. + * other [Locator](https://playwright.dev/docs/api/class-locator) helper methods and web-first assertions do a better + * job. * * The method finds all elements matching the specified selector within the page and passes an array of matched - * elements as a first argument to `pageFunction`. Returns the result of `pageFunction` invocation. + * elements as a first argument to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression). Returns + * the result of + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression) + * invocation. * - * If `pageFunction` returns a [Promise], then + * If [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression) returns + * a [Promise], then * [page.$$eval(selector, pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all) * would wait for the promise to resolve and return its value. * @@ -495,18 +538,25 @@ export interface Page { * * @param selector A selector to query for. * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression). */ $$eval(selector: string, pageFunction: PageFunctionOn, arg: Arg): Promise; /** * **NOTE** In most cases, * [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all), - * other {@link Locator} helper methods and web-first assertions do a better job. + * other [Locator](https://playwright.dev/docs/api/class-locator) helper methods and web-first assertions do a better + * job. * * The method finds all elements matching the specified selector within the page and passes an array of matched - * elements as a first argument to `pageFunction`. Returns the result of `pageFunction` invocation. + * elements as a first argument to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression). Returns + * the result of + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression) + * invocation. * - * If `pageFunction` returns a [Promise], then + * If [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression) returns + * a [Promise], then * [page.$$eval(selector, pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all) * would wait for the promise to resolve and return its value. * @@ -518,18 +568,25 @@ export interface Page { * * @param selector A selector to query for. * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression). */ $$eval(selector: K, pageFunction: PageFunctionOn, arg?: any): Promise; /** * **NOTE** In most cases, * [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all), - * other {@link Locator} helper methods and web-first assertions do a better job. + * other [Locator](https://playwright.dev/docs/api/class-locator) helper methods and web-first assertions do a better + * job. * * The method finds all elements matching the specified selector within the page and passes an array of matched - * elements as a first argument to `pageFunction`. Returns the result of `pageFunction` invocation. + * elements as a first argument to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression). Returns + * the result of + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression) + * invocation. * - * If `pageFunction` returns a [Promise], then + * If [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression) returns + * a [Promise], then * [page.$$eval(selector, pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all) * would wait for the promise to resolve and return its value. * @@ -541,12 +598,15 @@ export interface Page { * * @param selector A selector to query for. * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-eval-on-selector-all-option-expression). */ $$eval(selector: string, pageFunction: PageFunctionOn, arg?: any): Promise; /** - * Returns when the `pageFunction` returns a truthy value. It resolves to a JSHandle of the truthy value. + * Returns when the + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-wait-for-function-option-expression) returns a + * truthy value. It resolves to a JSHandle of the truthy value. * * **Usage** * @@ -577,12 +637,15 @@ export interface Page { * ``` * * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-wait-for-function-option-expression). * @param options */ waitForFunction(pageFunction: PageFunction, arg: Arg, options?: PageWaitForFunctionOptions): Promise>; /** - * Returns when the `pageFunction` returns a truthy value. It resolves to a JSHandle of the truthy value. + * Returns when the + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-wait-for-function-option-expression) returns a + * truthy value. It resolves to a JSHandle of the truthy value. * * **Usage** * @@ -613,7 +676,8 @@ export interface Page { * ``` * * @param pageFunction Function to be evaluated in the page context. - * @param arg Optional argument to pass to `pageFunction`. + * @param arg Optional argument to pass to + * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-wait-for-function-option-expression). * @param options */ waitForFunction(pageFunction: PageFunction, arg?: any, options?: PageWaitForFunctionOptions): Promise>; @@ -623,15 +687,21 @@ export interface Page { * [locator.waitFor([options])](https://playwright.dev/docs/api/class-locator#locator-wait-for) instead. Read more * about [locators](https://playwright.dev/docs/locators). * - * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or - * `detached`. + * Returns when element specified by selector satisfies + * [`state`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-state) option. Returns `null` if + * waiting for `hidden` or `detached`. * - * **NOTE** Playwright automatically waits for element to be ready before performing an action. Using {@link Locator} - * objects and web-first assertions makes the code wait-for-selector-free. + * **NOTE** Playwright automatically waits for element to be ready before performing an action. Using + * [Locator](https://playwright.dev/docs/api/class-locator) objects and web-first assertions makes the code + * wait-for-selector-free. * - * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If - * at the moment of calling the method `selector` already satisfies the condition, the method will return immediately. - * If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. + * Wait for the [`selector`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-selector) to + * satisfy [`state`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-state) option (either + * appear/disappear from dom, or become visible/hidden). If at the moment of calling the method + * [`selector`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-selector) already satisfies + * the condition, the method will return immediately. If the selector doesn't satisfy the condition for the + * [`timeout`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-timeout) milliseconds, the + * function will throw. * * **Usage** * @@ -661,15 +731,21 @@ export interface Page { * [locator.waitFor([options])](https://playwright.dev/docs/api/class-locator#locator-wait-for) instead. Read more * about [locators](https://playwright.dev/docs/locators). * - * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or - * `detached`. + * Returns when element specified by selector satisfies + * [`state`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-state) option. Returns `null` if + * waiting for `hidden` or `detached`. * - * **NOTE** Playwright automatically waits for element to be ready before performing an action. Using {@link Locator} - * objects and web-first assertions makes the code wait-for-selector-free. + * **NOTE** Playwright automatically waits for element to be ready before performing an action. Using + * [Locator](https://playwright.dev/docs/api/class-locator) objects and web-first assertions makes the code + * wait-for-selector-free. * - * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If - * at the moment of calling the method `selector` already satisfies the condition, the method will return immediately. - * If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. + * Wait for the [`selector`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-selector) to + * satisfy [`state`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-state) option (either + * appear/disappear from dom, or become visible/hidden). If at the moment of calling the method + * [`selector`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-selector) already satisfies + * the condition, the method will return immediately. If the selector doesn't satisfy the condition for the + * [`timeout`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-timeout) milliseconds, the + * function will throw. * * **Usage** * @@ -699,15 +775,21 @@ export interface Page { * [locator.waitFor([options])](https://playwright.dev/docs/api/class-locator#locator-wait-for) instead. Read more * about [locators](https://playwright.dev/docs/locators). * - * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or - * `detached`. + * Returns when element specified by selector satisfies + * [`state`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-state) option. Returns `null` if + * waiting for `hidden` or `detached`. * - * **NOTE** Playwright automatically waits for element to be ready before performing an action. Using {@link Locator} - * objects and web-first assertions makes the code wait-for-selector-free. + * **NOTE** Playwright automatically waits for element to be ready before performing an action. Using + * [Locator](https://playwright.dev/docs/api/class-locator) objects and web-first assertions makes the code + * wait-for-selector-free. * - * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If - * at the moment of calling the method `selector` already satisfies the condition, the method will return immediately. - * If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. + * Wait for the [`selector`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-selector) to + * satisfy [`state`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-state) option (either + * appear/disappear from dom, or become visible/hidden). If at the moment of calling the method + * [`selector`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-selector) already satisfies + * the condition, the method will return immediately. If the selector doesn't satisfy the condition for the + * [`timeout`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-timeout) milliseconds, the + * function will throw. * * **Usage** * @@ -737,15 +819,21 @@ export interface Page { * [locator.waitFor([options])](https://playwright.dev/docs/api/class-locator#locator-wait-for) instead. Read more * about [locators](https://playwright.dev/docs/locators). * - * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or - * `detached`. + * Returns when element specified by selector satisfies + * [`state`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-state) option. Returns `null` if + * waiting for `hidden` or `detached`. * - * **NOTE** Playwright automatically waits for element to be ready before performing an action. Using {@link Locator} - * objects and web-first assertions makes the code wait-for-selector-free. + * **NOTE** Playwright automatically waits for element to be ready before performing an action. Using + * [Locator](https://playwright.dev/docs/api/class-locator) objects and web-first assertions makes the code + * wait-for-selector-free. * - * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If - * at the moment of calling the method `selector` already satisfies the condition, the method will return immediately. - * If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. + * Wait for the [`selector`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-selector) to + * satisfy [`state`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-state) option (either + * appear/disappear from dom, or become visible/hidden). If at the moment of calling the method + * [`selector`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-selector) already satisfies + * the condition, the method will return immediately. If the selector doesn't satisfy the condition for the + * [`timeout`](https://playwright.dev/docs/api/class-page#page-wait-for-selector-option-timeout) milliseconds, the + * function will throw. * * **Usage** * @@ -772,12 +860,18 @@ export interface Page { waitForSelector(selector: string, options: PageWaitForSelectorOptions): Promise>; /** - * The method adds a function called `name` on the `window` object of every frame in this page. When called, the - * function executes `callback` and returns a [Promise] which resolves to the return value of `callback`. If the - * `callback` returns a [Promise], it will be awaited. + * The method adds a function called + * [`name`](https://playwright.dev/docs/api/class-page#page-expose-binding-option-name) on the `window` object of + * every frame in this page. When called, the function executes + * [`callback`](https://playwright.dev/docs/api/class-page#page-expose-binding-option-callback) and returns a + * [Promise] which resolves to the return value of + * [`callback`](https://playwright.dev/docs/api/class-page#page-expose-binding-option-callback). If the + * [`callback`](https://playwright.dev/docs/api/class-page#page-expose-binding-option-callback) returns a [Promise], + * it will be awaited. * - * The first argument of the `callback` function contains information about the caller: `{ browserContext: - * BrowserContext, page: Page, frame: Frame }`. + * The first argument of the + * [`callback`](https://playwright.dev/docs/api/class-page#page-expose-binding-option-callback) function contains + * information about the caller: `{ browserContext: BrowserContext, page: Page, frame: Frame }`. * * See * [browserContext.exposeBinding(name, callback[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-expose-binding) @@ -818,12 +912,18 @@ export interface Page { */ exposeBinding(name: string, playwrightBinding: (source: BindingSource, arg: JSHandle) => any, options: { handle: true }): Promise; /** - * The method adds a function called `name` on the `window` object of every frame in this page. When called, the - * function executes `callback` and returns a [Promise] which resolves to the return value of `callback`. If the - * `callback` returns a [Promise], it will be awaited. + * The method adds a function called + * [`name`](https://playwright.dev/docs/api/class-page#page-expose-binding-option-name) on the `window` object of + * every frame in this page. When called, the function executes + * [`callback`](https://playwright.dev/docs/api/class-page#page-expose-binding-option-callback) and returns a + * [Promise] which resolves to the return value of + * [`callback`](https://playwright.dev/docs/api/class-page#page-expose-binding-option-callback). If the + * [`callback`](https://playwright.dev/docs/api/class-page#page-expose-binding-option-callback) returns a [Promise], + * it will be awaited. * - * The first argument of the `callback` function contains information about the caller: `{ browserContext: - * BrowserContext, page: Page, frame: Frame }`. + * The first argument of the + * [`callback`](https://playwright.dev/docs/api/class-page#page-expose-binding-option-callback) function contains + * information about the caller: `{ browserContext: BrowserContext, page: Page, frame: Frame }`. * * See * [browserContext.exposeBinding(name, callback[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-expose-binding) @@ -922,7 +1022,8 @@ export interface Page { /** * Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. * - * The arguments passed into `console.log` are available on the {@link ConsoleMessage} event handler argument. + * The arguments passed into `console.log` are available on the + * [ConsoleMessage](https://playwright.dev/docs/api/class-consolemessage) event handler argument. * * **Usage** * @@ -975,6 +1076,7 @@ export interface Page { * **NOTE** When no [page.on('dialog')](https://playwright.dev/docs/api/class-page#page-event-dialog) or * [browserContext.on('dialog')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-dialog) * listeners are present, all dialogs are automatically dismissed. + * */ on(event: 'dialog', listener: (dialog: Dialog) => any): this; @@ -986,7 +1088,7 @@ export interface Page { /** * Emitted when attachment download started. User can access basic file operations on downloaded content via the - * passed {@link Download} instance. + * passed [Download](https://playwright.dev/docs/api/class-download) instance. */ on(event: 'download', listener: (download: Download) => any): this; @@ -1053,7 +1155,7 @@ export interface Page { * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route) * and * [browserContext.on('request')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-request) - * respectively instead of similar methods on the {@link Page}. + * respectively instead of similar methods on the [Page](https://playwright.dev/docs/api/class-page). * * ```js * // Start waiting for popup before clicking. Note no await. @@ -1066,6 +1168,7 @@ export interface Page { * **NOTE** Use * [page.waitForLoadState([state, options])](https://playwright.dev/docs/api/class-page#page-wait-for-load-state) to * wait until the page gets to a particular state (you should not need it in most cases). + * */ on(event: 'popup', listener: (page: Page) => any): this; @@ -1091,6 +1194,7 @@ export interface Page { * with [page.on('requestfailed')](https://playwright.dev/docs/api/class-page#page-event-request-failed). A request * will only be considered failed when the client cannot get an HTTP response from the server, e.g. due to network * error net::ERR_FAILED. + * */ on(event: 'requestfailed', listener: (request: Request) => any): this; @@ -1107,7 +1211,7 @@ export interface Page { on(event: 'response', listener: (response: Response) => any): this; /** - * Emitted when {@link WebSocket} request is sent. + * Emitted when [WebSocket](https://playwright.dev/docs/api/class-websocket) request is sent. */ on(event: 'websocket', listener: (webSocket: WebSocket) => any): this; @@ -1220,7 +1324,8 @@ export interface Page { /** * Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. * - * The arguments passed into `console.log` are available on the {@link ConsoleMessage} event handler argument. + * The arguments passed into `console.log` are available on the + * [ConsoleMessage](https://playwright.dev/docs/api/class-consolemessage) event handler argument. * * **Usage** * @@ -1273,6 +1378,7 @@ export interface Page { * **NOTE** When no [page.on('dialog')](https://playwright.dev/docs/api/class-page#page-event-dialog) or * [browserContext.on('dialog')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-dialog) * listeners are present, all dialogs are automatically dismissed. + * */ addListener(event: 'dialog', listener: (dialog: Dialog) => any): this; @@ -1284,7 +1390,7 @@ export interface Page { /** * Emitted when attachment download started. User can access basic file operations on downloaded content via the - * passed {@link Download} instance. + * passed [Download](https://playwright.dev/docs/api/class-download) instance. */ addListener(event: 'download', listener: (download: Download) => any): this; @@ -1351,7 +1457,7 @@ export interface Page { * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route) * and * [browserContext.on('request')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-request) - * respectively instead of similar methods on the {@link Page}. + * respectively instead of similar methods on the [Page](https://playwright.dev/docs/api/class-page). * * ```js * // Start waiting for popup before clicking. Note no await. @@ -1364,6 +1470,7 @@ export interface Page { * **NOTE** Use * [page.waitForLoadState([state, options])](https://playwright.dev/docs/api/class-page#page-wait-for-load-state) to * wait until the page gets to a particular state (you should not need it in most cases). + * */ addListener(event: 'popup', listener: (page: Page) => any): this; @@ -1389,6 +1496,7 @@ export interface Page { * with [page.on('requestfailed')](https://playwright.dev/docs/api/class-page#page-event-request-failed). A request * will only be considered failed when the client cannot get an HTTP response from the server, e.g. due to network * error net::ERR_FAILED. + * */ addListener(event: 'requestfailed', listener: (request: Request) => any): this; @@ -1405,7 +1513,7 @@ export interface Page { addListener(event: 'response', listener: (response: Response) => any): this; /** - * Emitted when {@link WebSocket} request is sent. + * Emitted when [WebSocket](https://playwright.dev/docs/api/class-websocket) request is sent. */ addListener(event: 'websocket', listener: (webSocket: WebSocket) => any): this; @@ -1613,7 +1721,8 @@ export interface Page { /** * Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. * - * The arguments passed into `console.log` are available on the {@link ConsoleMessage} event handler argument. + * The arguments passed into `console.log` are available on the + * [ConsoleMessage](https://playwright.dev/docs/api/class-consolemessage) event handler argument. * * **Usage** * @@ -1666,6 +1775,7 @@ export interface Page { * **NOTE** When no [page.on('dialog')](https://playwright.dev/docs/api/class-page#page-event-dialog) or * [browserContext.on('dialog')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-dialog) * listeners are present, all dialogs are automatically dismissed. + * */ prependListener(event: 'dialog', listener: (dialog: Dialog) => any): this; @@ -1677,7 +1787,7 @@ export interface Page { /** * Emitted when attachment download started. User can access basic file operations on downloaded content via the - * passed {@link Download} instance. + * passed [Download](https://playwright.dev/docs/api/class-download) instance. */ prependListener(event: 'download', listener: (download: Download) => any): this; @@ -1744,7 +1854,7 @@ export interface Page { * [browserContext.route(url, handler[, options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-route) * and * [browserContext.on('request')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-request) - * respectively instead of similar methods on the {@link Page}. + * respectively instead of similar methods on the [Page](https://playwright.dev/docs/api/class-page). * * ```js * // Start waiting for popup before clicking. Note no await. @@ -1757,6 +1867,7 @@ export interface Page { * **NOTE** Use * [page.waitForLoadState([state, options])](https://playwright.dev/docs/api/class-page#page-wait-for-load-state) to * wait until the page gets to a particular state (you should not need it in most cases). + * */ prependListener(event: 'popup', listener: (page: Page) => any): this; @@ -1782,6 +1893,7 @@ export interface Page { * with [page.on('requestfailed')](https://playwright.dev/docs/api/class-page#page-event-request-failed). A request * will only be considered failed when the client cannot get an HTTP response from the server, e.g. due to network * error net::ERR_FAILED. + * */ prependListener(event: 'requestfailed', listener: (request: Request) => any): this; @@ -1798,7 +1910,7 @@ export interface Page { prependListener(event: 'response', listener: (response: Response) => any): this; /** - * Emitted when {@link WebSocket} request is sent. + * Emitted when [WebSocket](https://playwright.dev/docs/api/class-websocket) request is sent. */ prependListener(event: 'websocket', listener: (webSocket: WebSocket) => any): this; @@ -1826,7 +1938,8 @@ export interface Page { * handler is only called when you perform an action/assertion - if the overlay becomes visible but you don't * perform any actions, the handler will not be triggered. * - After executing the handler, Playwright will ensure that overlay that triggered the handler is not visible - * anymore. You can opt-out of this behavior with `noWaitAfter`. + * anymore. You can opt-out of this behavior with + * [`noWaitAfter`](https://playwright.dev/docs/api/class-page#page-add-locator-handler-option-no-wait-after). * - The execution time of the handler counts towards the timeout of the action/assertion that executed the handler. * If your handler takes too long, it might cause timeouts. * - You can register multiple handlers. However, only a single handler will be running at a time. Make sure the @@ -1834,13 +1947,17 @@ export interface Page { * * **NOTE** Running the handler will alter your page state mid-test. For example it will change the currently focused * element and move the mouse. Make sure that actions that run after the handler are self-contained and do not rely on - * the focus and mouse state being unchanged.

For example, consider a test that calls + * the focus and mouse state being unchanged. + * + * For example, consider a test that calls * [locator.focus([options])](https://playwright.dev/docs/api/class-locator#locator-focus) followed by * [keyboard.press(key[, options])](https://playwright.dev/docs/api/class-keyboard#keyboard-press). If your handler * clicks a button between these two actions, the focused element most likely will be wrong, and key press will happen * on the unexpected element. Use * [locator.press(key[, options])](https://playwright.dev/docs/api/class-locator#locator-press) instead to avoid this - * problem.

Another example is a series of mouse actions, where + * problem. + * + * Another example is a series of mouse actions, where * [mouse.move(x, y[, options])](https://playwright.dev/docs/api/class-mouse#mouse-move) is followed by * [mouse.down([options])](https://playwright.dev/docs/api/class-mouse#mouse-down). Again, when the handler runs * between these two actions, the mouse position will be wrong during the mouse down. Prefer self-contained actions @@ -1876,8 +1993,9 @@ export interface Page { * ``` * * An example with a custom callback on every actionability check. It uses a `` locator that is always visible, - * so the handler is called before every actionability check. It is important to specify `noWaitAfter`, because the - * handler does not hide the `` element. + * so the handler is called before every actionability check. It is important to specify + * [`noWaitAfter`](https://playwright.dev/docs/api/class-page#page-add-locator-handler-option-no-wait-after), because + * the handler does not hide the `` element. * * ```js * // Setup the handler. @@ -1891,7 +2009,7 @@ export interface Page { * ``` * * Handler takes the original locator as an argument. You can also automatically remove the handler after a number of - * invocations by setting `times`: + * invocations by setting [`times`](https://playwright.dev/docs/api/class-page#page-add-locator-handler-option-times): * * ```js * await page.addLocatorHandler(page.getByLabel('Close'), async locator => { @@ -1900,8 +2018,9 @@ export interface Page { * ``` * * @param locator Locator that triggers the handler. - * @param handler Function that should be run once `locator` appears. This function should get rid of the element that blocks actions - * like click. + * @param handler Function that should be run once + * [`locator`](https://playwright.dev/docs/api/class-page#page-add-locator-handler-option-locator) appears. This + * function should get rid of the element that blocks actions like click. * @param options */ addLocatorHandler(locator: Locator, handler: ((locator: Locator) => Promise), options?: { @@ -1979,19 +2098,24 @@ export interface Page { * **NOTE** Use locator-based [locator.check([options])](https://playwright.dev/docs/api/class-locator#locator-check) instead. * Read more about [locators](https://playwright.dev/docs/locators). * - * This method checks an element matching `selector` by performing the following steps: - * 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM. + * This method checks an element matching + * [`selector`](https://playwright.dev/docs/api/class-page#page-check-option-selector) by performing the following + * steps: + * 1. Find an element matching [`selector`](https://playwright.dev/docs/api/class-page#page-check-option-selector). + * If there is none, wait until a matching element is attached to the DOM. * 1. Ensure that matched element is a checkbox or a radio input. If not, this method throws. If the element is * already checked, this method returns immediately. - * 1. Wait for [actionability](https://playwright.dev/docs/actionability) checks on the matched element, unless `force` option is set. If - * the element is detached during the checks, the whole action is retried. + * 1. Wait for [actionability](https://playwright.dev/docs/actionability) checks on the matched element, unless + * [`force`](https://playwright.dev/docs/api/class-page#page-check-option-force) option is set. If the element + * is detached during the checks, the whole action is retried. * 1. Scroll the element into view if needed. * 1. Use [page.mouse](https://playwright.dev/docs/api/class-page#page-mouse) to click in the center of the * element. * 1. Ensure that the element is now checked. If not, this method throws. * - * When all steps combined have not finished during the specified `timeout`, this method throws a {@link - * TimeoutError}. Passing zero timeout disables this. + * When all steps combined have not finished during the specified + * [`timeout`](https://playwright.dev/docs/api/class-page#page-check-option-timeout), this method throws a + * [TimeoutError](https://playwright.dev/docs/api/class-timeouterror). Passing zero timeout disables this. * @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be * used. * @param options @@ -2043,17 +2167,24 @@ export interface Page { * **NOTE** Use locator-based [locator.click([options])](https://playwright.dev/docs/api/class-locator#locator-click) instead. * Read more about [locators](https://playwright.dev/docs/locators). * - * This method clicks an element matching `selector` by performing the following steps: - * 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM. - * 1. Wait for [actionability](https://playwright.dev/docs/actionability) checks on the matched element, unless `force` option is set. If - * the element is detached during the checks, the whole action is retried. + * This method clicks an element matching + * [`selector`](https://playwright.dev/docs/api/class-page#page-click-option-selector) by performing the following + * steps: + * 1. Find an element matching [`selector`](https://playwright.dev/docs/api/class-page#page-click-option-selector). + * If there is none, wait until a matching element is attached to the DOM. + * 1. Wait for [actionability](https://playwright.dev/docs/actionability) checks on the matched element, unless + * [`force`](https://playwright.dev/docs/api/class-page#page-click-option-force) option is set. If the element + * is detached during the checks, the whole action is retried. * 1. Scroll the element into view if needed. * 1. Use [page.mouse](https://playwright.dev/docs/api/class-page#page-mouse) to click in the center of the - * element, or the specified `position`. - * 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. + * element, or the specified + * [`position`](https://playwright.dev/docs/api/class-page#page-click-option-position). + * 1. Wait for initiated navigations to either succeed or fail, unless + * [`noWaitAfter`](https://playwright.dev/docs/api/class-page#page-click-option-no-wait-after) option is set. * - * When all steps combined have not finished during the specified `timeout`, this method throws a {@link - * TimeoutError}. Passing zero timeout disables this. + * When all steps combined have not finished during the specified + * [`timeout`](https://playwright.dev/docs/api/class-page#page-click-option-timeout), this method throws a + * [TimeoutError](https://playwright.dev/docs/api/class-timeouterror). Passing zero timeout disables this. * @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be * used. * @param options @@ -2128,13 +2259,17 @@ export interface Page { }): Promise; /** - * If `runBeforeUnload` is `false`, does not run any unload handlers and waits for the page to be closed. If - * `runBeforeUnload` is `true` the method will run unload handlers, but will **not** wait for the page to close. + * If [`runBeforeUnload`](https://playwright.dev/docs/api/class-page#page-close-option-run-before-unload) is `false`, + * does not run any unload handlers and waits for the page to be closed. If + * [`runBeforeUnload`](https://playwright.dev/docs/api/class-page#page-close-option-run-before-unload) is `true` the + * method will run unload handlers, but will **not** wait for the page to close. * * By default, `page.close()` **does not** run `beforeunload` handlers. * - * **NOTE** if `runBeforeUnload` is passed as true, a `beforeunload` dialog might be summoned and should be handled - * manually via [page.on('dialog')](https://playwright.dev/docs/api/class-page#page-event-dialog) event. + * **NOTE** if [`runBeforeUnload`](https://playwright.dev/docs/api/class-page#page-close-option-run-before-unload) is + * passed as true, a `beforeunload` dialog might be summoned and should be handled manually via + * [page.on('dialog')](https://playwright.dev/docs/api/class-page#page-event-dialog) event. + * * @param options */ close(options?: { @@ -2164,18 +2299,26 @@ export interface Page { * **NOTE** Use locator-based [locator.dblclick([options])](https://playwright.dev/docs/api/class-locator#locator-dblclick) * instead. Read more about [locators](https://playwright.dev/docs/locators). * - * This method double clicks an element matching `selector` by performing the following steps: - * 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM. - * 1. Wait for [actionability](https://playwright.dev/docs/actionability) checks on the matched element, unless `force` option is set. If - * the element is detached during the checks, the whole action is retried. + * This method double clicks an element matching + * [`selector`](https://playwright.dev/docs/api/class-page#page-dblclick-option-selector) by performing the following + * steps: + * 1. Find an element matching + * [`selector`](https://playwright.dev/docs/api/class-page#page-dblclick-option-selector). If there is none, + * wait until a matching element is attached to the DOM. + * 1. Wait for [actionability](https://playwright.dev/docs/actionability) checks on the matched element, unless + * [`force`](https://playwright.dev/docs/api/class-page#page-dblclick-option-force) option is set. If the + * element is detached during the checks, the whole action is retried. * 1. Scroll the element into view if needed. * 1. Use [page.mouse](https://playwright.dev/docs/api/class-page#page-mouse) to double click in the center of the - * element, or the specified `position`. + * element, or the specified + * [`position`](https://playwright.dev/docs/api/class-page#page-dblclick-option-position). * - * When all steps combined have not finished during the specified `timeout`, this method throws a {@link - * TimeoutError}. Passing zero timeout disables this. + * When all steps combined have not finished during the specified + * [`timeout`](https://playwright.dev/docs/api/class-page#page-dblclick-option-timeout), this method throws a + * [TimeoutError](https://playwright.dev/docs/api/class-timeouterror). Passing zero timeout disables this. * * **NOTE** `page.dblclick()` dispatches two `click` events and a single `dblclick` event. + * * @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be * used. * @param options @@ -2257,10 +2400,13 @@ export interface Page { * await page.dispatchEvent('button#submit', 'click'); * ``` * - * Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` - * properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default. + * Under the hood, it creates an instance of an event based on the given + * [`type`](https://playwright.dev/docs/api/class-page#page-dispatch-event-option-type), initializes it with + * [`eventInit`](https://playwright.dev/docs/api/class-page#page-dispatch-event-option-event-init) properties and + * dispatches it on the element. Events are `composed`, `cancelable` and bubble by default. * - * Since `eventInit` is event-specific, please refer to the events documentation for the lists of initial properties: + * Since [`eventInit`](https://playwright.dev/docs/api/class-page#page-dispatch-event-option-event-init) is + * event-specific, please refer to the events documentation for the lists of initial properties: * - [DeviceMotionEvent](https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent/DeviceMotionEvent) * - [DeviceOrientationEvent](https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent/DeviceOrientationEvent) * - [DragEvent](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/DragEvent) @@ -2440,10 +2586,15 @@ export interface Page { }): Promise; /** - * The method adds a function called `name` on the `window` object of every frame in the page. When called, the - * function executes `callback` and returns a [Promise] which resolves to the return value of `callback`. + * The method adds a function called + * [`name`](https://playwright.dev/docs/api/class-page#page-expose-function-option-name) on the `window` object of + * every frame in the page. When called, the function executes + * [`callback`](https://playwright.dev/docs/api/class-page#page-expose-function-option-callback) and returns a + * [Promise] which resolves to the return value of + * [`callback`](https://playwright.dev/docs/api/class-page#page-expose-function-option-callback). * - * If the `callback` returns a [Promise], it will be awaited. + * If the [`callback`](https://playwright.dev/docs/api/class-page#page-expose-function-option-callback) returns a + * [Promise], it will be awaited. * * See * [browserContext.exposeFunction(name, callback)](https://playwright.dev/docs/api/class-browsercontext#browser-context-expose-function) @@ -2489,9 +2640,10 @@ export interface Page { * **NOTE** Use locator-based [locator.fill(value[, options])](https://playwright.dev/docs/api/class-locator#locator-fill) * instead. Read more about [locators](https://playwright.dev/docs/locators). * - * This method waits for an element matching `selector`, waits for [actionability](https://playwright.dev/docs/actionability) checks, - * focuses the element, fills it and triggers an `input` event after filling. Note that you can pass an empty string - * to clear the input field. + * This method waits for an element matching + * [`selector`](https://playwright.dev/docs/api/class-page#page-fill-option-selector), waits for + * [actionability](https://playwright.dev/docs/actionability) checks, focuses the element, fills it and triggers an `input` event after + * filling. Note that you can pass an empty string to clear the input field. * * If the target element is not an ``, `