From a1b60553477e78545b10ab3837486e3d9a30fe3f Mon Sep 17 00:00:00 2001 From: Can Stand <70889873+canstand@users.noreply.github.com> Date: Fri, 6 Sep 2024 16:51:55 +0800 Subject: [PATCH] chore: roll to Playwright v1.47.0 (#480) --- .github/workflows/build.yml | 13 +- .github/workflows/verify_type_generation.yml | 2 +- README.md | 8 +- browser.go | 55 +++ browser_type.go | 8 + fetch.go | 11 + generated-interfaces.go | 115 ++--- generated-structs.go | 420 +++++++++++------- js_handle.go | 28 ++ locator.go | 5 +- patches/main.patch | 375 +++++++++------- playwright | 2 +- run.go | 2 +- tests/assets/client-certificates/README.md | 62 +++ .../client/self-signed/cert.pem | 28 ++ .../client/self-signed/csr.pem | 26 ++ .../client/self-signed/key.pem | 52 +++ .../client/trusted/cert-legacy.pfx | Bin 0 -> 4045 bytes .../client/trusted/cert.pem | 29 ++ .../client/trusted/cert.pfx | Bin 0 -> 4195 bytes .../client/trusted/csr.pem | 26 ++ .../client/trusted/key.pem | 52 +++ .../server/server_cert.pem | 32 ++ .../client-certificates/server/server_key.pem | 52 +++ tests/binding_test.go | 4 +- ...rowser_context_client_certificates_test.go | 206 +++++++++ tests/browser_context_test.go | 24 + tests/fetch_test.go | 28 ++ tests/js_handle_test.go | 32 +- tests/utils_test.go | 9 + tracing.go | 35 +- 31 files changed, 1310 insertions(+), 431 deletions(-) create mode 100644 tests/assets/client-certificates/README.md create mode 100644 tests/assets/client-certificates/client/self-signed/cert.pem create mode 100644 tests/assets/client-certificates/client/self-signed/csr.pem create mode 100644 tests/assets/client-certificates/client/self-signed/key.pem create mode 100644 tests/assets/client-certificates/client/trusted/cert-legacy.pfx create mode 100644 tests/assets/client-certificates/client/trusted/cert.pem create mode 100644 tests/assets/client-certificates/client/trusted/cert.pfx create mode 100644 tests/assets/client-certificates/client/trusted/csr.pem create mode 100644 tests/assets/client-certificates/client/trusted/key.pem create mode 100644 tests/assets/client-certificates/server/server_cert.pem create mode 100644 tests/assets/client-certificates/server/server_key.pem create mode 100644 tests/browser_context_client_certificates_test.go diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c4af2409..11c14244 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v5 with: - go-version: ^1.19.9 + go-version: oldstable id: go - name: golangci-lint uses: golangci/golangci-lint-action@v6 @@ -27,8 +27,9 @@ jobs: # https://github.com/microsoft/playwright/issues/30705 is fixed. os: [ubuntu-latest, windows-latest, macos-13] browser: [chromium, firefox, webkit] + go: ['stable', 'oldstable'] runs-on: ${{ matrix.os }} - name: ${{ matrix.browser }} on ${{ matrix.os }} + name: ${{ matrix.browser }} on ${{ matrix.os }}, go ${{ matrix.go }} steps: - uses: actions/checkout@v4 with: @@ -36,7 +37,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: ^1.19.9 + go-version: ${{ matrix.go }} id: go - name: Cache drivers uses: actions/cache@v4 @@ -52,7 +53,7 @@ jobs: ~/Library/Caches/ms-playwright ~\AppData\Local\ms-playwright-go ~\AppData\Local\ms-playwright - key: ${{ runner.os }}-go-${{ matrix.browser }}-${{ hashFiles('**/run.go') }} + key: ${{ runner.os }}-go${{ matrix.go }}-${{ matrix.browser }}-${{ hashFiles('**/run.go') }} - run: | go install ./... playwright install --with-deps ${{ matrix.browser }} @@ -84,7 +85,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: ^1.19.9 + go-version: oldstable id: go - name: Install goveralls run: go install github.com/mattn/goveralls@latest @@ -99,7 +100,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v5 with: - go-version: ^1.19.9 + go-version: oldstable id: go - run: | go install ./... diff --git a/.github/workflows/verify_type_generation.yml b/.github/workflows/verify_type_generation.yml index 297def67..4fa433d5 100644 --- a/.github/workflows/verify_type_generation.yml +++ b/.github/workflows/verify_type_generation.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: ^1.19.9 + go-version: oldstable - name: Install gofumpt run: go install mvdan.cc/gofumpt@latest - name: Install Browsers diff --git a/README.md b/README.md index 99f4aaf0..02ac77d2 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![PkgGoDev](https://pkg.go.dev/badge/github.com/playwright-community/playwright-go)](https://pkg.go.dev/github.com/playwright-community/playwright-go) [![License](https://img.shields.io/badge/License-MIT-blue.svg)](http://opensource.org/licenses/MIT) [![Go Report Card](https://goreportcard.com/badge/github.com/playwright-community/playwright-go)](https://goreportcard.com/report/github.com/playwright-community/playwright-go) ![Build Status](https://github.com/playwright-community/playwright-go/workflows/Go/badge.svg) -[![Join Slack](https://img.shields.io/badge/join-slack-infomational)](https://aka.ms/playwright-slack) [![Coverage Status](https://coveralls.io/repos/github/playwright-community/playwright-go/badge.svg?branch=main)](https://coveralls.io/github/playwright-community/playwright-go?branch=main) [![Chromium version](https://img.shields.io/badge/chromium-127.0.6533.17-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-127.0-blue.svg?logo=mozilla-firefox)](https://www.mozilla.org/en-US/firefox/new/) [![WebKit version](https://img.shields.io/badge/webkit-17.4-blue.svg?logo=safari)](https://webkit.org/) +[![Join Slack](https://img.shields.io/badge/join-slack-infomational)](https://aka.ms/playwright-slack) [![Coverage Status](https://coveralls.io/repos/github/playwright-community/playwright-go/badge.svg?branch=main)](https://coveralls.io/github/playwright-community/playwright-go?branch=main) [![Chromium version](https://img.shields.io/badge/chromium-129.0.6668.29-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-130.0-blue.svg?logo=mozilla-firefox)](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/) [API reference](https://playwright.dev/docs/api/class-playwright) | [Example recipes](https://github.com/playwright-community/playwright-go/tree/main/examples) @@ -13,9 +13,9 @@ Playwright is a Go library to automate [Chromium](https://www.chromium.org/Home) | | Linux | macOS | Windows | | :--- | :---: | :---: | :---: | -| Chromium 127.0.6533.17 | ✅ | ✅ | ✅ | -| WebKit 17.4 | ✅ | ✅ | ✅ | -| Firefox 127.0 | ✅ | ✅ | ✅ | +| Chromium 129.0.6668.29 | ✅ | ✅ | ✅ | +| WebKit 18.0 | ✅ | ✅ | ✅ | +| Firefox 130.0 | ✅ | ✅ | ✅ | Headless execution is supported for all the browsers on all platforms. diff --git a/browser.go b/browser.go index cca7abbd..c87540ab 100644 --- a/browser.go +++ b/browser.go @@ -1,6 +1,7 @@ package playwright import ( + "encoding/base64" "encoding/json" "errors" "fmt" @@ -46,6 +47,14 @@ func (b *browserImpl) NewContext(options ...BrowserNewContextOptions) (BrowserCo overrides["extraHTTPHeaders"] = serializeMapToNameAndValue(options[0].ExtraHttpHeaders) options[0].ExtraHttpHeaders = nil } + if option.ClientCertificates != nil { + certs, err := transformClientCertificate(option.ClientCertificates) + if err != nil { + return nil, err + } + overrides["clientCertificates"] = certs + options[0].ClientCertificates = nil + } if option.StorageStatePath != nil { var storageState *OptionalStorageState storageString, err := os.ReadFile(*options[0].StorageStatePath) @@ -217,3 +226,49 @@ func newBrowser(parent *channelOwner, objectType string, guid string, initialize b.channel.On("close", b.onClose) return b } + +func transformClientCertificate(clientCertificates []ClientCertificate) ([]map[string]interface{}, error) { + results := make([]map[string]interface{}, 0) + + for _, cert := range clientCertificates { + data := map[string]interface{}{ + "origin": cert.Origin, + "passphrase": cert.Passphrase, + } + if len(cert.Cert) > 0 { + data["cert"] = base64.StdEncoding.EncodeToString(cert.Cert) + } else if cert.CertPath != nil { + content, err := os.ReadFile(*cert.CertPath) + if err != nil { + return nil, err + } + data["cert"] = base64.StdEncoding.EncodeToString(content) + } + + if len(cert.Key) > 0 { + data["key"] = base64.StdEncoding.EncodeToString(cert.Key) + } else if cert.KeyPath != nil { + content, err := os.ReadFile(*cert.KeyPath) + if err != nil { + return nil, err + } + data["key"] = base64.StdEncoding.EncodeToString(content) + } + + if len(cert.Pfx) > 0 { + data["pfx"] = base64.StdEncoding.EncodeToString(cert.Pfx) + } else if cert.PfxPath != nil { + content, err := os.ReadFile(*cert.PfxPath) + if err != nil { + return nil, err + } + data["pfx"] = base64.StdEncoding.EncodeToString(content) + } + + results = append(results, data) + } + if len(results) == 0 { + return nil, nil + } + return results, nil +} diff --git a/browser_type.go b/browser_type.go index e1202caa..fd160b71 100644 --- a/browser_type.go +++ b/browser_type.go @@ -52,6 +52,14 @@ func (b *browserTypeImpl) LaunchPersistentContext(userDataDir string, options .. } options[0].AcceptDownloads = nil } + if options[0].ClientCertificates != nil { + certs, err := transformClientCertificate(options[0].ClientCertificates) + if err != nil { + return nil, err + } + overrides["clientCertificates"] = certs + options[0].ClientCertificates = nil + } if options[0].ExtraHttpHeaders != nil { overrides["extraHTTPHeaders"] = serializeMapToNameAndValue(options[0].ExtraHttpHeaders) options[0].ExtraHttpHeaders = nil diff --git a/fetch.go b/fetch.go index c88e8b8c..89ca5187 100644 --- a/fetch.go +++ b/fetch.go @@ -16,6 +16,14 @@ type apiRequestImpl struct { func (r *apiRequestImpl) NewContext(options ...APIRequestNewContextOptions) (APIRequestContext, error) { overrides := map[string]interface{}{} if len(options) == 1 { + if options[0].ClientCertificates != nil { + certs, err := transformClientCertificate(options[0].ClientCertificates) + if err != nil { + return nil, err + } + overrides["clientCertificates"] = certs + options[0].ClientCertificates = nil + } if options[0].ExtraHttpHeaders != nil { overrides["extraHTTPHeaders"] = serializeMapToNameAndValue(options[0].ExtraHttpHeaders) options[0].ExtraHttpHeaders = nil @@ -105,6 +113,9 @@ func (r *apiRequestContextImpl) innerFetch(url string, request Request, options if options[0].MaxRedirects != nil && *options[0].MaxRedirects < 0 { return nil, errors.New("maxRedirects must be non-negative") } + if options[0].MaxRetries != nil && *options[0].MaxRetries < 0 { + return nil, errors.New("maxRetries must be non-negative") + } // only one of them can be specified if countNonNil(options[0].Data, options[0].Form, options[0].Multipart) > 1 { return nil, errors.New("only one of 'data', 'form' or 'multipart' can be specified") diff --git a/generated-interfaces.go b/generated-interfaces.go index 5a78cdae..6354f1ca 100644 --- a/generated-interfaces.go +++ b/generated-interfaces.go @@ -103,8 +103,8 @@ type APIResponse interface { // An object with all the response HTTP headers associated with this response. Headers() map[string]string - // An array with all the request HTTP headers associated with this response. Header names are not lower-cased. Headers - // with multiple entries, such as `Set-Cookie`, appear in the array multiple times. + // An array with all the response HTTP headers associated with this response. Header names are not lower-cased. + // Headers with multiple entries, such as `Set-Cookie`, appear in the array multiple times. HeadersArray() []NameValue // Returns the JSON representation of response body. @@ -209,12 +209,11 @@ type Browser interface { Version() string } -// BrowserContexts provide a way to operate multiple independent browser sessions. -// +// BrowserContexts provide a way to operate multiple independent browser sessions. // If a page opens another page, e.g. with a `window.open` call, the popup will belong to the parent page's browser // context. -// Playwright allows creating "incognito" browser contexts with [Browser.NewContext] method. "Incognito" browser -// contexts don't write any browsing data to disk. +// Playwright allows creating isolated non-persistent browser contexts with [Browser.NewContext] method. +// Non-persistent browser contexts don't write any browsing data to disk. type BrowserContext interface { EventEmitter // **NOTE** Only works with Chromium browser's persistent context. @@ -280,10 +279,6 @@ type BrowserContext interface { // Adds cookies into this browser context. All pages within this context will have these cookies installed. Cookies // can be obtained via [BrowserContext.Cookies]. - // - // cookies: Adds cookies to the browser context. - // - // For the cookie to apply to all subdomains as well, prefix domain with a dot, like this: ".example.com". AddCookies(cookies []OptionalCookie) error // Adds a script which would be evaluated in one of the following scenarios: @@ -526,9 +521,9 @@ type BrowserType interface { Name() string } -// The `CDPSession` instances are used to talk raw Chrome Devtools Protocol: -// - protocol methods can be called with `session.send` method. -// - protocol events can be subscribed to with `session.on` method. +// The `CDPSession` instances are used to talk raw Chrome Devtools Protocol: +// - protocol methods can be called with `session.send` method. +// - protocol events can be subscribed to with `session.on` method. // // Useful links: // - Documentation on DevTools Protocol can be found here: @@ -589,6 +584,8 @@ type Clock interface { // unless [Clock.RunFor], [Clock.FastForward], [Clock.PauseAt] or [Clock.Resume] is called. // Only fires due timers at most once. This is equivalent to user closing the laptop lid for a while and reopening it // at the specified time and pausing. + // + // time: Time to pause at. PauseAt(time interface{}) error // Resumes timers. Once this method is called, time resumes flowing, timers are fired as usual. @@ -600,6 +597,8 @@ type Clock interface { SetFixedTime(time interface{}) error // Sets current system time but does not trigger any timers. + // + // time: Time to be set. SetSystemTime(time interface{}) error } @@ -733,8 +732,7 @@ type ElementHandle interface { // 2. Wait for [actionability] checks on the element, unless “force” option is set. // 3. Scroll the element into view if needed. // 4. Use [Page.Mouse] to click in the center of the element. - // 5. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 6. Ensure that the element is now checked. If not, this method throws. + // 5. Ensure that the element is now checked. If not, this method throws. // If the element is detached from the DOM at any moment during the action, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. @@ -767,8 +765,6 @@ type ElementHandle interface { // 1. Wait for [actionability] checks on the element, unless “force” option is set. // 2. Scroll the element into view if needed. // 3. Use [Page.Mouse] to double click in the center of the element, or the specified “position”. - // 4. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. Note that if - // the first click of the `dblclick()` triggers a navigation event, this method will throw. // If the element is detached from the DOM at any moment during the action, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. @@ -869,7 +865,6 @@ type ElementHandle interface { // 1. Wait for [actionability] checks on the element, unless “force” option is set. // 2. Scroll the element into view if needed. // 3. Use [Page.Mouse] to hover over the center of the element, or the specified “position”. - // 4. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. // If the element is detached from the DOM at any moment during the action, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. @@ -1065,8 +1060,7 @@ type ElementHandle interface { // the element is detached during the checks, the whole action is retried. // 4. Scroll the element into view if needed. // 5. Use [Page.Mouse] to click in the center of the element. - // 6. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 7. Ensure that the element is now checked or unchecked. If not, this method throws. + // 6. Ensure that the element is now checked or unchecked. If not, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // @@ -1097,7 +1091,6 @@ type ElementHandle interface { // 1. Wait for [actionability] checks on the element, unless “force” option is set. // 2. Scroll the element into view if needed. // 3. Use [Page.Touchscreen] to tap the center of the element, or the specified “position”. - // 4. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. // If the element is detached from the DOM at any moment during the action, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. @@ -1131,8 +1124,7 @@ type ElementHandle interface { // 2. Wait for [actionability] checks on the element, unless “force” option is set. // 3. Scroll the element into view if needed. // 4. Use [Page.Mouse] to click in the center of the element. - // 5. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 6. Ensure that the element is now unchecked. If not, this method throws. + // 5. Ensure that the element is now unchecked. If not, this method throws. // If the element is detached from the DOM at any moment during the action, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. @@ -1225,8 +1217,7 @@ type Frame interface { // the element is detached during the checks, the whole action is retried. // 4. Scroll the element into view if needed. // 5. Use [Page.Mouse] to click in the center of the element. - // 6. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 7. Ensure that the element is now checked. If not, this method throws. + // 6. 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 [TimeoutError]. // Passing zero timeout disables this. // @@ -1268,9 +1259,8 @@ type Frame interface { // 2. Wait for [actionability] checks on the matched element, unless “force” option is set. If // the element is detached during the checks, the whole action is retried. // 3. Scroll the element into view if needed. - // 4. Use [Page.Mouse] to double click in the center of the element, or the specified “position”. - // 5. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. Note that if - // the first click of the `dblclick()` triggers a navigation event, this method will throw. + // 4. Use [Page.Mouse] to double click in the center of the element, or the specified “position”. if the first + // click of the `dblclick()` triggers a navigation event, this method will throw. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // **NOTE** `frame.dblclick()` dispatches two `click` events and a single `dblclick` event. @@ -1514,7 +1504,6 @@ type Frame interface { // the element is detached during the checks, the whole action is retried. // 3. Scroll the element into view if needed. // 4. Use [Page.Mouse] to hover over the center of the element, or the specified “position”. - // 5. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // @@ -1728,8 +1717,7 @@ type Frame interface { // the element is detached during the checks, the whole action is retried. // 5. Scroll the element into view if needed. // 6. Use [Page.Mouse] to click in the center of the element. - // 7. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 8. Ensure that the element is now checked or unchecked. If not, this method throws. + // 7. Ensure that the element is now checked or unchecked. If not, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // @@ -1774,7 +1762,6 @@ type Frame interface { // the element is detached during the checks, the whole action is retried. // 3. Scroll the element into view if needed. // 4. Use [Page.Touchscreen] to tap the center of the element, or the specified “position”. - // 5. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // **NOTE** `frame.tap()` requires that the `hasTouch` option of the browser context be set to true. @@ -1820,8 +1807,7 @@ type Frame interface { // the element is detached during the checks, the whole action is retried. // 4. Scroll the element into view if needed. // 5. Use [Page.Mouse] to click in the center of the element. - // 6. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 7. Ensure that the element is now unchecked. If not, this method throws. + // 6. Ensure that the element is now unchecked. If not, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // @@ -2200,8 +2186,7 @@ type Locator interface { // 2. Wait for [actionability] checks on the element, unless “force” option is set. // 3. Scroll the element into view if needed. // 4. Use [Page.Mouse] to click in the center of the element. - // 5. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 6. Ensure that the element is now checked. If not, this method throws. + // 5. Ensure that the element is now checked. If not, this method throws. // If the element is detached from the DOM at any moment during the action, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. @@ -2255,8 +2240,6 @@ type Locator interface { // 1. Wait for [actionability] checks on the element, unless “force” option is set. // 2. Scroll the element into view if needed. // 3. Use [Page.Mouse] to double click in the center of the element, or the specified “position”. - // 4. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. Note that if - // the first click of the `dblclick()` triggers a navigation event, this method will throw. // If the element is detached from the DOM at any moment during the action, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. @@ -2500,7 +2483,6 @@ type Locator interface { // 1. Wait for [actionability] checks on the element, unless “force” option is set. // 2. Scroll the element into view if needed. // 3. Use [Page.Mouse] to hover over the center of the element, or the specified “position”. - // 4. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. // If the element is detached from the DOM at any moment during the action, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. @@ -2703,8 +2685,7 @@ type Locator interface { // the element is detached during the checks, the whole action is retried. // 4. Scroll the element into view if needed. // 5. Use [Page.Mouse] to click in the center of the element. - // 6. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 7. Ensure that the element is now checked or unchecked. If not, this method throws. + // 6. Ensure that the element is now checked or unchecked. If not, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // @@ -2737,7 +2718,6 @@ type Locator interface { // 1. Wait for [actionability] checks on the element, unless “force” option is set. // 2. Scroll the element into view if needed. // 3. Use [Page.Touchscreen] to tap the center of the element, or the specified “position”. - // 4. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. // If the element is detached from the DOM at any moment during the action, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. @@ -2773,8 +2753,7 @@ type Locator interface { // 2. Wait for [actionability] checks on the element, unless “force” option is set. // 3. Scroll the element into view if needed. // 4. Use [Page.Mouse] to click in the center of the element. - // 5. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 6. Ensure that the element is now unchecked. If not, this method throws. + // 5. Ensure that the element is now unchecked. If not, this method throws. // If the element is detached from the DOM at any moment during the action, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. @@ -2944,15 +2923,24 @@ type LocatorAssertions interface { // Every `page` object has its own Mouse, accessible with [Page.Mouse]. type Mouse interface { // Shortcut for [Mouse.Move], [Mouse.Down], [Mouse.Up]. + // + // 1. x: X coordinate relative to the main frame's viewport in CSS pixels. + // 2. y: Y coordinate relative to the main frame's viewport in CSS pixels. Click(x float64, y float64, options ...MouseClickOptions) error // Shortcut for [Mouse.Move], [Mouse.Down], [Mouse.Up], [Mouse.Down] and [Mouse.Up]. + // + // 1. x: X coordinate relative to the main frame's viewport in CSS pixels. + // 2. y: Y coordinate relative to the main frame's viewport in CSS pixels. Dblclick(x float64, y float64, options ...MouseDblclickOptions) error // Dispatches a `mousedown` event. Down(options ...MouseDownOptions) error // Dispatches a `mousemove` event. + // + // 1. x: X coordinate relative to the main frame's viewport in CSS pixels. + // 2. y: Y coordinate relative to the main frame's viewport in CSS pixels. Move(x float64, y float64, options ...MouseMoveOptions) error // Dispatches a `mouseup` event. @@ -2970,8 +2958,7 @@ type Mouse interface { Wheel(deltaX float64, deltaY float64) error } -// Page provides methods to interact with a single tab in a [Browser], or an -// +// Page provides methods to interact with a single tab in a [Browser], or an // [extension background page] in Chromium. One [Browser] // instance might have multiple [Page] instances. // This example creates a page, navigates it to a URL, and then saves a screenshot: @@ -3107,8 +3094,7 @@ type Page interface { // the element is detached during the checks, the whole action is retried. // 4. Scroll the element into view if needed. // 5. Use [Page.Mouse] to click in the center of the element. - // 6. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 7. Ensure that the element is now checked. If not, this method throws. + // 6. 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 [TimeoutError]. // Passing zero timeout disables this. // @@ -3159,8 +3145,6 @@ type Page interface { // the element is detached during the checks, the whole action is retried. // 3. Scroll the element into view if needed. // 4. Use [Page.Mouse] to double click in the center of the element, or the specified “position”. - // 5. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. Note that if - // the first click of the `dblclick()` triggers a navigation event, this method will throw. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // **NOTE** `page.dblclick()` dispatches two `click` events and a single `dblclick` event. @@ -3405,12 +3389,12 @@ type Page interface { GetByTitle(text interface{}, options ...PageGetByTitleOptions) Locator // Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of - // the last redirect. If can not go back, returns `null`. + // the last redirect. If cannot go back, returns `null`. // Navigate to the previous page in history. GoBack(options ...PageGoBackOptions) (Response, error) // Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of - // the last redirect. If can not go forward, returns `null`. + // the last redirect. If cannot go forward, returns `null`. // Navigate to the next page in history. GoForward(options ...PageGoForwardOptions) (Response, error) @@ -3443,7 +3427,6 @@ type Page interface { // the element is detached during the checks, the whole action is retried. // 3. Scroll the element into view if needed. // 4. Use [Page.Mouse] to hover over the center of the element, or the specified “position”. - // 5. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // @@ -3756,8 +3739,7 @@ type Page interface { // the element is detached during the checks, the whole action is retried. // 5. Scroll the element into view if needed. // 6. Use [Page.Mouse] to click in the center of the element. - // 7. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 8. Ensure that the element is now checked or unchecked. If not, this method throws. + // 7. Ensure that the element is now checked or unchecked. If not, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // @@ -3836,7 +3818,6 @@ type Page interface { // the element is detached during the checks, the whole action is retried. // 3. Scroll the element into view if needed. // 4. Use [Page.Touchscreen] to tap the center of the element, or the specified “position”. - // 5. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // **NOTE** [Page.Tap] the method will throw if “hasTouch” option of the browser context is false. @@ -3884,8 +3865,7 @@ type Page interface { // the element is detached during the checks, the whole action is retried. // 4. Scroll the element into view if needed. // 5. Use [Page.Mouse] to click in the center of the element. - // 6. Wait for initiated navigations to either succeed or fail, unless “noWaitAfter” option is set. - // 7. Ensure that the element is now unchecked. If not, this method throws. + // 6. Ensure that the element is now unchecked. If not, this method throws. // When all steps combined have not finished during the specified “timeout”, this method throws a [TimeoutError]. // Passing zero timeout disables this. // @@ -4128,7 +4108,7 @@ type Request interface { // are NOT lower-cased. Headers with multiple entries, such as `Set-Cookie`, appear in the array multiple times. HeadersArray() ([]NameValue, error) - // Returns the value of the header matching the name. The name is case insensitive. + // Returns the value of the header matching the name. The name is case-insensitive. // // name: Name of the header. HeaderValue(name string) (string, error) @@ -4212,14 +4192,14 @@ type Response interface { // names are NOT lower-cased. Headers with multiple entries, such as `Set-Cookie`, appear in the array multiple times. HeadersArray() ([]NameValue, error) - // Returns the value of the header matching the name. The name is case insensitive. If multiple headers have the same + // Returns the value of the header matching the name. The name is case-insensitive. If multiple headers have the same // name (except `set-cookie`), they are returned as a list separated by `, `. For `set-cookie`, the `\n` separator is // used. If no headers are found, `null` is returned. // // name: Name of the header. HeaderValue(name string) (string, error) - // Returns all values of the headers matching the name, for example `set-cookie`. The name is case insensitive. + // Returns all values of the headers matching the name, for example `set-cookie`. The name is case-insensitive. // // name: Name of the header. HeaderValues(name string) ([]string, error) @@ -4262,19 +4242,19 @@ type Route interface { // Aborts the route's request. Abort(errorCode ...string) error - // Continues route's request with optional overrides. + // Sends route's request to the network with optional overrides. // // # Details // // Note that any overrides such as “url” or “headers” only apply to the request being routed. If this request results // in a redirect, overrides will not be applied to the new redirected request. If you want to propagate a header // through redirects, use the combination of [Route.Fetch] and [Route.Fulfill] instead. + // [Route.Continue] will immediately send the request to the network, other matching handlers won't be invoked. Use + // [Route.Fallback] If you want next matching handler in the chain to be invoked. Continue(options ...RouteContinueOptions) error - // When several routes match the given pattern, they run in the order opposite to their registration. That way the - // last registered route can always override all the previous ones. In the example below, request will be handled by - // the bottom-most handler first, then it'll fall back to the previous one and in the end will be aborted by the first - // registered route. + // Continues route's request with optional overrides. The method is similar to [Route.Continue] with the difference + // that other matching handlers will be invoked before sending the request. Fallback(options ...RouteFallbackOptions) error // Performs the request and fetches result without fulfilling it, so that the response could be modified and then @@ -4316,6 +4296,9 @@ type Selectors interface { type Touchscreen interface { // Dispatches a `touchstart` and `touchend` event with a single touch at the position (“x”,“y”). // **NOTE** [Page.Tap] the method will throw if “hasTouch” option of the browser context is false. + // + // 1. x: X coordinate relative to the main frame's viewport in CSS pixels. + // 2. y: Y coordinate relative to the main frame's viewport in CSS pixels. Tap(x int, y int) error } diff --git a/generated-structs.go b/generated-structs.go index ce467ba4..bd912ea4 100644 --- a/generated-structs.go +++ b/generated-structs.go @@ -12,6 +12,18 @@ type APIRequestNewContextOptions struct { // // [`URL()`]: https://developer.mozilla.org/en-US/docs/Web/API/URL/URL BaseURL *string `json:"baseURL"` + // TLS Client Authentication allows the server to request a client certificate and verify it. + // + // # Details + // + // An array of client certificates to be used. Each certificate object must have either both `certPath` and `keyPath`, + // a single `pfxPath`, or their corresponding direct value equivalents (`cert` and `key`, or `pfx`). Optionally, + // `passphrase` property should be provided if the certificate is encrypted. The `origin` property should be provided + // with an exact match to the request origin that the certificate is valid for. + // **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. + // **NOTE** When using WebKit on macOS, accessing `localhost` will not pick up client certificates. You can make it + // work by replacing `localhost` with `local.playwright`. + ClientCertificates []ClientCertificate `json:"clientCertificates"` // An object containing additional HTTP headers to be sent with every request. Defaults to none. ExtraHttpHeaders map[string]string `json:"extraHTTPHeaders"` // Credentials for [HTTP authentication]. If no @@ -57,6 +69,9 @@ type APIRequestContextDeleteOptions struct { // Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is // exceeded. Defaults to `20`. Pass `0` to not follow redirects. MaxRedirects *int `json:"maxRedirects"` + // Maximum number of times network errors should be retried. Currently only `ECONNRESET` error is retried. Does not + // retry based on HTTP response codes. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. + MaxRetries *int `json:"maxRetries"` // Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this // request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless // explicitly provided. File values can be passed either as @@ -94,6 +109,9 @@ type APIRequestContextFetchOptions struct { // Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is // exceeded. Defaults to `20`. Pass `0` to not follow redirects. MaxRedirects *int `json:"maxRedirects"` + // Maximum number of times network errors should be retried. Currently only `ECONNRESET` error is retried. Does not + // retry based on HTTP response codes. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. + MaxRetries *int `json:"maxRetries"` // If set changes the fetch method (e.g. [PUT] or // [POST]. If not specified, GET method is used. // @@ -133,6 +151,9 @@ type APIRequestContextGetOptions struct { // Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is // exceeded. Defaults to `20`. Pass `0` to not follow redirects. MaxRedirects *int `json:"maxRedirects"` + // Maximum number of times network errors should be retried. Currently only `ECONNRESET` error is retried. Does not + // retry based on HTTP response codes. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. + MaxRetries *int `json:"maxRetries"` // Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this // request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless // explicitly provided. File values can be passed either as @@ -166,6 +187,9 @@ type APIRequestContextHeadOptions struct { // Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is // exceeded. Defaults to `20`. Pass `0` to not follow redirects. MaxRedirects *int `json:"maxRedirects"` + // Maximum number of times network errors should be retried. Currently only `ECONNRESET` error is retried. Does not + // retry based on HTTP response codes. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. + MaxRetries *int `json:"maxRetries"` // Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this // request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless // explicitly provided. File values can be passed either as @@ -199,6 +223,9 @@ type APIRequestContextPatchOptions struct { // Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is // exceeded. Defaults to `20`. Pass `0` to not follow redirects. MaxRedirects *int `json:"maxRedirects"` + // Maximum number of times network errors should be retried. Currently only `ECONNRESET` error is retried. Does not + // retry based on HTTP response codes. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. + MaxRetries *int `json:"maxRetries"` // Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this // request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless // explicitly provided. File values can be passed either as @@ -232,6 +259,9 @@ type APIRequestContextPostOptions struct { // Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is // exceeded. Defaults to `20`. Pass `0` to not follow redirects. MaxRedirects *int `json:"maxRedirects"` + // Maximum number of times network errors should be retried. Currently only `ECONNRESET` error is retried. Does not + // retry based on HTTP response codes. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. + MaxRetries *int `json:"maxRetries"` // Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this // request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless // explicitly provided. File values can be passed either as @@ -265,6 +295,9 @@ type APIRequestContextPutOptions struct { // Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is // exceeded. Defaults to `20`. Pass `0` to not follow redirects. MaxRedirects *int `json:"maxRedirects"` + // Maximum number of times network errors should be retried. Currently only `ECONNRESET` error is retried. Does not + // retry based on HTTP response codes. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. + MaxRetries *int `json:"maxRetries"` // Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this // request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless // explicitly provided. File values can be passed either as @@ -308,6 +341,18 @@ type BrowserNewContextOptions struct { BaseURL *string `json:"baseURL"` // Toggles bypassing page's Content-Security-Policy. Defaults to `false`. BypassCSP *bool `json:"bypassCSP"` + // TLS Client Authentication allows the server to request a client certificate and verify it. + // + // # Details + // + // An array of client certificates to be used. Each certificate object must have either both `certPath` and `keyPath`, + // a single `pfxPath`, or their corresponding direct value equivalents (`cert` and `key`, or `pfx`). Optionally, + // `passphrase` property should be provided if the certificate is encrypted. The `origin` property should be provided + // with an exact match to the request origin that the certificate is valid for. + // **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. + // **NOTE** When using WebKit on macOS, accessing `localhost` will not pick up client certificates. You can make it + // work by replacing `localhost` with `local.playwright`. + ClientCertificates []ClientCertificate `json:"clientCertificates"` // Emulates `prefers-colors-scheme` media feature, supported values are `light`, `dark`, `no-preference`. See // [Page.EmulateMedia] for more details. Passing `no-override` resets emulation to system defaults. Defaults to // `light`. @@ -363,9 +408,6 @@ type BrowserNewContextOptions struct { // details. Defaults to none. Permissions []string `json:"permissions"` // Network proxy settings to use with this context. Defaults to none. - // **NOTE** For Chromium on Windows the browser needs to be launched with the global proxy for this option to work. If - // all contexts override the proxy, global proxy will be never used and can be any string, for example `launch({ - // proxy: { server: 'http://per-context' } })`. Proxy *Proxy `json:"proxy"` // 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 and all of these files are archived along with the @@ -399,8 +441,13 @@ type BrowserNewContextOptions struct { // - `block`: Playwright will block all registration of Service Workers. // // [Service Workers]: https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API - ServiceWorkers *ServiceWorkerPolicy `json:"serviceWorkers"` - StorageState *OptionalStorageState `json:"storageState"` + ServiceWorkers *ServiceWorkerPolicy `json:"serviceWorkers"` + // Learn more about [storage state and auth]. + // Populates context with given storage state. This option can be used to initialize context with logged-in + // information obtained via [BrowserContext.StorageState]. + // + // [storage state and auth]: https://playwright.dev/docs/auth + StorageState *OptionalStorageState `json:"storageState"` // Populates context with given storage state. This option can be used to initialize context with logged-in // information obtained via [BrowserContext.StorageState]. Path to the file with saved storage state. StorageStatePath *string `json:"storageStatePath"` @@ -439,6 +486,18 @@ type BrowserNewPageOptions struct { BaseURL *string `json:"baseURL"` // Toggles bypassing page's Content-Security-Policy. Defaults to `false`. BypassCSP *bool `json:"bypassCSP"` + // TLS Client Authentication allows the server to request a client certificate and verify it. + // + // # Details + // + // An array of client certificates to be used. Each certificate object must have either both `certPath` and `keyPath`, + // a single `pfxPath`, or their corresponding direct value equivalents (`cert` and `key`, or `pfx`). Optionally, + // `passphrase` property should be provided if the certificate is encrypted. The `origin` property should be provided + // with an exact match to the request origin that the certificate is valid for. + // **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. + // **NOTE** When using WebKit on macOS, accessing `localhost` will not pick up client certificates. You can make it + // work by replacing `localhost` with `local.playwright`. + ClientCertificates []ClientCertificate `json:"clientCertificates"` // Emulates `prefers-colors-scheme` media feature, supported values are `light`, `dark`, `no-preference`. See // [Page.EmulateMedia] for more details. Passing `no-override` resets emulation to system defaults. Defaults to // `light`. @@ -494,9 +553,6 @@ type BrowserNewPageOptions struct { // details. Defaults to none. Permissions []string `json:"permissions"` // Network proxy settings to use with this context. Defaults to none. - // **NOTE** For Chromium on Windows the browser needs to be launched with the global proxy for this option to work. If - // all contexts override the proxy, global proxy will be never used and can be any string, for example `launch({ - // proxy: { server: 'http://per-context' } })`. Proxy *Proxy `json:"proxy"` // 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 and all of these files are archived along with the @@ -530,8 +586,13 @@ type BrowserNewPageOptions struct { // - `block`: Playwright will block all registration of Service Workers. // // [Service Workers]: https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API - ServiceWorkers *ServiceWorkerPolicy `json:"serviceWorkers"` - StorageState *OptionalStorageState `json:"storageState"` + ServiceWorkers *ServiceWorkerPolicy `json:"serviceWorkers"` + // Learn more about [storage state and auth]. + // Populates context with given storage state. This option can be used to initialize context with logged-in + // information obtained via [BrowserContext.StorageState]. + // + // [storage state and auth]: https://playwright.dev/docs/auth + StorageState *OptionalStorageState `json:"storageState"` // Populates context with given storage state. This option can be used to initialize context with logged-in // information obtained via [BrowserContext.StorageState]. Path to the file with saved storage state. StorageStatePath *string `json:"storageStatePath"` @@ -567,11 +628,12 @@ type BrowserStartTracingOptions struct { type OptionalCookie struct { Name string `json:"name"` Value string `json:"value"` - // either url or domain / path are required. Optional. + // Either url or domain / path are required. Optional. URL *string `json:"url"` - // either url or domain / path are required Optional. + // For the cookie to apply to all subdomains as well, prefix domain with a dot, like this: ".example.com". Either url + // or domain / path are required. Optional. Domain *string `json:"domain"` - // either url or domain / path are required Optional. + // Either url or domain / path are required Optional. Path *string `json:"path"` // Unix time in seconds. Optional. Expires *float64 `json:"expires"` @@ -809,6 +871,18 @@ type BrowserTypeLaunchPersistentContextOptions struct { Channel *string `json:"channel"` // Enable Chromium sandboxing. Defaults to `false`. ChromiumSandbox *bool `json:"chromiumSandbox"` + // TLS Client Authentication allows the server to request a client certificate and verify it. + // + // # Details + // + // An array of client certificates to be used. Each certificate object must have either both `certPath` and `keyPath`, + // a single `pfxPath`, or their corresponding direct value equivalents (`cert` and `key`, or `pfx`). Optionally, + // `passphrase` property should be provided if the certificate is encrypted. The `origin` property should be provided + // with an exact match to the request origin that the certificate is valid for. + // **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. + // **NOTE** When using WebKit on macOS, accessing `localhost` will not pick up client certificates. You can make it + // work by replacing `localhost` with `local.playwright`. + ClientCertificates []ClientCertificate `json:"clientCertificates"` // Emulates `prefers-colors-scheme` media feature, supported values are `light`, `dark`, `no-preference`. See // [Page.EmulateMedia] for more details. Passing `no-override` resets emulation to system defaults. Defaults to // `light`. @@ -994,9 +1068,9 @@ type ElementHandleCheckOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1028,6 +1102,8 @@ type ElementHandleClickOptions struct { // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as // navigating to inaccessible pages. Defaults to `false`. + // + // Deprecated: This option will default to `true` in the future. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1054,9 +1130,9 @@ type ElementHandleDblclickOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1075,9 +1151,9 @@ type ElementHandleFillOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -1092,9 +1168,9 @@ type ElementHandleHoverOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1119,6 +1195,8 @@ type ElementHandlePressOptions struct { // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as // navigating to inaccessible pages. Defaults to `false`. + // + // Deprecated: This option will default to `true` in the future. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -1176,9 +1254,9 @@ type ElementHandleSelectOptionOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -1198,9 +1276,9 @@ type ElementHandleSetCheckedOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1215,9 +1293,9 @@ type ElementHandleSetCheckedOptions struct { Trial *bool `json:"trial"` } type ElementHandleSetInputFilesOptions struct { - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -1232,9 +1310,9 @@ type ElementHandleTapOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1251,9 +1329,9 @@ type ElementHandleTapOptions struct { type ElementHandleTypeOptions struct { // Time to wait between key presses in milliseconds. Defaults to 0. Delay *float64 `json:"delay"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -1264,9 +1342,9 @@ type ElementHandleUncheckOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1302,9 +1380,9 @@ type ElementHandleWaitForSelectorOptions struct { Timeout *float64 `json:"timeout"` } type FileChooserSetFilesOptions struct { - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -1316,7 +1394,7 @@ type FrameAddScriptTagOptions struct { // Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative // to the current working directory. Path *string `json:"path"` - // Script type. Use 'module' in order to load a Javascript ES6 module. See + // Script type. Use 'module' in order to load a JavaScript ES6 module. See // [script] for more details. // // [script]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script @@ -1338,9 +1416,9 @@ type FrameCheckOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1375,6 +1453,8 @@ type FrameClickOptions struct { // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as // navigating to inaccessible pages. Defaults to `false`. + // + // Deprecated: This option will default to `true` in the future. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1404,9 +1484,9 @@ type FrameDblclickOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1436,9 +1516,9 @@ type FrameDragAndDropOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not // specified, some visible point of the element is used. @@ -1468,9 +1548,9 @@ type FrameFillOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // When true, the call requires selector to resolve to a single element. If given selector resolves to more than one // element, the call throws an exception. @@ -1597,9 +1677,9 @@ type FrameHoverOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1715,6 +1795,8 @@ type FramePressOptions struct { // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as // navigating to inaccessible pages. Defaults to `false`. + // + // Deprecated: This option will default to `true` in the future. NoWaitAfter *bool `json:"noWaitAfter"` // When true, the call requires selector to resolve to a single element. If given selector resolves to more than one // element, the call throws an exception. @@ -1733,9 +1815,9 @@ type FrameSelectOptionOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // When true, the call requires selector to resolve to a single element. If given selector resolves to more than one // element, the call throws an exception. @@ -1749,9 +1831,9 @@ type FrameSetCheckedOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1783,9 +1865,9 @@ type FrameSetContentOptions struct { WaitUntil *WaitUntilState `json:"waitUntil"` } type FrameSetInputFilesOptions struct { - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // When true, the call requires selector to resolve to a single element. If given selector resolves to more than one // element, the call throws an exception. @@ -1803,9 +1885,9 @@ type FrameTapOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -1833,9 +1915,9 @@ type FrameTextContentOptions struct { type FrameTypeOptions struct { // Time to wait between key presses in milliseconds. Defaults to 0. Delay *float64 `json:"delay"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // When true, the call requires selector to resolve to a single element. If given selector resolves to more than one // element, the call throws an exception. @@ -1849,9 +1931,9 @@ type FrameUncheckOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -2058,9 +2140,9 @@ type LocatorCheckOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -2079,9 +2161,9 @@ type LocatorClearOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -2105,6 +2187,8 @@ type LocatorClickOptions struct { // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as // navigating to inaccessible pages. Defaults to `false`. + // + // Deprecated: This option will default to `true` in the future. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -2131,9 +2215,9 @@ type LocatorDblclickOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -2157,9 +2241,9 @@ type LocatorDragToOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not // specified, some visible point of the element is used. @@ -2196,9 +2280,9 @@ type LocatorFillOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -2320,9 +2404,9 @@ type LocatorHoverOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -2408,6 +2492,8 @@ type LocatorPressOptions struct { // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as // navigating to inaccessible pages. Defaults to `false`. + // + // Deprecated: This option will default to `true` in the future. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -2416,9 +2502,9 @@ type LocatorPressOptions struct { type LocatorPressSequentiallyOptions struct { // Time to wait between key presses in milliseconds. Defaults to 0. Delay *float64 `json:"delay"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -2476,9 +2562,9 @@ type LocatorSelectOptionOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -2498,9 +2584,9 @@ type LocatorSetCheckedOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -2515,9 +2601,9 @@ type LocatorSetCheckedOptions struct { Trial *bool `json:"trial"` } type LocatorSetInputFilesOptions struct { - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -2532,9 +2618,9 @@ type LocatorTapOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -2556,9 +2642,9 @@ type LocatorTextContentOptions struct { type LocatorTypeOptions struct { // Time to wait between key presses in milliseconds. Defaults to 0. Delay *float64 `json:"delay"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can // be changed by using the [BrowserContext.SetDefaultTimeout] or [Page.SetDefaultTimeout] methods. @@ -2569,9 +2655,9 @@ type LocatorUncheckOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -2753,7 +2839,7 @@ type PageAddScriptTagOptions struct { // Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative // to the current working directory. Path *string `json:"path"` - // Script type. Use 'module' in order to load a Javascript ES6 module. See + // Script type. Use 'module' in order to load a JavaScript ES6 module. See // [script] for more details. // // [script]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script @@ -2775,9 +2861,9 @@ type PageCheckOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -2812,6 +2898,8 @@ type PageClickOptions struct { // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as // navigating to inaccessible pages. Defaults to `false`. + // + // Deprecated: This option will default to `true` in the future. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -2850,9 +2938,9 @@ type PageDblclickOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -2882,9 +2970,9 @@ type PageDragAndDropOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not // specified, some visible point of the element is used. @@ -2926,9 +3014,9 @@ type PageFillOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // When true, the call requires selector to resolve to a single element. If given selector resolves to more than one // element, the call throws an exception. @@ -3089,9 +3177,9 @@ type PageHoverOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -3247,6 +3335,8 @@ type PagePressOptions struct { // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as // navigating to inaccessible pages. Defaults to `false`. + // + // Deprecated: This option will default to `true` in the future. NoWaitAfter *bool `json:"noWaitAfter"` // When true, the call requires selector to resolve to a single element. If given selector resolves to more than one // element, the call throws an exception. @@ -3294,7 +3384,8 @@ type PageRouteFromHAROptions struct { // separate files or entries in the ZIP archive. If `embed` is specified, content is stored inline the HAR file. UpdateContent *RouteFromHarUpdateContentPolicy `json:"updateContent"` // 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`. + // cookies, security and other types of HAR information that are not used when replaying from HAR. Defaults to + // `minimal`. UpdateMode *HarMode `json:"updateMode"` // A glob pattern, regular expression or predicate to match the request URL. Only requests with URL matching the // pattern will be served from the HAR file. If not specified, all requests are served from the HAR file. @@ -3352,9 +3443,9 @@ type PageSelectOptionOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // When true, the call requires selector to resolve to a single element. If given selector resolves to more than one // element, the call throws an exception. @@ -3368,9 +3459,9 @@ type PageSetCheckedOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -3402,9 +3493,9 @@ type PageSetContentOptions struct { WaitUntil *WaitUntilState `json:"waitUntil"` } type PageSetInputFilesOptions struct { - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // When true, the call requires selector to resolve to a single element. If given selector resolves to more than one // element, the call throws an exception. @@ -3422,9 +3513,9 @@ type PageTapOptions struct { // current modifiers back. If not specified, currently pressed modifiers are used. "ControlOrMeta" resolves to // "Control" on Windows and Linux and to "Meta" on macOS. Modifiers []KeyboardModifier `json:"modifiers"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -3452,9 +3543,9 @@ type PageTextContentOptions struct { type PageTypeOptions struct { // Time to wait between key presses in milliseconds. Defaults to 0. Delay *float64 `json:"delay"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // When true, the call requires selector to resolve to a single element. If given selector resolves to more than one // element, the call throws an exception. @@ -3468,9 +3559,9 @@ type PageUncheckOptions struct { // // [actionability]: https://playwright.dev/docs/actionability Force *bool `json:"force"` - // Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You - // can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as - // navigating to inaccessible pages. Defaults to `false`. + // This option has no effect. + // + // Deprecated: This option has no effect. NoWaitAfter *bool `json:"noWaitAfter"` // A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of // the element. @@ -3743,6 +3834,9 @@ type RouteFetchOptions struct { // Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is // exceeded. Defaults to `20`. Pass `0` to not follow redirects. MaxRedirects *int `json:"maxRedirects"` + // Maximum number of times network errors should be retried. Currently only `ECONNRESET` error is retried. Does not + // retry based on HTTP response codes. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. + MaxRetries *int `json:"maxRetries"` // If set changes the request method (e.g. GET or POST). Method *string `json:"method"` // If set changes the post data of request. @@ -3812,6 +3906,24 @@ type WebSocketWaitForEventOptions struct { // default value can be changed by using the [BrowserContext.SetDefaultTimeout]. Timeout *float64 `json:"timeout"` } +type ClientCertificate struct { + // Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port. + Origin string `json:"origin"` + // Path to the file with the certificate in PEM format. + CertPath *string `json:"certPath"` + // Direct value of the certificate in PEM format. + Cert []byte `json:"cert"` + // Path to the file with the private key in PEM format. + KeyPath *string `json:"keyPath"` + // Direct value of the private key in PEM format. + Key []byte `json:"key"` + // Path to the PFX or PKCS12 encoded private key and certificate chain. + PfxPath *string `json:"pfxPath"` + // Direct value of the PFX or PKCS12 encoded private key and certificate chain. + Pfx []byte `json:"pfx"` + // Passphrase for the private key (PEM or PFX). + Passphrase *string `json:"passphrase"` +} type HttpCredentials struct { Username string `json:"username"` Password string `json:"password"` diff --git a/js_handle.go b/js_handle.go index 7b667a5f..58ed33bf 100644 --- a/js_handle.go +++ b/js_handle.go @@ -172,6 +172,14 @@ func parseValue(result interface{}, refs map[float64]interface{}) interface{} { } return out } + + if v, ok := vMap["e"]; ok { + return parseError(Error{ + Name: v.(map[string]interface{})["n"].(string), + Message: v.(map[string]interface{})["m"].(string), + Stack: v.(map[string]interface{})["s"].(string), + }) + } panic(fmt.Errorf("Unexpected value: %v", vMap)) } @@ -196,6 +204,26 @@ func serializeValue(value interface{}, handles *[]*channel, depth int) interface } } + if err, ok := value.(error); ok { + var e *Error + if errors.As(err, &e) { + return map[string]interface{}{ + "e": map[string]interface{}{ + "n": e.Name, + "m": e.Message, + "s": e.Stack, + }, + } + } + return map[string]interface{}{ + "e": map[string]interface{}{ + "n": "", + "m": err.Error(), + "s": "", + }, + } + } + if depth > 100 { panic(errors.New("Maximum argument depth exceeded")) } diff --git a/locator.go b/locator.go index 4ed8005c..a31e70f9 100644 --- a/locator.go +++ b/locator.go @@ -170,9 +170,8 @@ func (l *locatorImpl) Clear(options ...LocatorClearOptions) error { } if len(options) == 1 { return l.Fill("", LocatorFillOptions{ - Force: options[0].Force, - NoWaitAfter: options[0].NoWaitAfter, - Timeout: options[0].Timeout, + Force: options[0].Force, + Timeout: options[0].Timeout, }) } else { return l.Fill("") diff --git a/patches/main.patch b/patches/main.patch index 807930e7..4bbd90f1 100644 --- a/patches/main.patch +++ b/patches/main.patch @@ -1,8 +1,8 @@ diff --git a/docs/src/api/class-apirequest.md b/docs/src/api/class-apirequest.md -index 164de27b2..a19100289 100644 +index 2f832e1dd..b8a33f161 100644 --- a/docs/src/api/class-apirequest.md +++ b/docs/src/api/class-apirequest.md -@@ -45,7 +45,7 @@ Methods like [`method: APIRequestContext.get`] take the base URL into considerat +@@ -48,7 +48,7 @@ Methods like [`method: APIRequestContext.get`] take the base URL into considerat ### option: APIRequest.newContext.storageState * since: v1.16 @@ -12,10 +12,10 @@ index 164de27b2..a19100289 100644 - `cookies` <[Array]<[Object]>> - `name` <[string]> diff --git a/docs/src/api/class-apirequestcontext.md b/docs/src/api/class-apirequestcontext.md -index 7101d1996..3179c7297 100644 +index a6333d6b0..9a37f42aa 100644 --- a/docs/src/api/class-apirequestcontext.md +++ b/docs/src/api/class-apirequestcontext.md -@@ -153,12 +153,18 @@ context cookies from the response. The method will automatically follow redirect +@@ -156,12 +156,18 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.delete.data = %%-js-python-csharp-fetch-option-data-%% * since: v1.17 @@ -34,7 +34,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.delete.multipart = %%-js-fetch-option-multipart-%% * since: v1.17 -@@ -168,6 +174,9 @@ context cookies from the response. The method will automatically follow redirect +@@ -171,6 +177,9 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.delete.multipart = %%-csharp-fetch-option-multipart-%% * since: v1.17 @@ -44,7 +44,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.delete.timeout = %%-js-python-csharp-fetch-option-timeout-%% * since: v1.16 -@@ -305,7 +314,7 @@ Target URL or Request to get all parameters from. +@@ -314,7 +323,7 @@ Target URL or Request to get all parameters from. ### option: APIRequestContext.fetch.method * since: v1.16 @@ -53,7 +53,7 @@ index 7101d1996..3179c7297 100644 - `method` <[string]> If set changes the fetch method (e.g. [PUT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT) or -@@ -317,12 +326,18 @@ If set changes the fetch method (e.g. [PUT](https://developer.mozilla.org/en-US/ +@@ -326,12 +335,18 @@ If set changes the fetch method (e.g. [PUT](https://developer.mozilla.org/en-US/ ### option: APIRequestContext.fetch.data = %%-js-python-csharp-fetch-option-data-%% * since: v1.16 @@ -72,7 +72,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.fetch.multipart = %%-js-fetch-option-multipart-%% * since: v1.16 -@@ -332,6 +347,9 @@ If set changes the fetch method (e.g. [PUT](https://developer.mozilla.org/en-US/ +@@ -341,6 +356,9 @@ If set changes the fetch method (e.g. [PUT](https://developer.mozilla.org/en-US/ ### option: APIRequestContext.fetch.multipart = %%-csharp-fetch-option-multipart-%% * since: v1.16 @@ -82,7 +82,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.fetch.timeout = %%-js-python-csharp-fetch-option-timeout-%% * since: v1.16 -@@ -406,12 +424,18 @@ await request.GetAsync("https://example.com/api/getText", new() { Params = query +@@ -433,12 +451,18 @@ await request.GetAsync("https://example.com/api/getText", new() { Params = query ### option: APIRequestContext.get.data = %%-js-python-csharp-fetch-option-data-%% * since: v1.26 @@ -101,7 +101,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.get.multipart = %%-js-fetch-option-multipart-%% * since: v1.26 -@@ -421,6 +445,9 @@ await request.GetAsync("https://example.com/api/getText", new() { Params = query +@@ -448,6 +472,9 @@ await request.GetAsync("https://example.com/api/getText", new() { Params = query ### option: APIRequestContext.get.multipart = %%-csharp-fetch-option-multipart-%% * since: v1.26 @@ -111,7 +111,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.get.timeout = %%-js-python-csharp-fetch-option-timeout-%% * since: v1.16 -@@ -459,12 +486,18 @@ context cookies from the response. The method will automatically follow redirect +@@ -492,12 +519,18 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.head.data = %%-js-python-csharp-fetch-option-data-%% * since: v1.26 @@ -130,7 +130,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.head.multipart = %%-js-fetch-option-multipart-%% * since: v1.26 -@@ -474,6 +507,9 @@ context cookies from the response. The method will automatically follow redirect +@@ -507,6 +540,9 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.head.multipart = %%-csharp-fetch-option-multipart-%% * since: v1.26 @@ -140,7 +140,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.head.timeout = %%-js-python-csharp-fetch-option-timeout-%% * since: v1.16 -@@ -512,12 +548,18 @@ context cookies from the response. The method will automatically follow redirect +@@ -551,12 +587,18 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.patch.data = %%-js-python-csharp-fetch-option-data-%% * since: v1.16 @@ -159,7 +159,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.patch.multipart = %%-js-fetch-option-multipart-%% * since: v1.16 -@@ -527,6 +569,9 @@ context cookies from the response. The method will automatically follow redirect +@@ -566,6 +608,9 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.patch.multipart = %%-csharp-fetch-option-multipart-%% * since: v1.16 @@ -169,7 +169,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.patch.timeout = %%-js-python-csharp-fetch-option-timeout-%% * since: v1.16 -@@ -686,12 +731,18 @@ await request.PostAsync("https://example.com/api/uploadScript", new() { Multipar +@@ -731,12 +776,18 @@ await request.PostAsync("https://example.com/api/uploadScript", new() { Multipar ### option: APIRequestContext.post.data = %%-js-python-csharp-fetch-option-data-%% * since: v1.16 @@ -188,7 +188,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.post.multipart = %%-js-fetch-option-multipart-%% * since: v1.16 -@@ -701,6 +752,9 @@ await request.PostAsync("https://example.com/api/uploadScript", new() { Multipar +@@ -746,6 +797,9 @@ await request.PostAsync("https://example.com/api/uploadScript", new() { Multipar ### option: APIRequestContext.post.multipart = %%-csharp-fetch-option-multipart-%% * since: v1.16 @@ -198,7 +198,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.post.timeout = %%-js-python-csharp-fetch-option-timeout-%% * since: v1.16 -@@ -739,12 +793,18 @@ context cookies from the response. The method will automatically follow redirect +@@ -790,12 +844,18 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.put.data = %%-js-python-csharp-fetch-option-data-%% * since: v1.16 @@ -217,7 +217,7 @@ index 7101d1996..3179c7297 100644 ### option: APIRequestContext.put.multipart = %%-js-fetch-option-multipart-%% * since: v1.16 -@@ -754,6 +814,9 @@ context cookies from the response. The method will automatically follow redirect +@@ -805,6 +865,9 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.put.multipart = %%-csharp-fetch-option-multipart-%% * since: v1.16 @@ -228,7 +228,7 @@ index 7101d1996..3179c7297 100644 * since: v1.16 diff --git a/docs/src/api/class-apiresponse.md b/docs/src/api/class-apiresponse.md -index 1297d2d4f..6ecc65ae7 100644 +index 5a901b76b..26da2aa12 100644 --- a/docs/src/api/class-apiresponse.md +++ b/docs/src/api/class-apiresponse.md @@ -65,7 +65,7 @@ Headers with multiple entries, such as `Set-Cookie`, appear in the array multipl @@ -254,64 +254,30 @@ index 6fce864d0..237865884 100644 Makes the assertion check for the opposite condition. For example, this code tests that the response status is not successful: diff --git a/docs/src/api/class-browser.md b/docs/src/api/class-browser.md -index abbf4fd96..ad6ef3629 100644 +index 59cf4c99c..95f686ffa 100644 --- a/docs/src/api/class-browser.md +++ b/docs/src/api/class-browser.md -@@ -256,8 +256,25 @@ await browser.CloseAsync(); - ### option: Browser.newContext.proxy = %%-context-option-proxy-%% +@@ -261,6 +261,9 @@ await browser.CloseAsync(); + ### option: Browser.newContext.storageState = %%-js-python-context-option-storage-state-%% * since: v1.8 --### option: Browser.newContext.storageState = %%-js-python-context-option-storage-state-%% -+### option: Browser.newContext.storageState - * since: v1.8 -+* langs: js, python, go -+- `storageState` <[path]|[Object]> -+ - `cookies` <[Array]<[Object]>> Cookies to set for context -+ - `name` <[string]> -+ - `value` <[string]> -+ - `url` ?<[string]> either url or domain / path are required. Optional. -+ - `domain` ?<[string]> either url or domain / path are required Optional. -+ - `path` ?<[string]> either url or domain / path are required Optional. -+ - `expires` ?<[float]> Unix time in seconds. Optional. -+ - `httpOnly` ?<[boolean]> Optional. -+ - `secure` ?<[boolean]> Optional. -+ - `sameSite` ?<[SameSiteAttribute]<"Strict"|"Lax"|"None">> Optional. -+ - `origins` <[Array]<[Object]>> localStorage to set for context -+ - `origin` <[string]> -+ - `localStorage` <[Array]<[Object]>> -+ - `name` <[string]> -+ - `value` <[string]> - ++### option: Browser.newContext.storageState = %%-go-context-option-storage-state-%% ++* since: v1.8 ++ ### option: Browser.newContext.storageState = %%-csharp-java-context-option-storage-state-%% * since: v1.8 -@@ -281,8 +298,25 @@ testing frameworks should explicitly create [`method: Browser.newContext`] follo - ### option: Browser.newPage.proxy = %%-context-option-proxy-%% - * since: v1.8 --### option: Browser.newPage.storageState = %%-js-python-context-option-storage-state-%% -+### option: Browser.newPage.storageState +@@ -289,6 +292,9 @@ testing frameworks should explicitly create [`method: Browser.newContext`] follo + ### option: Browser.newPage.storageState = %%-js-python-context-option-storage-state-%% * since: v1.8 -+* langs: js, python, go -+- `storageState` <[path]|[Object]> -+ - `cookies` <[Array]<[Object]>> Cookies to set for context -+ - `name` <[string]> -+ - `value` <[string]> -+ - `url` ?<[string]> either url or domain / path are required. Optional. -+ - `domain` ?<[string]> either url or domain / path are required Optional. -+ - `path` ?<[string]> either url or domain / path are required Optional. -+ - `expires` ?<[float]> Unix time in seconds. Optional. -+ - `httpOnly` ?<[boolean]> Optional. -+ - `secure` ?<[boolean]> Optional. -+ - `sameSite` ?<[SameSiteAttribute]<"Strict"|"Lax"|"None">> Optional. -+ - `origins` <[Array]<[Object]>> localStorage to set for context -+ - `origin` <[string]> -+ - `localStorage` <[Array]<[Object]>> -+ - `name` <[string]> -+ - `value` <[string]> ++### option: Browser.newPage.storageState = %%-go-context-option-storage-state-%% ++* since: v1.8 ++ ### option: Browser.newPage.storageState = %%-csharp-java-context-option-storage-state-%% * since: v1.8 -@@ -292,7 +326,7 @@ testing frameworks should explicitly create [`method: Browser.newContext`] follo + +@@ -311,7 +317,7 @@ Allows to wait for async listeners to complete or to ignore subsequent errors fr ## async method: Browser.startTracing * since: v1.11 @@ -320,7 +286,7 @@ index abbf4fd96..ad6ef3629 100644 :::note This API controls [Chromium Tracing](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool) which is a low-level chromium-specific debugging tool. API to control [Playwright Tracing](../trace-viewer) could be found [here](./class-tracing). -@@ -330,10 +364,18 @@ browser.stop_tracing() +@@ -349,10 +355,18 @@ browser.stop_tracing() ### param: Browser.startTracing.page * since: v1.11 @@ -339,7 +305,7 @@ index abbf4fd96..ad6ef3629 100644 ### option: Browser.startTracing.path * since: v1.11 - `path` <[path]> -@@ -354,7 +396,7 @@ specify custom categories to use instead of default. +@@ -373,7 +387,7 @@ specify custom categories to use instead of default. ## async method: Browser.stopTracing * since: v1.11 @@ -349,10 +315,10 @@ index abbf4fd96..ad6ef3629 100644 :::note diff --git a/docs/src/api/class-browsercontext.md b/docs/src/api/class-browsercontext.md -index 686db16f4..b0dc4d4e6 100644 +index 43396f495..0f6524f39 100644 --- a/docs/src/api/class-browsercontext.md +++ b/docs/src/api/class-browsercontext.md -@@ -422,7 +422,7 @@ The order of evaluation of multiple scripts installed via [`method: BrowserConte +@@ -417,7 +417,7 @@ The order of evaluation of multiple scripts installed via [`method: BrowserConte ### param: BrowserContext.addInitScript.script * since: v1.8 @@ -361,7 +327,7 @@ index 686db16f4..b0dc4d4e6 100644 - `script` <[function]|[string]|[Object]> - `path` ?<[path]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory. Optional. -@@ -1201,7 +1201,7 @@ handler function to route the request. +@@ -1210,7 +1210,7 @@ handler function to route the request. ### param: BrowserContext.route.handler * since: v1.8 @@ -370,7 +336,7 @@ index 686db16f4..b0dc4d4e6 100644 - `handler` <[function]\([Route]\)> handler function to route the request. -@@ -1259,7 +1259,7 @@ Optional setting to control resource content management. If `attach` is specifie +@@ -1268,7 +1268,7 @@ Optional setting to control resource content management. If `attach` is specifie ## method: BrowserContext.serviceWorkers * since: v1.11 @@ -379,7 +345,7 @@ index 686db16f4..b0dc4d4e6 100644 - returns: <[Array]<[Worker]>> :::note -@@ -1446,6 +1446,13 @@ A glob pattern, regex pattern or predicate receiving [URL] used to register a ro +@@ -1455,6 +1455,13 @@ A glob pattern, regex pattern or predicate receiving [URL] used to register a ro Optional handler function used to register a routing with [`method: BrowserContext.route`]. @@ -393,7 +359,7 @@ index 686db16f4..b0dc4d4e6 100644 ### param: BrowserContext.unroute.handler * since: v1.8 * langs: csharp, java -@@ -1487,7 +1494,8 @@ Condition to wait for. +@@ -1496,7 +1503,8 @@ Condition to wait for. ## async method: BrowserContext.waitForConsoleMessage * since: v1.34 @@ -403,7 +369,7 @@ index 686db16f4..b0dc4d4e6 100644 - alias-python: expect_console_message - alias-csharp: RunAndWaitForConsoleMessage - returns: <[ConsoleMessage]> -@@ -1518,7 +1526,8 @@ Receives the [ConsoleMessage] object and resolves to truthy value when the waiti +@@ -1527,7 +1535,8 @@ Receives the [ConsoleMessage] object and resolves to truthy value when the waiti ## async method: BrowserContext.waitForEvent * since: v1.8 @@ -413,7 +379,7 @@ index 686db16f4..b0dc4d4e6 100644 - alias-python: expect_event - returns: <[any]> -@@ -1584,7 +1593,8 @@ Either a predicate that receives an event or an options object. Optional. +@@ -1593,7 +1602,8 @@ Either a predicate that receives an event or an options object. Optional. ## async method: BrowserContext.waitForPage * since: v1.9 @@ -423,7 +389,7 @@ index 686db16f4..b0dc4d4e6 100644 - alias-python: expect_page - alias-csharp: RunAndWaitForPage - returns: <[Page]> -@@ -1603,7 +1613,7 @@ Will throw an error if the context closes before new [Page] is created. +@@ -1612,7 +1622,7 @@ Will throw an error if the context closes before new [Page] is created. ### option: BrowserContext.waitForPage.predicate * since: v1.9 @@ -432,7 +398,7 @@ index 686db16f4..b0dc4d4e6 100644 - `predicate` <[function]\([Page]\):[boolean]> Receives the [Page] object and resolves to truthy value when the waiting should resolve. -@@ -1616,7 +1626,8 @@ Receives the [Page] object and resolves to truthy value when the waiting should +@@ -1625,7 +1635,8 @@ Receives the [Page] object and resolves to truthy value when the waiting should ## async method: BrowserContext.waitForEvent2 * since: v1.8 @@ -443,10 +409,10 @@ index 686db16f4..b0dc4d4e6 100644 - returns: <[any]> diff --git a/docs/src/api/class-cdpsession.md b/docs/src/api/class-cdpsession.md -index 8ae780363..01fc2b445 100644 +index a14dd58fb..8e3807d87 100644 --- a/docs/src/api/class-cdpsession.md +++ b/docs/src/api/class-cdpsession.md -@@ -103,7 +103,7 @@ Optional method parameters. +@@ -102,7 +102,7 @@ Optional method parameters. ### param: CDPSession.send.params * since: v1.30 @@ -455,6 +421,46 @@ index 8ae780363..01fc2b445 100644 - alias-csharp: args - `params` ?<[Map]> +diff --git a/docs/src/api/class-clock.md b/docs/src/api/class-clock.md +index f2ee2433b..b89e77f92 100644 +--- a/docs/src/api/class-clock.md ++++ b/docs/src/api/class-clock.md +@@ -71,7 +71,7 @@ Fake timers are used to manually control the flow of time in tests. They allow y + Time to initialize with, current system time by default. + + ### option: Clock.install.time +-* langs: python ++* langs: python, go + * since: v1.45 + - `time` <[float]|[string]|[Date]> + +@@ -169,7 +169,7 @@ await page.Clock.PauseAtAsync("2020-02-02"); + Time to pause at. + + ### param: Clock.pauseAt.time +-* langs: python ++* langs: python, go + * since: v1.45 + - `time` <[float]|[string]|[Date]> + +@@ -233,7 +233,7 @@ await page.Clock.SetFixedTimeAsync("2020-02-02"); + Time to be set in milliseconds. + + ### param: Clock.setFixedTime.time +-* langs: python ++* langs: python, go + * since: v1.45 + - `time` <[float]|[string]|[Date]> + +@@ -291,7 +291,7 @@ await page.Clock.SetSystemTimeAsync("2020-02-02"); + Time to be set in milliseconds. + + ### param: Clock.setSystemTime.time +-* langs: python ++* langs: python, go + * since: v1.45 + - `time` <[float]|[string]|[Date]> + diff --git a/docs/src/api/class-consolemessage.md b/docs/src/api/class-consolemessage.md index 2268ee3ed..44cdaffce 100644 --- a/docs/src/api/class-consolemessage.md @@ -483,10 +489,10 @@ index 2268ee3ed..44cdaffce 100644 * since: v1.8 - returns: <[string]> diff --git a/docs/src/api/class-frame.md b/docs/src/api/class-frame.md -index 50e157b15..84015863d 100644 +index f3f308622..125f34c40 100644 --- a/docs/src/api/class-frame.md +++ b/docs/src/api/class-frame.md -@@ -1952,7 +1952,7 @@ await page.MainFrame.WaitForFunctionAsync("selector => !!document.querySelector( +@@ -1946,7 +1946,7 @@ await page.MainFrame.WaitForFunctionAsync("selector => !!document.querySelector( Optional argument to pass to [`param: expression`]. @@ -495,7 +501,7 @@ index 50e157b15..84015863d 100644 * since: v1.8 ### option: Frame.waitForFunction.polling = %%-csharp-java-wait-for-function-polling-%% -@@ -2004,6 +2004,11 @@ await frame.WaitForLoadStateAsync(); // Defaults to LoadState.Load +@@ -1998,6 +1998,11 @@ await frame.WaitForLoadStateAsync(); // Defaults to LoadState.Load ``` ### param: Frame.waitForLoadState.state = %%-wait-for-load-state-state-%% @@ -507,7 +513,7 @@ index 50e157b15..84015863d 100644 * since: v1.8 ### option: Frame.waitForLoadState.timeout = %%-navigation-timeout-%% -@@ -2016,6 +2021,7 @@ await frame.WaitForLoadStateAsync(); // Defaults to LoadState.Load +@@ -2010,6 +2015,7 @@ await frame.WaitForLoadStateAsync(); // Defaults to LoadState.Load * since: v1.8 * deprecated: This method is inherently racy, please use [`method: Frame.waitForURL`] instead. * langs: @@ -565,10 +571,10 @@ index 1ff5e5211..31dd3a4b0 100644 Expected options currently selected. diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md -index 3d667bb18..a1065ebf9 100644 +index e1aa90804..a6f24f82b 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md -@@ -622,7 +622,7 @@ The order of evaluation of multiple scripts installed via [`method: BrowserConte +@@ -621,7 +621,7 @@ The order of evaluation of multiple scripts installed via [`method: BrowserConte ### param: Page.addInitScript.script * since: v1.8 @@ -577,7 +583,7 @@ index 3d667bb18..a1065ebf9 100644 - `script` <[function]|[string]|[Object]> - `path` ?<[path]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory. Optional. -@@ -1274,11 +1274,11 @@ Passing `null` disables CSS media emulation. +@@ -1270,11 +1270,11 @@ Passing `null` disables CSS media emulation. ### option: Page.emulateMedia.media * since: v1.9 @@ -593,7 +599,7 @@ index 3d667bb18..a1065ebf9 100644 ### option: Page.emulateMedia.colorScheme * since: v1.9 -@@ -1290,11 +1290,11 @@ Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'` +@@ -1286,11 +1286,11 @@ Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'` ### option: Page.emulateMedia.colorScheme * since: v1.9 @@ -608,7 +614,7 @@ index 3d667bb18..a1065ebf9 100644 ### option: Page.emulateMedia.reducedMotion * since: v1.12 -@@ -1305,10 +1305,10 @@ Emulates `'prefers-reduced-motion'` media feature, supported values are `'reduce +@@ -1301,10 +1301,10 @@ Emulates `'prefers-reduced-motion'` media feature, supported values are `'reduce ### option: Page.emulateMedia.reducedMotion * since: v1.12 @@ -622,7 +628,7 @@ index 3d667bb18..a1065ebf9 100644 ### option: Page.emulateMedia.forcedColors * since: v1.15 -@@ -1319,8 +1319,8 @@ Emulates `'forced-colors'` media feature, supported values are `'active'` and `' +@@ -1315,8 +1315,8 @@ Emulates `'forced-colors'` media feature, supported values are `'active'` and `' ### option: Page.emulateMedia.forcedColors * since: v1.15 @@ -633,7 +639,7 @@ index 3d667bb18..a1065ebf9 100644 ## async method: Page.evalOnSelector * since: v1.9 -@@ -2140,14 +2140,14 @@ Frame name specified in the `iframe`'s `name` attribute. +@@ -2136,14 +2136,14 @@ Frame name specified in the `iframe`'s `name` attribute. ### option: Page.frame.name * since: v1.8 @@ -650,7 +656,7 @@ index 3d667bb18..a1065ebf9 100644 - `url` ?<[string]|[RegExp]|[function]\([URL]\):[boolean]> A glob pattern, regex pattern or predicate receiving frame's `url` as a [URL] object. Optional. -@@ -2871,7 +2871,7 @@ Paper width, accepts values labeled with units. +@@ -2866,7 +2866,7 @@ Paper width, accepts values labeled with units. ### option: Page.pdf.width * since: v1.8 @@ -659,7 +665,7 @@ index 3d667bb18..a1065ebf9 100644 - `width` <[string]> Paper width, accepts values labeled with units. -@@ -2885,7 +2885,7 @@ Paper height, accepts values labeled with units. +@@ -2880,7 +2880,7 @@ Paper height, accepts values labeled with units. ### option: Page.pdf.height * since: v1.8 @@ -668,7 +674,7 @@ index 3d667bb18..a1065ebf9 100644 - `height` <[string]> Paper height, accepts values labeled with units. -@@ -2903,7 +2903,7 @@ Paper margins, defaults to none. +@@ -2898,7 +2898,7 @@ Paper margins, defaults to none. ### option: Page.pdf.margin * since: v1.8 @@ -677,7 +683,7 @@ index 3d667bb18..a1065ebf9 100644 - `margin` <[Object]> - `top` ?<[string]> Top margin, accepts values labeled with units. Defaults to `0`. - `right` ?<[string]> Right margin, accepts values labeled with units. Defaults to `0`. -@@ -3326,7 +3326,7 @@ Function that should be run once [`param: locator`] appears. This function shoul +@@ -3321,7 +3321,7 @@ Function that should be run once [`param: locator`] appears. This function shoul Function that should be run once [`param: locator`] appears. This function should get rid of the element that blocks actions like click. ### param: Page.addLocatorHandler.handler @@ -686,7 +692,7 @@ index 3d667bb18..a1065ebf9 100644 * since: v1.42 - `handler` <[function]\([Locator]\)> -@@ -3548,6 +3548,13 @@ it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/We +@@ -3569,6 +3569,13 @@ it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/We handler function to route the request. @@ -700,7 +706,7 @@ index 3d667bb18..a1065ebf9 100644 ### param: Page.route.handler * since: v1.8 * langs: csharp, java -@@ -3930,12 +3937,12 @@ await page.GotoAsync("https://www.microsoft.com"); +@@ -3950,12 +3957,12 @@ await page.GotoAsync("https://www.microsoft.com"); ### param: Page.setViewportSize.width * since: v1.10 @@ -715,7 +721,7 @@ index 3d667bb18..a1065ebf9 100644 - `height` <[int]> page height in pixels. ## async method: Page.tap -@@ -4122,6 +4129,13 @@ A glob pattern, regex pattern or predicate receiving [URL] to match while routin +@@ -4140,6 +4147,13 @@ A glob pattern, regex pattern or predicate receiving [URL] to match while routin Optional handler function to route the request. @@ -729,7 +735,7 @@ index 3d667bb18..a1065ebf9 100644 ### param: Page.unroute.handler * since: v1.8 * langs: csharp, java -@@ -4160,7 +4174,8 @@ Performs action and waits for the Page to close. +@@ -4178,7 +4192,8 @@ Performs action and waits for the Page to close. ## async method: Page.waitForConsoleMessage * since: v1.9 @@ -739,7 +745,7 @@ index 3d667bb18..a1065ebf9 100644 - alias-python: expect_console_message - alias-csharp: RunAndWaitForConsoleMessage - returns: <[ConsoleMessage]> -@@ -4191,7 +4206,8 @@ Receives the [ConsoleMessage] object and resolves to truthy value when the waiti +@@ -4209,7 +4224,8 @@ Receives the [ConsoleMessage] object and resolves to truthy value when the waiti ## async method: Page.waitForDownload * since: v1.9 @@ -749,7 +755,7 @@ index 3d667bb18..a1065ebf9 100644 - alias-python: expect_download - alias-csharp: RunAndWaitForDownload - returns: <[Download]> -@@ -4222,7 +4238,8 @@ Receives the [Download] object and resolves to truthy value when the waiting sho +@@ -4240,7 +4256,8 @@ Receives the [Download] object and resolves to truthy value when the waiting sho ## async method: Page.waitForEvent * since: v1.8 @@ -759,7 +765,7 @@ index 3d667bb18..a1065ebf9 100644 - alias-python: expect_event - returns: <[any]> -@@ -4275,7 +4292,8 @@ Either a predicate that receives an event or an options object. Optional. +@@ -4293,7 +4310,8 @@ Either a predicate that receives an event or an options object. Optional. ## async method: Page.waitForFileChooser * since: v1.9 @@ -769,7 +775,7 @@ index 3d667bb18..a1065ebf9 100644 - alias-python: expect_file_chooser - alias-csharp: RunAndWaitForFileChooser - returns: <[FileChooser]> -@@ -4433,7 +4451,7 @@ await page.WaitForFunctionAsync("selector => !!document.querySelector(selector)" +@@ -4451,7 +4469,7 @@ await page.WaitForFunctionAsync("selector => !!document.querySelector(selector)" Optional argument to pass to [`param: expression`]. @@ -778,7 +784,7 @@ index 3d667bb18..a1065ebf9 100644 * since: v1.8 ### option: Page.waitForFunction.polling = %%-csharp-java-wait-for-function-polling-%% -@@ -4530,6 +4548,11 @@ Console.WriteLine(await popup.TitleAsync()); // popup is ready to use. +@@ -4548,6 +4566,11 @@ Console.WriteLine(await popup.TitleAsync()); // popup is ready to use. ``` ### param: Page.waitForLoadState.state = %%-wait-for-load-state-state-%% @@ -790,7 +796,7 @@ index 3d667bb18..a1065ebf9 100644 * since: v1.8 ### option: Page.waitForLoadState.timeout = %%-navigation-timeout-%% -@@ -4542,6 +4565,7 @@ Console.WriteLine(await popup.TitleAsync()); // popup is ready to use. +@@ -4560,6 +4583,7 @@ Console.WriteLine(await popup.TitleAsync()); // popup is ready to use. * since: v1.8 * deprecated: This method is inherently racy, please use [`method: Page.waitForURL`] instead. * langs: @@ -798,7 +804,7 @@ index 3d667bb18..a1065ebf9 100644 * alias-python: expect_navigation * alias-csharp: RunAndWaitForNavigation - returns: <[null]|[Response]> -@@ -4626,7 +4650,8 @@ a navigation. +@@ -4644,7 +4668,8 @@ a navigation. ## async method: Page.waitForPopup * since: v1.9 @@ -808,7 +814,7 @@ index 3d667bb18..a1065ebf9 100644 - alias-python: expect_popup - alias-csharp: RunAndWaitForPopup - returns: <[Page]> -@@ -4658,6 +4683,7 @@ Receives the [Page] object and resolves to truthy value when the waiting should +@@ -4676,6 +4701,7 @@ Receives the [Page] object and resolves to truthy value when the waiting should ## async method: Page.waitForRequest * since: v1.8 * langs: @@ -816,7 +822,7 @@ index 3d667bb18..a1065ebf9 100644 * alias-python: expect_request * alias-csharp: RunAndWaitForRequest - returns: <[Request]> -@@ -4765,7 +4791,8 @@ changed by using the [`method: Page.setDefaultTimeout`] method. +@@ -4783,7 +4809,8 @@ changed by using the [`method: Page.setDefaultTimeout`] method. ## async method: Page.waitForRequestFinished * since: v1.12 @@ -826,7 +832,7 @@ index 3d667bb18..a1065ebf9 100644 - alias-python: expect_request_finished - alias-csharp: RunAndWaitForRequestFinished - returns: <[Request]> -@@ -4797,6 +4824,7 @@ Receives the [Request] object and resolves to truthy value when the waiting shou +@@ -4815,6 +4842,7 @@ Receives the [Request] object and resolves to truthy value when the waiting shou ## async method: Page.waitForResponse * since: v1.8 * langs: @@ -834,7 +840,7 @@ index 3d667bb18..a1065ebf9 100644 * alias-python: expect_response * alias-csharp: RunAndWaitForResponse - returns: <[Response]> -@@ -5160,7 +5188,8 @@ await page.WaitForURLAsync("**/target.html"); +@@ -5178,7 +5206,8 @@ await page.WaitForURLAsync("**/target.html"); ## async method: Page.waitForWebSocket * since: v1.9 @@ -844,7 +850,7 @@ index 3d667bb18..a1065ebf9 100644 - alias-python: expect_websocket - alias-csharp: RunAndWaitForWebSocket - returns: <[WebSocket]> -@@ -5191,7 +5220,8 @@ Receives the [WebSocket] object and resolves to truthy value when the waiting sh +@@ -5209,7 +5238,8 @@ Receives the [WebSocket] object and resolves to truthy value when the waiting sh ## async method: Page.waitForWorker * since: v1.9 @@ -854,7 +860,7 @@ index 3d667bb18..a1065ebf9 100644 - alias-python: expect_worker - alias-csharp: RunAndWaitForWorker - returns: <[Worker]> -@@ -5233,7 +5263,8 @@ This does not contain ServiceWorkers +@@ -5251,7 +5281,8 @@ This does not contain ServiceWorkers ## async method: Page.waitForEvent2 * since: v1.8 @@ -865,7 +871,7 @@ index 3d667bb18..a1065ebf9 100644 - returns: <[any]> diff --git a/docs/src/api/class-pageassertions.md b/docs/src/api/class-pageassertions.md -index 51076e5e0..b20771b7e 100644 +index 2dcd17b3a..10505c95f 100644 --- a/docs/src/api/class-pageassertions.md +++ b/docs/src/api/class-pageassertions.md @@ -69,7 +69,7 @@ public class ExampleTests : PageTest @@ -913,12 +919,12 @@ index 7a960e34e..375498833 100644 Creates a [PageAssertions] object for the given [Page]. diff --git a/docs/src/api/class-request.md b/docs/src/api/class-request.md -index fcf231f75..f14d3f914 100644 +index e13d9de69..6fb14af3d 100644 --- a/docs/src/api/class-request.md +++ b/docs/src/api/class-request.md @@ -126,6 +126,13 @@ Headers with multiple entries, such as `Set-Cookie`, appear in the array multipl - Returns the value of the header matching the name. The name is case insensitive. + Returns the value of the header matching the name. The name is case-insensitive. +## async method: Request.headerValue +* since: v1.15 @@ -940,7 +946,7 @@ index fcf231f75..f14d3f914 100644 Returns parsed request's body for `form-urlencoded` and JSON as a fallback if any. diff --git a/docs/src/api/class-response.md b/docs/src/api/class-response.md -index 13ff68b85..761ac8bc8 100644 +index cddaf6965..6aa3225f5 100644 --- a/docs/src/api/class-response.md +++ b/docs/src/api/class-response.md @@ -23,7 +23,7 @@ Waits for this response to finish, returns always `null`. @@ -953,7 +959,7 @@ index 13ff68b85..761ac8bc8 100644 ## method: Response.frame @@ -62,6 +62,14 @@ Headers with multiple entries, such as `Set-Cookie`, appear in the array multipl - Returns the value of the header matching the name. The name is case insensitive. If multiple headers have + Returns the value of the header matching the name. The name is case-insensitive. If multiple headers have the same name (except `set-cookie`), they are returned as a list separated by `, `. For `set-cookie`, the `\n` separator is used. If no headers are found, `null` is returned. +## async method: Response.headerValue @@ -977,10 +983,10 @@ index 13ff68b85..761ac8bc8 100644 Returns the JSON representation of response body. diff --git a/docs/src/api/class-route.md b/docs/src/api/class-route.md -index dcdca4705..c6d3acebe 100644 +index 106fbf55e..b5c898fd8 100644 --- a/docs/src/api/class-route.md +++ b/docs/src/api/class-route.md -@@ -125,7 +125,7 @@ If set changes the post data of request. +@@ -127,7 +127,7 @@ If set changes the post data of request. ### option: Route.continue.postData * since: v1.8 @@ -989,7 +995,7 @@ index dcdca4705..c6d3acebe 100644 - `postData` <[string]|[Buffer]> If set changes the post data of request. -@@ -408,7 +408,7 @@ If set changes the post data of request. +@@ -414,7 +414,7 @@ If set changes the post data of request. ### option: Route.fallback.postData * since: v1.23 @@ -998,7 +1004,7 @@ index dcdca4705..c6d3acebe 100644 - `postData` <[string]|[Buffer]> If set changes the post data of request. -@@ -525,7 +525,7 @@ and `content-type` header will be set to `application/json` if not explicitly se +@@ -537,7 +537,7 @@ and `content-type` header will be set to `application/json` if not explicitly se set to `application/octet-stream` if not explicitly set. ### option: Route.fetch.postData @@ -1007,7 +1013,7 @@ index dcdca4705..c6d3acebe 100644 * since: v1.29 - `postData` <[string]|[Buffer]> -@@ -638,7 +638,7 @@ If set, equals to setting `Content-Type` response header. +@@ -650,7 +650,7 @@ If set, equals to setting `Content-Type` response header. ### option: Route.fulfill.body * since: v1.8 @@ -1095,7 +1101,7 @@ index 3b3308b88..e21ea93ef 100644 - returns: <[any]> diff --git a/docs/src/api/params.md b/docs/src/api/params.md -index a1dd84c4e..f9164ab56 100644 +index ccd6bae8f..059ed0b8e 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md @@ -8,7 +8,7 @@ When to consider operation succeeded, defaults to `load`. Events can be either: @@ -1125,7 +1131,7 @@ index a1dd84c4e..f9164ab56 100644 - `timeout` <[float]> Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by -@@ -176,8 +176,8 @@ Defaults to `'visible'`. Can be either: +@@ -183,8 +183,8 @@ Defaults to `'visible'`. Can be either: * `'hidden'` - wait for element to be either detached from DOM, or have an empty bounding box or `visibility:hidden`. This is opposite to the `'visible'` option. @@ -1136,7 +1142,7 @@ index a1dd84c4e..f9164ab56 100644 - `polling` <[float]|"raf"> If [`option: polling`] is `'raf'`, then [`param: expression`] is constantly executed in `requestAnimationFrame` -@@ -198,14 +198,14 @@ If `true`, Playwright does not pass its own configurations args and only uses th +@@ -205,14 +205,14 @@ If `true`, Playwright does not pass its own configurations args and only uses th array is given, then filters out the given default arguments. Dangerous option; use with care. Defaults to `false`. ## csharp-java-browser-option-ignoredefaultargs @@ -1153,7 +1159,7 @@ index a1dd84c4e..f9164ab56 100644 - `ignoreAllDefaultArgs` <[boolean]> If `true`, Playwright does not pass its own configurations args and only uses the ones from [`option: args`]. -@@ -224,7 +224,7 @@ Dangerous option; use with care. Defaults to `false`. +@@ -231,7 +231,7 @@ Dangerous option; use with care. Defaults to `false`. Network proxy settings. ## csharp-java-browser-option-env @@ -1162,16 +1168,37 @@ index a1dd84c4e..f9164ab56 100644 - `env` <[Object]<[string], [string]>> Specify environment variables that will be visible to the browser. Defaults to `process.env`. -@@ -236,7 +236,7 @@ Specify environment variables that will be visible to the browser. Defaults to ` - Specify environment variables that will be visible to the browser. Defaults to `process.env`. +@@ -264,6 +264,29 @@ Learn more about [storage state and auth](../auth.md). - ## js-python-context-option-storage-state --* langs: js, python -+* langs: js, python, go - - `storageState` <[path]|[Object]> - - `cookies` <[Array]<[Object]>> Cookies to set for context - - `name` <[string]> -@@ -265,7 +265,7 @@ Populates context with given storage state. This option can be used to initializ + Populates context with given storage state. This option can be used to initialize context with logged-in information obtained via [`method: BrowserContext.storageState`]. + ++## go-context-option-storage-state ++* langs: go ++- `storageState` <[path]|[Object]> ++ - `cookies` <[Array]<[Object]>> Cookies to set for context ++ - `name` <[string]> ++ - `value` <[string]> ++ - `url` ?<[string]> Either url or domain / path are required. Optional. ++ - `domain` ?<[string]> For the cookie to apply to all subdomains as well, prefix domain with a dot, like this: ".example.com". Either url or domain / path are required. Optional. ++ - `path` ?<[string]> Either url or domain / path are required Optional. ++ - `expires` ?<[float]> Unix time in seconds. Optional. ++ - `httpOnly` ?<[boolean]> Optional. ++ - `secure` ?<[boolean]> Optional. ++ - `sameSite` ?<[SameSiteAttribute]<"Strict"|"Lax"|"None">> Optional. ++ - `origins` <[Array]<[Object]>> localStorage to set for context ++ - `origin` <[string]> ++ - `localStorage` <[Array]<[Object]>> ++ - `name` <[string]> ++ - `value` <[string]> ++ ++Learn more about [storage state and auth](../auth.md). ++ ++Populates context with given storage state. This option can be used to initialize context with logged-in information obtained via [`method: BrowserContext.storageState`]. ++ + ## csharp-java-context-option-storage-state + * langs: csharp, java + - `storageState` <[string]> +@@ -272,7 +295,7 @@ Populates context with given storage state. This option can be used to initializ obtained via [`method: BrowserContext.storageState`]. ## csharp-java-context-option-storage-state-path @@ -1180,7 +1207,7 @@ index a1dd84c4e..f9164ab56 100644 - `storageStatePath` <[path]> Populates context with given storage state. This option can be used to initialize context with logged-in information -@@ -356,7 +356,7 @@ Target URL. +@@ -369,7 +392,7 @@ Query parameters to be sent with the URL. Query parameters to be sent with the URL. ## csharp-fetch-option-params @@ -1189,7 +1216,7 @@ index a1dd84c4e..f9164ab56 100644 - `params` <[Object]<[string], [Serializable]>> Query parameters to be sent with the URL. -@@ -368,19 +368,19 @@ Query parameters to be sent with the URL. +@@ -381,19 +404,19 @@ Query parameters to be sent with the URL. Optional request parameters. ## js-python-csharp-fetch-option-headers @@ -1212,7 +1239,7 @@ index a1dd84c4e..f9164ab56 100644 - `failOnStatusCode` <[boolean]> Whether to throw on response codes other than 2xx and 3xx. By default response object is returned -@@ -404,6 +404,14 @@ unless explicitly provided. +@@ -417,6 +440,14 @@ unless explicitly provided. An instance of [FormData] can be created via [`method: APIRequestContext.createFormData`]. @@ -1227,7 +1254,7 @@ index a1dd84c4e..f9164ab56 100644 ## js-fetch-option-multipart * langs: js - `multipart` <[FormData]|[Object]<[string], [string]|[float]|[boolean]|[ReadStream]|[Object]>> -@@ -437,6 +445,15 @@ unless explicitly provided. File values can be passed as file-like object contai +@@ -450,6 +481,15 @@ unless explicitly provided. File values can be passed as file-like object contai An instance of [FormData] can be created via [`method: APIRequestContext.createFormData`]. @@ -1243,7 +1270,7 @@ index a1dd84c4e..f9164ab56 100644 ## js-python-csharp-fetch-option-data * langs: js, python, csharp - `data` <[string]|[Buffer]|[Serializable]> -@@ -445,14 +462,22 @@ Allows to set post data of the request. If the data parameter is an object, it w +@@ -458,21 +498,29 @@ Allows to set post data of the request. If the data parameter is an object, it w and `content-type` header will be set to `application/json` if not explicitly set. Otherwise the `content-type` header will be set to `application/octet-stream` if not explicitly set. @@ -1268,7 +1295,15 @@ index a1dd84c4e..f9164ab56 100644 - `maxRedirects` <[int]> Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is exceeded. -@@ -495,7 +520,7 @@ Function to be evaluated in the worker context. + Defaults to `20`. Pass `0` to not follow redirects. + + ## js-python-csharp-fetch-option-maxretries +-* langs: js, python, csharp ++* langs: js, python, csharp, go + - `maxRetries` <[int]> + + Maximum number of times network errors should be retried. Currently only `ECONNRESET` error is retried. Does not retry based on HTTP response codes. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. +@@ -514,7 +562,7 @@ Function to be evaluated in the worker context. Function to be evaluated in the main Electron process. ## python-context-option-viewport @@ -1277,7 +1312,7 @@ index a1dd84c4e..f9164ab56 100644 - `viewport` <[null]|[Object]> - `width` <[int]> page width in pixels. - `height` <[int]> page height in pixels. -@@ -503,7 +528,7 @@ Function to be evaluated in the main Electron process. +@@ -522,7 +570,7 @@ Function to be evaluated in the main Electron process. Sets a consistent viewport for each page. Defaults to an 1280x720 viewport. `no_viewport` disables the fixed viewport. Learn more about [viewport emulation](../emulation.md#viewport). ## python-context-option-no-viewport @@ -1286,7 +1321,7 @@ index a1dd84c4e..f9164ab56 100644 - `noViewport` <[boolean]> Does not enforce fixed viewport, allows resizing window in the headed mode. -@@ -584,11 +609,11 @@ Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'` +@@ -628,11 +676,11 @@ Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'` [`method: Page.emulateMedia`] for more details. Passing `null` resets emulation to system defaults. Defaults to `'light'`. ## context-option-colorscheme-csharp-python @@ -1301,7 +1336,7 @@ index a1dd84c4e..f9164ab56 100644 ## context-option-reducedMotion * langs: js, java -@@ -597,10 +622,10 @@ Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'` +@@ -641,10 +689,10 @@ Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'` Emulates `'prefers-reduced-motion'` media feature, supported values are `'reduce'`, `'no-preference'`. See [`method: Page.emulateMedia`] for more details. Passing `null` resets emulation to system defaults. Defaults to `'no-preference'`. ## context-option-reducedMotion-csharp-python @@ -1315,7 +1350,7 @@ index a1dd84c4e..f9164ab56 100644 ## context-option-forcedColors * langs: js, java -@@ -609,10 +634,10 @@ Emulates `'prefers-reduced-motion'` media feature, supported values are `'reduce +@@ -653,10 +701,10 @@ Emulates `'prefers-reduced-motion'` media feature, supported values are `'reduce Emulates `'forced-colors'` media feature, supported values are `'active'`, `'none'`. See [`method: Page.emulateMedia`] for more details. Passing `null` resets emulation to system defaults. Defaults to `'none'`. ## context-option-forcedColors-csharp-python @@ -1329,7 +1364,7 @@ index a1dd84c4e..f9164ab56 100644 ## context-option-logger * langs: js -@@ -647,7 +672,7 @@ specified, the HAR is not recorded. Make sure to await [`method: BrowserContext. +@@ -691,7 +739,7 @@ specified, the HAR is not recorded. Make sure to await [`method: BrowserContext. saved. ## context-option-recordhar-path @@ -1338,7 +1373,7 @@ index a1dd84c4e..f9164ab56 100644 - alias-python: record_har_path - `recordHarPath` <[path]> -@@ -656,33 +681,33 @@ specified HAR file on the filesystem. If not specified, the HAR is not recorded. +@@ -700,33 +748,33 @@ specified HAR file on the filesystem. If not specified, the HAR is not recorded. call [`method: BrowserContext.close`] for the HAR to be saved. ## context-option-recordhar-omit-content @@ -1377,8 +1412,8 @@ index a1dd84c4e..f9164ab56 100644 - `recordVideo` <[Object]> - `dir` <[path]> Path to the directory to put videos into. - `size` ?<[Object]> Optional dimensions of the recorded videos. If not specified the size will be equal to `viewport` -@@ -747,7 +772,7 @@ Whether to allow sites to register Service workers. Defaults to `'allow'`. - * `'block'`: Playwright will block all registration of Service Workers. +@@ -795,7 +843,7 @@ Specifies whether to wait for already running listeners and what to do if they t + * `'ignoreErrors'` - do not wait for current listener calls (if any) to finish, all errors thrown by the listeners after removal are silently caught ## unroute-all-options-behavior -* langs: js, csharp, python @@ -1386,8 +1421,8 @@ index a1dd84c4e..f9164ab56 100644 * since: v1.41 - `behavior` <[UnrouteBehavior]<"wait"|"ignoreErrors"|"default">> -@@ -757,7 +782,7 @@ Specifies whether to wait for already running handlers and what to do if they th - * `'ignoreErrors'` - do not wait for current handler calls (if any) to finish, all errors thrown by the handlers after unrouting are silently caught +@@ -806,7 +854,7 @@ Specifies whether to wait for already running handlers and what to do if they th + ## select-options-values -* langs: java, js, csharp @@ -1395,7 +1430,7 @@ index a1dd84c4e..f9164ab56 100644 - `values` <[null]|[string]|[ElementHandle]|[Array]<[string]>|[Object]|[Array]<[ElementHandle]>|[Array]<[Object]>> - `value` ?<[string]> Matches by `option.value`. Optional. - `label` ?<[string]> Matches by `option.label`. Optional. -@@ -775,7 +800,7 @@ the parameter is a string without wildcard characters, the method will wait for +@@ -824,7 +872,7 @@ the parameter is a string without wildcard characters, the method will wait for equal to the string. ## wait-for-event-event @@ -1404,7 +1439,7 @@ index a1dd84c4e..f9164ab56 100644 - `event` <[string]> Event name, same one typically passed into `*.on(event)`. -@@ -833,7 +858,7 @@ only the first option matching one of the passed options is selected. Optional. +@@ -882,7 +930,7 @@ only the first option matching one of the passed options is selected. Optional. Receives the event data and resolves to truthy value when the waiting should resolve. ## wait-for-event-timeout @@ -1413,7 +1448,7 @@ index a1dd84c4e..f9164ab56 100644 - `timeout` <[float]> Maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. -@@ -853,7 +878,7 @@ using the [`method: AndroidDevice.setDefaultTimeout`] method. +@@ -902,7 +950,7 @@ using the [`method: AndroidDevice.setDefaultTimeout`] method. Time to retry the assertion for in milliseconds. Defaults to `timeout` in `TestConfig.expect`. ## csharp-java-python-assertions-timeout @@ -1422,7 +1457,7 @@ index a1dd84c4e..f9164ab56 100644 - `timeout` <[float]> Time to retry the assertion for in milliseconds. Defaults to `5000`. -@@ -992,7 +1017,7 @@ Firefox user preferences. Learn more about the Firefox user preferences at +@@ -1041,7 +1089,7 @@ Firefox user preferences. Learn more about the Firefox user preferences at [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox). ## csharp-java-browser-option-firefoxuserprefs @@ -1433,10 +1468,10 @@ index a1dd84c4e..f9164ab56 100644 Firefox user preferences. Learn more about the Firefox user preferences at diff --git a/utils/doclint/generateGoApi.js b/utils/doclint/generateGoApi.js new file mode 100644 -index 000000000..b3c147d77 +index 000000000..cd59dd615 --- /dev/null +++ b/utils/doclint/generateGoApi.js -@@ -0,0 +1,854 @@ +@@ -0,0 +1,860 @@ +/** + * Copyright (c) Microsoft Corporation. + * @@ -1605,6 +1640,8 @@ index 000000000..b3c147d77 + out.push(...transformComment(element)); + + out.push(`type ${name} interface {`); ++ if (['Browser', 'BrowserContext', 'CDPSession', 'Page'].includes(name)) // v1.47 ++ out.push('EventEmitter'); + if (element.extends) + out.push(element.extends) + @@ -1640,7 +1677,7 @@ index 000000000..b3c147d77 + out.push(`type ${name} struct {`) + + for (const member of type.properties) { -+ let fakeType = new Type(name, null); ++ let fakeType = new Type(name, undefined); + renderMember(member, fakeType, out, name.endsWith('Options')); + } + @@ -1680,7 +1717,7 @@ index 000000000..b3c147d77 + * @param {string} name + */ +function toArgumentName(name) { -+ return `${ name === 'type' ? 'typ' : name}`; ++ return `${name === 'type' ? 'typ' : name}`; +} + +/** @@ -1728,7 +1765,7 @@ index 000000000..b3c147d77 + return; + } + -+ let type = translateType(member.type, parent, t => generateNameDefault(member, name, t, parent), !member.required || isOptional, false, true); ++ let type = translateType(member.type, parent, t => generateNameDefault(member, name, t, parent), !member.required || isOptional, false); + + if ((additionalTypes.has(type) || enumTypes.has(type)) && !classNameMap.has(type)) { + type = `${type}`.replace(/^\*?/, '*'); @@ -1778,8 +1815,8 @@ index 000000000..b3c147d77 + // For some of these we don't want to generate generic types. + // For some others we simply did not have the code that was deduping the names. + if (attemptedName === 'Cookie') { -+ const optionalMembers = t?.properties.filter(m => !m.required) -+ if (optionalMembers.length > 1) ++ const optionalMembers = t.properties?.filter(m => !m.required) ++ if ( optionalMembers && optionalMembers.length > 1) + attemptedName = 'OptionalCookie'; + } + if (attemptedName === 'BoundingBox' || attemptedName === 'Clip') @@ -1871,7 +1908,7 @@ index 000000000..b3c147d77 + const name = toMemberName(member); + + if (member.kind === 'event') { -+ const payloadType = translateType(member.type, parent, t => generateNameDefault(member, name, t, parent), false, true, false) ++ const payloadType = translateType(member.type, parent, t => generateNameDefault(member, name, t, parent), false, false) + output(transformComment(member)); + output(`${name}(fn func(${payloadType}))`); + return; @@ -1932,7 +1969,7 @@ index 000000000..b3c147d77 + + let argType = translateType(arg.type, parent, (t) => generateNameDefault(member, argName, t, parent), !arg.required); + -+ if (argType === null && arg.type.union) { ++ if (!argType) { + argType = 'interface{}' + } else if (argName === 'handler' && argType === 'interface{}') { + argType = 'func()' @@ -2283,10 +2320,14 @@ index 000000000..b3c147d77 +function typesDiffer(left, right) { + if (left.name !== right.name) + return true; -+ const replacer = (k, v) => k === 'spec' || k === 'comment' ? undefined : v ++ const replacer = (k, v) => { ++ if (k === 'since' || k === 'spec' || k === 'comment' || k === 'enclosingMethod' || k === 'parent') ++ return undefined; ++ return v ++ } + if (JSON.stringify(right.properties, replacer) !== JSON.stringify(left.properties, replacer)) { -+ // console.log(JSON.stringify(left.properties) + '\n') -+ // console.log(JSON.stringify(right.properties) + '\n') ++ // console.log(JSON.stringify(left.properties, replacer) + '\n') ++ // console.log(JSON.stringify(right.properties, replacer) + '\n') + return true; + } + return false; diff --git a/playwright b/playwright index e8989f83..d5943def 160000 --- a/playwright +++ b/playwright @@ -1 +1 @@ -Subproject commit e8989f83d9801cdaadc3803b5341c601c9593947 +Subproject commit d5943def35edadc6f9bd8daeed382559d2a55fbe diff --git a/run.go b/run.go index 4e32073c..ac8e01fe 100644 --- a/run.go +++ b/run.go @@ -18,7 +18,7 @@ import ( ) const ( - playwrightCliVersion = "1.45.1" + playwrightCliVersion = "1.47.0" ) var ( diff --git a/tests/assets/client-certificates/README.md b/tests/assets/client-certificates/README.md new file mode 100644 index 00000000..7ee690de --- /dev/null +++ b/tests/assets/client-certificates/README.md @@ -0,0 +1,62 @@ +# Client Certificate test-certificates + +## Server + +```bash +openssl req \ + -x509 \ + -newkey rsa:4096 \ + -keyout server/server_key.pem \ + -out server/server_cert.pem \ + -nodes \ + -days 365 \ + -subj "/CN=localhost/O=Client\ Certificate\ Demo" \ + -addext "subjectAltName=DNS:localhost,DNS:local.playwright" +``` + +## Trusted client-certificate (server signed/valid) + +``` +mkdir -p client/trusted +# generate server-signed (valid) certifcate +openssl req \ + -newkey rsa:4096 \ + -keyout client/trusted/key.pem \ + -out client/trusted/csr.pem \ + -nodes \ + -days 365 \ + -subj "/CN=Alice" + +# sign with server_cert.pem +openssl x509 \ + -req \ + -in client/trusted/csr.pem \ + -CA server/server_cert.pem \ + -CAkey server/server_key.pem \ + -out client/trusted/cert.pem \ + -set_serial 01 \ + -days 365 +# create pfx +openssl pkcs12 -export -out client/trusted/cert.pfx -inkey client/trusted/key.pem -in client/trusted/cert.pem -passout pass:secure +``` + +## Self-signed certificate (invalid) + +``` +mkdir -p client/self-signed +openssl req \ + -newkey rsa:4096 \ + -keyout client/self-signed/key.pem \ + -out client/self-signed/csr.pem \ + -nodes \ + -days 365 \ + -subj "/CN=Bob" + +# sign with self-signed/key.pem +openssl x509 \ + -req \ + -in client/self-signed/csr.pem \ + -signkey client/self-signed/key.pem \ + -out client/self-signed/cert.pem \ + -days 365 +``` diff --git a/tests/assets/client-certificates/client/self-signed/cert.pem b/tests/assets/client-certificates/client/self-signed/cert.pem new file mode 100644 index 00000000..3c077179 --- /dev/null +++ b/tests/assets/client-certificates/client/self-signed/cert.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEyzCCArOgAwIBAgIUYps4gh4MqFYg8zqQhHYL7zYfbLkwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDQm9iMB4XDTI0MDcxOTEyNDc0MFoXDTI1MDcxOTEyNDc0 +MFowDjEMMAoGA1UEAwwDQm9iMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEA179eTsqcc1c3AOQHzCZEyYLPta2CCAscUFqcEZ9vWvjW0uzOv9TDlB33Unov +jch4CElZOBhzTadVsbmnYKpxwyVU89WCuQKvedz4k1vu7S1YryfNbmS8PWbnQ4ds +9NB7SgJNHZILvx9DXuWeFEyzRIo1984z4HheBzrkf791LqpYKaKziANUo8h8t0dm +TX/boOz8cEnQNwtTC0ZX3aD0obG/UAhr/22ZGPo/E659fh4ptyYX2LrIUHGy+Eux +nJ9Y4cTqa88Ee6K6AkDiT/AoNQNxE4X++jqLuie8j/ZYpI1Oll38GwKVOyy1msRL +toGmISNwkMIQDGABrJlxgpP4QQAQ+08v9srzXOlkdxdr7OCP81r+ccBXiSQEe7BA +kdJ8l98l5dprJ++GJ+SZcV4+/iGR0dKU2IdAG5HiKZIFn6ch9Ux+UMqeGaYCpkHr +TiietHwcXgtVBlE0jFmB/HspmI/O0abK+grMmueaH7XtTI8YHnw0mUpL8+yp7mfA +7zFusgFgyiBPXeD/NQgg8vja67k++d1VGoXm2xr+5WPQCSbgQoMkkOBMLHWJTefd +6F4Z5M+oI0VwYbf6eQW246wJgpCHSPR0Vdijd6MAGRWKUuLfDsA9+12iGbKvwJ2e +nJlStft2V2LZcjBfdIMbigW1aSVNN5w6m6YVrQPry3WPkWcCAwEAAaMhMB8wHQYD +VR0OBBYEFPxKWTFQJSg4HD2qjxL0dnXX/z4qMA0GCSqGSIb3DQEBCwUAA4ICAQBz +4H1d5eGRU9bekUvi7LbZ5CP/I6w6PL/9AlXqO3BZKxplK7fYGHd3uqyDorJEsvjV +hxwvFlEnS0JIU3nRzhJU/h4Yaivf1WLRFwGZ4TPBjX9KFU27exFWD3rppazkWybJ +i4WuEdP3TJMdKLcNTtXWUDroDOgPlS66u6oZ+mUyUROil+B+fgQgVDhjRc5fvRgZ +Lng8wuejCo3ExQyxkwn2G5guyIimgHmOQghPtLO5xlc67Z4GPUZ1m4tC+BCiFO4D +YIXl3QiIpmU7Pss39LLKMGXXAgLRqyMzqE52lsznu18v5vDLfTaRH4u/wjzULhXz +SrV1IUJmhgEXta4EeDmPH0itgKtkbwjgCOD7drrFrJq/EnvIaJ5cpxiI1pFmYD8g +VVD7/KT/CyT1Uz1dI8QaP/JX8XEgtMJaSkPfjPErIViN9rh9ECCNLgFyv7Y0Plar +A6YlvdyV1Rta/BHndf5Hqz9QWNhbFCMQRGVQNEcoKwpFyjAE9SXoKJvFIK/w5WXu +qKzIYA26QXE3p734Xu1n8QiFJIyltVHbyUlD0k06194t5a2WK+/eDeReIsk0QOI8 +FGqhyPZ7YjR5tSZTmgljtViqBO5AA23QOVFqtjOUrjXP5pTbPJel99Z/FTkqSwvB +Rt4OX7HfuokWQDTT0TMn5jVtJyi54cH7f9MmsNJ23g== +-----END CERTIFICATE----- diff --git a/tests/assets/client-certificates/client/self-signed/csr.pem b/tests/assets/client-certificates/client/self-signed/csr.pem new file mode 100644 index 00000000..4c99e134 --- /dev/null +++ b/tests/assets/client-certificates/client/self-signed/csr.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEUzCCAjsCAQAwDjEMMAoGA1UEAwwDQm9iMIICIjANBgkqhkiG9w0BAQEFAAOC +Ag8AMIICCgKCAgEA179eTsqcc1c3AOQHzCZEyYLPta2CCAscUFqcEZ9vWvjW0uzO +v9TDlB33Unovjch4CElZOBhzTadVsbmnYKpxwyVU89WCuQKvedz4k1vu7S1YryfN +bmS8PWbnQ4ds9NB7SgJNHZILvx9DXuWeFEyzRIo1984z4HheBzrkf791LqpYKaKz +iANUo8h8t0dmTX/boOz8cEnQNwtTC0ZX3aD0obG/UAhr/22ZGPo/E659fh4ptyYX +2LrIUHGy+EuxnJ9Y4cTqa88Ee6K6AkDiT/AoNQNxE4X++jqLuie8j/ZYpI1Oll38 +GwKVOyy1msRLtoGmISNwkMIQDGABrJlxgpP4QQAQ+08v9srzXOlkdxdr7OCP81r+ +ccBXiSQEe7BAkdJ8l98l5dprJ++GJ+SZcV4+/iGR0dKU2IdAG5HiKZIFn6ch9Ux+ +UMqeGaYCpkHrTiietHwcXgtVBlE0jFmB/HspmI/O0abK+grMmueaH7XtTI8YHnw0 +mUpL8+yp7mfA7zFusgFgyiBPXeD/NQgg8vja67k++d1VGoXm2xr+5WPQCSbgQoMk +kOBMLHWJTefd6F4Z5M+oI0VwYbf6eQW246wJgpCHSPR0Vdijd6MAGRWKUuLfDsA9 ++12iGbKvwJ2enJlStft2V2LZcjBfdIMbigW1aSVNN5w6m6YVrQPry3WPkWcCAwEA +AaAAMA0GCSqGSIb3DQEBCwUAA4ICAQCb07d2IjUy1PeHCj/2k/z9FrZSo6K3c8y6 +b/u/MZ0AXPKLPDSo7UYpOJ8Z2cBiJ8jQapjTSEL8POUYqcvCmP55R6u68KmvINHo ++Ly7pP+xPrbA4Q0WmPnz37hQn+I1he0GuEQyjZZqUln9zwp67TsWNKxKtCH+1j8M +Ltzx6kuHCdPtDUtv291yhVRqvbjiDs+gzdQYNJtAkUbHwHFxu8oZhg8QZGyXYMN8 +TGoQ1LTezFZXJtX69K7WnrDGrjsgB6EMvwkqAFSYNH0LFvI0xo13OOgXr9mrwohA +76uZtjXL9B15EqrMce6mdUZi46QJuQ2avTi57Lz+fqvsBYdQO89VcFSmqu2nfspN +QZDrooyjHrlls8MpoBd8fde9oT4uA4/d9SJtuHUnjgGN7Qr7eTruWXL8wVMwFnvL +igWE4detO9y2gpRLq6uEqzWYMGtN9PXJCGU8C8m9E2EBUKMrT/bpNbboatLcgRrW +acj0BRVqoVzk1sRq7Sa6ejywqgARvIhTehg6DqdMdcENCPQ7rxDRu5PSDM8/mwIj +0KYl8d2PlECB4ofRyLcy17BZzjP6hSnkGzcFk0/bChZOSIRnwvKbvfXnB45hhPk8 +XwT/6UNSwC2STP3gtOmLqrWj+OE0gy0AkDMvP3UnQVGMUvgfYg+N4ROCVtlqzxe9 +W65c05Mm1g== +-----END CERTIFICATE REQUEST----- diff --git a/tests/assets/client-certificates/client/self-signed/key.pem b/tests/assets/client-certificates/client/self-signed/key.pem new file mode 100644 index 00000000..70d5e3dd --- /dev/null +++ b/tests/assets/client-certificates/client/self-signed/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +dg6m3MAyZ1IXjHlogOdmGvnq07/w +-----END PRIVATE KEY----- diff --git a/tests/assets/client-certificates/client/trusted/cert-legacy.pfx b/tests/assets/client-certificates/client/trusted/cert-legacy.pfx new file mode 100644 index 0000000000000000000000000000000000000000..9f06aa35c82f05be583a0cf8de295a68fdb9ccbf GIT binary patch literal 4045 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 v0%SM}+@;+8399Sr=!Rn90H#R9{ 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 literal 0 HcmV?d00001 diff --git a/tests/assets/client-certificates/client/trusted/csr.pem b/tests/assets/client-certificates/client/trusted/csr.pem new file mode 100644 index 00000000..8ead6da3 --- /dev/null +++ b/tests/assets/client-certificates/client/trusted/csr.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEVTCCAj0CAQAwEDEOMAwGA1UEAwwFQWxpY2UwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQCac3+4rNmH4/N1s4HqR2X168tgS/aA6sHW5at8mWRnq54N +m11RvnK55jHQYVAdBgJy5M07w0wakp8inxzlY95wqxBimYG63Un/1p7mX9FkB4LN +ISCc6j/s/Ufv85MXPbn0S5rm9UcQO9cINJb1RP1YgDDLN5cxMz6X4nyofN8H6Lhv +h4JDdBw4DfDEFERkVfF+bkZ7YW4XHEChgzm3RxCF0eeGzIXGrkkK9AsSdJAhOvTl +HPFCQKXTYZhsL5+3Ma4RnWnDWvLTHx6KzoU+twTM2mYhhQuQgQpnmDHxGge8kGeH +GtfdgAjtVJTE57xF/shP0JU+tuIV8NNhQ/vEmhL0Wa093/EvpTVp0EUEuDh9ORRH +5K5M4bKJyU4XX5noiht6yOn00uaoJcWduUAWsU+cDSvDTMw81opWWm0QIAV3G2yu +RSkumHAKqvQLeyeyiKz+OEhyEiZ7EZNExPD0TSpApSTU6aCTUAvPYGQ59VjsMHTu +J9r4wKIYaDvfL+t72vg2vTQma5cTOBJfIdxH9blFTjEnToH3LX8t0XndQ2RkiRnI +ze2p2jUShxo/lWCjCw+2Iaw0A0fNUK1BbOrFRPq1u7AnEuMJt7HF50MloItM97R9 +vofDwgDIzlX/PzlVRcn1WCo8Fr/0EXxPPreX0YDIp1ANQ8fSv7bKb2vQIxWuCQID +AQABoAAwDQYJKoZIhvcNAQELBQADggIBAGgf3EC8WL3RGmuGA+d/4wd1jNfrfU6n +xjnDwdEEX0TQZGGPjh5xvoCK76yZPkO6+z0IYSepEmWBS27HJKl7nuoOvS7MjQyJ +C+3Bdk3ToCeQjmNBlRBKsUw5ftTU902oMl5BptHGj1KGjYBLAkPdXb44wXSVKJ8q +ihFhWlovsva6GDoUorksU3vOwijdlGzTANQHJGFncgrRud9ATavpGS3KVxR73R3A +aBbu3Qw+QIfu8Qx5eBJp8CbMrpAmjfuq17STvqr5bC10Fnn4NegrnHOQG9JcK02+ +5Bn3+9X/n1mue7aohIdErLEiDMSqMOwFfrJeaH6YM1G4QkWyqGugtmHsWOUf0nlU +nkH1krvfw9rb6b+03c4A6GSeHnbX5ufFDSf5gaR6Wy7c0jBnoxVbtBLH2zXlrd0k +iRQG7C6XZzGMS7hb7GL7+bkRy9kWjmDL7z7Fp+EgzKhNmzuWII3E9X9va33HoQ/Q +UdK3JVToxRQg6XRKOxL9+U/+8i6U8lxObLWkWh2cypZqbz5qJxa+2u5JYO/KEoHZ +G963UX7XWezR98vZuTc1XHGZtBDMrjjDd7Kmb4/i/xBPeWwseeGtzFy9z2pnEnkL +uKE4C8wUNpzUUlsn4LneZXObIoErE7FqAAlVFujVe7iaJBmXoUXZR36drbfiaODK +vwAGyrYHaOlR +-----END CERTIFICATE REQUEST----- diff --git a/tests/assets/client-certificates/client/trusted/key.pem b/tests/assets/client-certificates/client/trusted/key.pem new file mode 100644 index 00000000..d60201e5 --- /dev/null +++ b/tests/assets/client-certificates/client/trusted/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +Y+eu85cike5J4vnz8uG04yt7rXjIrUav +-----END PRIVATE KEY----- diff --git a/tests/assets/client-certificates/server/server_cert.pem b/tests/assets/client-certificates/server/server_cert.pem new file mode 100644 index 00000000..52d8f531 --- /dev/null +++ b/tests/assets/client-certificates/server/server_cert.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFdTCCA12gAwIBAgIUNPWupe2xcu8YYG1ozoqk9viqDJswDQYJKoZIhvcNAQEL +BQAwNjESMBAGA1UEAwwJbG9jYWxob3N0MSAwHgYDVQQKDBdDbGllbnQgQ2VydGlm +aWNhdGUgRGVtbzAeFw0yNDA3MTkxMjQ3MzNaFw0yNTA3MTkxMjQ3MzNaMDYxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEgMB4GA1UECgwXQ2xpZW50IENlcnRpZmljYXRlIERl +bW8wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC+K5JWhlfvI47ZL/Az +L0xnOl+cMelr2BqH+7XS8187SbvluhFfFkq/7V7rwgsHI64sn8pgRCOnqKWV6jtb +651dGzn7Nby6InmyOQzF4VwfSVWQ6BYXgXuryS9Gm0gi8sOL1Ji/jV49n1gzLyIx +LNhd7NG2DCCedTHJnxyz4xq8MWhI/qI85iWJqcHhxkDb8wtH1Vd6nd/ZRVDbjgTv +PH3EDK7JqmnYG9+x4Jz0yEhvV7jL3gNu2mIyttvm7oRna9oHgaKFUJt4BCfPbT5U +3ipvcq29hdD5/5QIDzTWcExTnklolg5xpFext1+3KPSppESxcfBBNoL3h1B8ZcZa +lEMC/IoFUIDJQj5gmSn4okwMWIxgf+AL0609MKEqQ2FavOsvBmhHcQsqLk4MO/v0 +NGFv1/xGe4tUkX4han6ykf1+sqzupJT5qnUONmvghb2SpIt83o4j4KHVzZwk8JK0 +N6hN7JEjXQwSKCh3b0FFg+kPAe12d6BBcsNzEYmt2C1KNPbXMX84zIkgPN01XMg6 +kdCdjP6DH7CK+brW9qQufOqYpd3eNhJyeBm+oP3PhnhEiMTIO8X2GdSN5Rxozgxl +VIj/QWhLV64r5AqPr/Vpd1vcsxrg3aS5CASmoWQmTPuhEZptRtrkPkGw7k9NPZ34 +lnRenvKJ9e3DXhXRMqeYUY6wjwIDAQABo3sweTAdBgNVHQ4EFgQUEHtrxWCk96Eh +r60E0HBuwLk2i+IwHwYDVR0jBBgwFoAUEHtrxWCk96Ehr60E0HBuwLk2i+IwDwYD +VR0TAQH/BAUwAwEB/zAmBgNVHREEHzAdgglsb2NhbGhvc3SCEGxvY2FsLnBsYXl3 +cmlnaHQwDQYJKoZIhvcNAQELBQADggIBALP4kOAP21ZusbEH89VkZT3MkGlZuDQP +LyTYdLzT3EzN//2+lBDmJfpIPLL/K3sNEVSzNppa6tcCXiVNes/xJM7tHRhTOJ31 +HinSsib2r6DZ6SitQJWmD5FoAdkp9qdG8mA/5vOiwiVKKFV2/Z3i+3iUI/ZnEhUq +uUA1I3TI5LAQzgWLwYu1jSEM1EbH6uQiZ8AmXLVO4GQnVQdbyarWHxIy+zsg+MJN +fxIG/phDpkt1mI3SkAdpWRWjCKESQhrIcRUtu5eVk0lho6ttHODXF8bM7iWLoRc7 +rpcllI4HXHoXQqQkZHRa7KwTf0YVwwQbXTecZONWXwE9Ej5R5IcZzja5FWCSstsb +ULNW0JVxGBE7j5aOjxasYAbRexDmlfEdLvnp6bctZuvMvuBxrB+x5HSEZl6bVnbC +nvtoslylQJM1bwlZdCqJm04JXe1787HDBef2gABv27BjvG/zn89L5ipogZCrGpl6 +P9qs0eSERHuSrm3eHUVgXSQ1nbvOpk7RPFbsbp/npc1NbEDBdAMoXhLP9A+ytxLq +TF+w08nfCF6yJJ3jTkvABo10UH6zcPnfH3Ys7JYsHRbcloMfn+mc88KrTaCO+VZx +qjhFcz+zDu/AbtJkDJtxX2X7jNL0pzWS+9H8jFTrd3ta8XrJiSFq2VMxEU6R0IHk +2Ct10prMWB/3 +-----END CERTIFICATE----- diff --git a/tests/assets/client-certificates/server/server_key.pem b/tests/assets/client-certificates/server/server_key.pem new file mode 100644 index 00000000..ff6a3fc1 --- /dev/null +++ b/tests/assets/client-certificates/server/server_key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +8ynLaTs3oV3BjQya9pAUyzIX5L67 +-----END PRIVATE KEY----- diff --git a/tests/binding_test.go b/tests/binding_test.go index cb65c3b3..e090a8fb 100644 --- a/tests/binding_test.go +++ b/tests/binding_test.go @@ -80,7 +80,7 @@ func TestBrowserContextExposeBindingPanic(t *testing.T) { innerError := result.(map[string]interface{}) require.Equal(t, innerError["message"], "WOOF WOOF") stack := strings.Split(innerError["stack"].(string), "\n") - require.Contains(t, stack[3], "binding_test.go") + require.Contains(t, stack[4], "binding_test.go") } func TestBrowserContextExposeBindingHandleShouldWork(t *testing.T) { @@ -123,7 +123,7 @@ func TestPageExposeBindingPanic(t *testing.T) { innerError := result.(map[string]interface{}) require.Equal(t, innerError["message"], "WOOF WOOF") stack := strings.Split(innerError["stack"].(string), "\n") - require.Contains(t, stack[3], "binding_test.go") + require.Contains(t, stack[4], "binding_test.go") } func TestPageBindingsNoRace(t *testing.T) { diff --git a/tests/browser_context_client_certificates_test.go b/tests/browser_context_client_certificates_test.go new file mode 100644 index 00000000..8c9b0af8 --- /dev/null +++ b/tests/browser_context_client_certificates_test.go @@ -0,0 +1,206 @@ +package playwright_test + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "net/http" + "net/http/httptest" + "os" + "runtime" + "strings" + "testing" + + "github.com/playwright-community/playwright-go" + "github.com/stretchr/testify/require" +) + +func NewTLSServerRequireClientCert(t *testing.T) *httptest.Server { + t.Helper() + certPath := Asset("client-certificates/server/server_cert.pem") + keyPath := Asset("client-certificates/server/server_key.pem") + cert, err := tls.LoadX509KeyPair(certPath, keyPath) + require.NoError(t, err) + ca, err := os.ReadFile(Asset("client-certificates/server/server_cert.pem")) + require.NoError(t, err) + caPool := x509.NewCertPool() + ok := caPool.AppendCertsFromPEM(ca) + require.True(t, ok) + + ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + body := []byte(fmt.Sprintf(`
Hello %s, your certificate was issued by %s!
`, + r.TLS.PeerCertificates[0].Subject.CommonName, r.TLS.PeerCertificates[0].Issuer.CommonName)) + _, err := w.Write(body) + require.NoError(t, err) + })) + // ts.EnableHTTP2 = true + ts.TLS = &tls.Config{ + ClientAuth: tls.RequireAndVerifyClientCert, // Uses the go standard client certificate verification method + Certificates: []tls.Certificate{cert}, + ClientCAs: caPool, + } + ts.StartTLS() + return ts +} + +func TestClientCerts(t *testing.T) { + if isWebKit && runtime.GOOS == "darwin" { + t.Skip("WebKit does not proxy localhost on macOS") + } + tlsServer := NewTLSServerRequireClientCert(t) + defer tlsServer.Close() + + t.Run("should throw with untrusted client certs", func(t *testing.T) { + BeforeEach(t) + + request, err := pw.Request.NewContext(playwright.APIRequestNewContextOptions{ + IgnoreHttpsErrors: playwright.Bool(true), // TODO: Remove this once we can pass a custom CA. + ClientCertificates: []playwright.ClientCertificate{ + { + Origin: tlsServer.URL, + CertPath: playwright.String(Asset("client-certificates/client/self-signed/cert.pem")), + KeyPath: playwright.String(Asset("client-certificates/client/self-signed/key.pem")), + }, + }, + }) + require.NoError(t, err) + _, err = request.Get(tlsServer.URL) + require.Error(t, err) + require.Regexp(t, `alert (unknown ca|bad certificate)`, err.Error()) // go v1.19-1.20 fails with "bad certificate" + + require.NoError(t, request.Dispose()) + }) + + t.Run("should work with new context", func(t *testing.T) { + BeforeEach(t, playwright.BrowserNewContextOptions{ + IgnoreHttpsErrors: playwright.Bool(true), // TODO: Remove this once we can pass a custom CA. + ClientCertificates: []playwright.ClientCertificate{ + { + Origin: tlsServer.URL, + CertPath: playwright.String(Asset("client-certificates/client/trusted/cert.pem")), + KeyPath: playwright.String(Asset("client-certificates/client/trusted/key.pem")), + }, + }, + }) + + resp, err := page.Goto(strings.Replace(tlsServer.URL, "127.0.0.1", "localhost", 1)) + if tlsServer.EnableHTTP2 { + require.ErrorContains(t, err, "net::ERR_CONNECTION_CLOSED") + } else { + require.NoError(t, err) + require.False(t, resp.Ok()) // status code 503, client didn't provide a certificate due to origin mismatch + } + + _, err = page.Goto(tlsServer.URL) + require.NoError(t, err) + content, err := page.GetByTestId("message").TextContent() + require.NoError(t, err) + require.Equal(t, "Hello Alice, your certificate was issued by localhost!", content) + }) + + t.Run("should work with new persistent context", func(t *testing.T) { + BeforeEach(t) + + context2, err := browserType.LaunchPersistentContext( + t.TempDir(), + playwright.BrowserTypeLaunchPersistentContextOptions{ + IgnoreHttpsErrors: playwright.Bool(true), // TODO: Remove this once we can pass a custom CA. + ClientCertificates: []playwright.ClientCertificate{ + { + Origin: tlsServer.URL, + CertPath: playwright.String(Asset("client-certificates/client/trusted/cert.pem")), + KeyPath: playwright.String(Asset("client-certificates/client/trusted/key.pem")), + }, + }, + }) + require.NoError(t, err) + defer context2.Close() + page2, err := context2.NewPage() + require.NoError(t, err) + + resp, err := page2.Goto(strings.Replace(tlsServer.URL, "127.0.0.1", "localhost", 1)) + if tlsServer.EnableHTTP2 { + require.ErrorContains(t, err, "net::ERR_CONNECTION_CLOSED") + } else { + require.NoError(t, err) + require.False(t, resp.Ok()) // status code 503, client didn't provide a certificate due to origin mismatch + } + + _, err = page2.Goto(tlsServer.URL) + require.NoError(t, err) + content, err := page2.GetByTestId("message").TextContent() + require.NoError(t, err) + require.Equal(t, "Hello Alice, your certificate was issued by localhost!", content) + }) + + t.Run("should work with global apirequestcontext", func(t *testing.T) { + BeforeEach(t) + + request, err := pw.Request.NewContext(playwright.APIRequestNewContextOptions{ + IgnoreHttpsErrors: playwright.Bool(true), // TODO: Remove this once we can pass a custom CA. + ClientCertificates: []playwright.ClientCertificate{ + { + Origin: tlsServer.URL, + CertPath: playwright.String(Asset("client-certificates/client/trusted/cert.pem")), + KeyPath: playwright.String(Asset("client-certificates/client/trusted/key.pem")), + }, + }, + }) + require.NoError(t, err) + resp, err := request.Get(tlsServer.URL) + require.NoError(t, err) + require.True(t, resp.Ok()) + + body, err := resp.Body() + require.NoError(t, err) + require.Contains(t, string(body), "Hello Alice, your certificate was issued by localhost!") + require.NoError(t, request.Dispose()) + }) + + t.Run("should work with pfx", func(t *testing.T) { + BeforeEach(t) + + request, err := pw.Request.NewContext(playwright.APIRequestNewContextOptions{ + IgnoreHttpsErrors: playwright.Bool(true), // TODO: Remove this once we can pass a custom CA. + ClientCertificates: []playwright.ClientCertificate{ + { + Origin: tlsServer.URL, + PfxPath: playwright.String(Asset("client-certificates/client/trusted/cert.pfx")), + Passphrase: playwright.String("secure"), + }, + }, + }) + require.NoError(t, err) + resp, err := request.Get(tlsServer.URL) + require.NoError(t, err) + require.Equal(t, 200, resp.Status()) + body, err := resp.Body() + require.NoError(t, err) + require.Contains(t, string(body), "Hello Alice, your certificate was issued by localhost!") + require.NoError(t, request.Dispose()) + }) + + t.Run("should pass with matching certificates when passing as content", func(t *testing.T) { + certContent, err := os.ReadFile(Asset("client-certificates/client/trusted/cert.pem")) + require.NoError(t, err) + keyContent, err := os.ReadFile(Asset("client-certificates/client/trusted/key.pem")) + require.NoError(t, err) + + BeforeEach(t, playwright.BrowserNewContextOptions{ + IgnoreHttpsErrors: playwright.Bool(true), // TODO: Remove this once we can pass a custom CA. + ClientCertificates: []playwright.ClientCertificate{ + { + Origin: tlsServer.URL, + Cert: certContent, + Key: keyContent, + }, + }, + }) + + _, err = page.Goto(tlsServer.URL) + require.NoError(t, err) + content, err := page.GetByTestId("message").TextContent() + require.NoError(t, err) + require.Equal(t, "Hello Alice, your certificate was issued by localhost!", content) + }) +} diff --git a/tests/browser_context_test.go b/tests/browser_context_test.go index f9993cec..f0d459b1 100644 --- a/tests/browser_context_test.go +++ b/tests/browser_context_test.go @@ -741,3 +741,27 @@ func expectPageCookies(t *testing.T, cookie string) { require.NoError(t, err) require.Equal(t, cookie, ret) } + +func TestBrowserContextShouldRetryECONNRESET(t *testing.T) { + BeforeEach(t) + + requestCount := atomic.Int32{} + server.SetRoute("/test", func(w http.ResponseWriter, r *http.Request) { + if requestCount.Add(1) <= 3 { + server.CloseClientConnections() + return + } + w.Header().Add("Content-Type", "text/plain") + _, _ = w.Write([]byte("Hello!")) + }) + + response, err := context.Request().Fetch(server.PREFIX+"/test", playwright.APIRequestContextFetchOptions{ + MaxRetries: playwright.Int(3), + }) + require.NoError(t, err) + require.Equal(t, 200, response.Status()) + body, err := response.Body() + require.NoError(t, err) + require.Equal(t, []byte("Hello!"), body) + require.Equal(t, int32(4), requestCount.Load()) +} diff --git a/tests/fetch_test.go b/tests/fetch_test.go index dd6ace3d..710427d4 100644 --- a/tests/fetch_test.go +++ b/tests/fetch_test.go @@ -9,6 +9,7 @@ import ( "path/filepath" "strings" "sync" + "sync/atomic" "testing" "time" @@ -530,3 +531,30 @@ func TestSupportHttpCredentialsSendImmediatelyForBrowserNewPage(t *testing.T) { require.NoError(t, page1.Close()) } + +func TestFetchShouldRetryECONNRESET(t *testing.T) { + BeforeEach(t) + + requestCount := atomic.Int32{} + server.SetRoute("/test", func(w http.ResponseWriter, r *http.Request) { + if requestCount.Add(1) <= 3 { + server.CloseClientConnections() + return + } + w.Header().Add("Content-Type", "text/plain") + _, _ = w.Write([]byte("Hello!")) + }) + + request, err := pw.Request.NewContext() + require.NoError(t, err) + response, err := request.Get(server.PREFIX+"/test", playwright.APIRequestContextGetOptions{ + MaxRetries: playwright.Int(3), + }) + require.NoError(t, err) + require.Equal(t, 200, response.Status()) + body, err := response.Body() + require.NoError(t, err) + require.Equal(t, []byte("Hello!"), body) + require.Equal(t, int32(4), requestCount.Load()) + require.NoError(t, request.Dispose()) +} diff --git a/tests/js_handle_test.go b/tests/js_handle_test.go index ef431843..8590544d 100644 --- a/tests/js_handle_test.go +++ b/tests/js_handle_test.go @@ -1,12 +1,14 @@ package playwright_test import ( + "errors" "math" "math/big" "net/url" "testing" "time" + "github.com/playwright-community/playwright-go" "github.com/stretchr/testify/require" ) @@ -311,9 +313,35 @@ func TestEvaluate(t *testing.T) { }) t.Run("evaluate exception", func(t *testing.T) { - val, err := page.Evaluate(`new Error("error message")`) + val, err := page.Evaluate(`() => { + function innerFunction() { + const e = new Error('error message'); + e.name = 'foobar'; + return e; + } + return innerFunction(); + }`) + require.NoError(t, err) + var e *playwright.Error + require.True(t, errors.As(val.(error), &e)) + require.Equal(t, "foobar", e.Name) + require.Equal(t, "error message", e.Message) + require.Contains(t, e.Stack, "innerFunction") + }) + + t.Run("pass exception argument", func(t *testing.T) { + eee := &playwright.Error{ + Name: "foobar", + Message: "error message", + Stack: "test stack", + } + val, err := page.Evaluate(`e => { + return { message: e.message, name: e.name, stack: e.stack }; + }`, eee) require.NoError(t, err) - require.Contains(t, val, "Error: error message") + require.Equal(t, "foobar", val.(map[string]interface{})["name"]) + require.Equal(t, "error message", val.(map[string]interface{})["message"]) + require.Contains(t, val.(map[string]interface{})["stack"], "test stack") }) t.Run("evaluate date", func(t *testing.T) { diff --git a/tests/utils_test.go b/tests/utils_test.go index 2b69a31c..9e3e4e08 100644 --- a/tests/utils_test.go +++ b/tests/utils_test.go @@ -3,6 +3,7 @@ package playwright_test import ( "archive/zip" "bytes" + "crypto/tls" "errors" "fmt" "io" @@ -75,6 +76,14 @@ func (t *testServer) AfterEach() { t.requestSubscriberes = make(map[string][]chan *http.Request) } +func (t *testServer) CloseClientConnections() { + t.testServer.CloseClientConnections() +} + +func (t *testServer) SetTLSConfig(config *tls.Config) { + t.testServer.TLS = config +} + func (t *testServer) serveHTTP(w http.ResponseWriter, r *http.Request) { t.Lock() defer t.Unlock() diff --git a/tracing.go b/tracing.go index d12371bc..7386fc36 100644 --- a/tracing.go +++ b/tracing.go @@ -23,34 +23,21 @@ func (t *tracingImpl) Start(options ...TracingStartOptions) error { if _, err := t.channel.Send("tracingStart", options); err != nil { return "", err } - - result, err := t.channel.Send("tracingStartChunk", chunkOption) - if err != nil { - return nil, err - } - name, ok := result.(string) - if !ok { - name = "" - } - return nil, t.startCollectingStacks(name) + return t.channel.Send("tracingStartChunk", chunkOption) } - _, err := t.connection.WrapAPICall(innerStart, true) - return err + name, err := t.connection.WrapAPICall(innerStart, true) + if err != nil { + return err + } + return t.startCollectingStacks(name.(string)) } func (t *tracingImpl) StartChunk(options ...TracingStartChunkOptions) error { - _, err := t.connection.WrapAPICall(func() (interface{}, error) { - result, err := t.channel.Send("tracingStartChunk", options) - if err != nil { - return nil, err - } - name, ok := result.(string) - if !ok { - name = "" - } - return nil, t.startCollectingStacks(name) - }, true) - return err + name, err := t.channel.Send("tracingStartChunk", options) + if err != nil { + return err + } + return t.startCollectingStacks(name.(string)) } func (t *tracingImpl) StopChunk(path ...string) error {