From 21654ccac0b7c8f6b87bd1a39f077f9abfb0d556 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Sat, 12 Mar 2022 14:34:36 +0100 Subject: [PATCH] chore: roll to 1.20.0-beta-1647057403000 (#256) --- .github/workflows/build.yml | 11 +- .github/workflows/verify_type_generation.yml | 4 +- README.md | 6 +- browser_context.go | 2 +- connection.go | 3 + examples/download/main.go | 2 +- examples/mobile-and-geolocation/main.go | 11 +- examples/parallel-scraping/main.go | 2 +- generated-enums.go | 37 +++++ generated-interfaces.go | 37 +++-- generated-structs.go | 150 ++++++++++++++++- objectFactory.go | 6 + patches/main.patch | 152 ++++++------------ playwright | 2 +- run.go | 5 +- scripts/apply-patch.sh | 5 +- scripts/data/interfaces.json | 2 +- scripts/generate-api.sh | 2 + tests/assets/css-transition.html | 21 +++ tests/assets/empty-standard-mode.html | 1 + tests/assets/error.html | 2 +- tests/assets/example.mp3 | Bin 0 -> 48465 bytes tests/assets/input/drag-n-drop-manual.html | 44 +++++ tests/assets/modernizr.html | 5 + .../assets/modernizr/mobile-safari-14-1.json | 5 +- tests/assets/modernizr/safari-14-1.json | 5 +- tests/assets/mui.html | 13 ++ tests/assets/rotate-pseudo.html | 32 ++++ tests/assets/rotate-z-shadow-dom.html | 31 ++++ tests/assets/rotate-z.html | 2 +- tests/assets/web-animation.html | 23 +++ tests/assets/webfont/README.md | 3 + tests/assets/webfont/iconfont.svg | 14 ++ tests/assets/webfont/iconfont.woff2 | Bin 0 -> 2656 bytes tests/assets/webfont/webfont.html | 18 +++ tests/remote_server_test.go | 2 +- tracing.go | 76 +++++---- 37 files changed, 550 insertions(+), 186 deletions(-) create mode 100644 tests/assets/css-transition.html create mode 100644 tests/assets/empty-standard-mode.html create mode 100644 tests/assets/example.mp3 create mode 100644 tests/assets/input/drag-n-drop-manual.html create mode 100644 tests/assets/mui.html create mode 100644 tests/assets/rotate-pseudo.html create mode 100644 tests/assets/rotate-z-shadow-dom.html create mode 100644 tests/assets/web-animation.html create mode 100644 tests/assets/webfont/README.md create mode 100644 tests/assets/webfont/iconfont.svg create mode 100644 tests/assets/webfont/iconfont.woff2 create mode 100644 tests/assets/webfont/webfont.html diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 89d8ba8d..3dbbe133 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,7 +33,7 @@ jobs: id: go - run: | go install ./... - playwright install-deps + playwright install --with-deps ${{ matrix.browser }} - name: Test env: BROWSER: ${{ matrix.browser }} @@ -83,6 +83,11 @@ jobs: id: go - run: | go install ./... - playwright install-deps + playwright install --with-deps - name: Run examples - run: xvfb-run bash -c "for dir in examples/*; do go run \$dir/main.go; done" + run: | + for dir in examples/*; do + echo "::group::go run $dir/main.go" + xvfb-run go run $dir/main.go + echo "::endgroup::" + done diff --git a/.github/workflows/verify_type_generation.yml b/.github/workflows/verify_type_generation.yml index a0e52e32..f952da7c 100644 --- a/.github/workflows/verify_type_generation.yml +++ b/.github/workflows/verify_type_generation.yml @@ -17,7 +17,9 @@ jobs: with: go-version: ^1.16.1 - name: Install Browsers - run: go run scripts/install-browsers/main.go + run: | + go install ./... + playwright install --with-deps - name: Regenerate APIs run: | git config --global user.email "no-reply@github.com" diff --git a/README.md b/README.md index dacfc5c0..a8007a8a 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-97.0.4666.0-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-93.0-blue.svg?logo=mozilla-firefox)](https://www.mozilla.org/en-US/firefox/new/) [![WebKit version](https://img.shields.io/badge/webkit-15.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-101.0.4929.0-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-97.0.1-blue.svg?logo=mozilla-firefox)](https://www.mozilla.org/en-US/firefox/new/) [![WebKit version](https://img.shields.io/badge/webkit-15.4-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 97.0.4666.0 | ✅ | ✅ | ✅ | +| Chromium 101.0.4929.0 | ✅ | ✅ | ✅ | | WebKit 15.4 | ✅ | ✅ | ✅ | -| Firefox 93.0 | ✅ | ✅ | ✅ | +| Firefox 97.0.1 | ✅ | ✅ | ✅ | Headless execution is supported for all the browsers on all platforms. diff --git a/browser_context.go b/browser_context.go index cc2a8858..355d9ea3 100644 --- a/browser_context.go +++ b/browser_context.go @@ -363,7 +363,7 @@ func newBrowserContext(parent *channelOwner, objectType string, guid string, ini bindings: make(map[string]BindingCallFunction), } bt.createChannelOwner(bt, parent, objectType, guid, initializer) - bt.tracing = newTracing(bt) + bt.tracing = fromChannel(initializer["tracing"]).(*tracingImpl) bt.channel.On("bindingCall", func(params map[string]interface{}) { bt.onBinding(fromChannel(params["binding"]).(*bindingCallImpl)) }) diff --git a/connection.go b/connection.go index 94d9e573..b38e3b01 100644 --- a/connection.go +++ b/connection.go @@ -66,6 +66,9 @@ func (c *connection) Dispatch(msg *message) { ) return } + if object == nil { + return + } if method == "__dispose__" { object.dispose() return diff --git a/examples/download/main.go b/examples/download/main.go index 0a9a11aa..8710bfbd 100644 --- a/examples/download/main.go +++ b/examples/download/main.go @@ -23,7 +23,7 @@ func main() { pw, err := playwright.Run() assertErrorToNilf("could not launch playwright: %w", err) browser, err := pw.Chromium.Launch(playwright.BrowserTypeLaunchOptions{ - Headless: playwright.Bool(false), + Headless: playwright.Bool(true), }) assertErrorToNilf("could not launch Chromium: %w", err) context, err := browser.NewContext() diff --git a/examples/mobile-and-geolocation/main.go b/examples/mobile-and-geolocation/main.go index 9add2eaa..cdfa222d 100644 --- a/examples/mobile-and-geolocation/main.go +++ b/examples/mobile-and-geolocation/main.go @@ -5,7 +5,6 @@ package main import ( "log" - "regexp" "github.com/playwright-community/playwright-go" ) @@ -15,13 +14,12 @@ func main() { if err != nil { log.Fatalf("could not start playwright: %v", err) } - browser, err := pw.WebKit.Launch() + browser, err := pw.Chromium.Launch() if err != nil { log.Fatalf("could not launch browser: %v", err) } - device := pw.Devices["iPhone 11 Pro"] + device := pw.Devices["Pixel 5"] context, err := browser.NewContext(playwright.BrowserNewContextOptions{ - Locale: playwright.String("en-US"), Geolocation: &playwright.BrowserNewContextOptionsGeolocation{ Longitude: playwright.Float(12.492507), Latitude: playwright.Float(41.889938), @@ -40,13 +38,12 @@ func main() { if err != nil { log.Fatalf("could not create page: %v", err) } - if _, err = page.Goto("https://maps.google.com"); err != nil { + if _, err = page.Goto("https://www.openstreetmap.org"); err != nil { log.Fatalf("could not goto: %v", err) } - if err = page.Click(".ml-my-location-fab button"); err != nil { + if err = page.Click("a[data-original-title='Show My Location']"); err != nil { log.Fatalf("could not click on location: %v", err) } - page.WaitForRequest(regexp.MustCompile(".*preview/pwa")) if _, err = page.Screenshot(playwright.PageScreenshotOptions{ Path: playwright.String("colosseum-iphone.png"), }); err != nil { diff --git a/examples/parallel-scraping/main.go b/examples/parallel-scraping/main.go index 42a79355..f582a087 100644 --- a/examples/parallel-scraping/main.go +++ b/examples/parallel-scraping/main.go @@ -32,7 +32,7 @@ func worker(id int, jobs chan job, results chan<- bool, browser playwright.Brows results <- true continue } - fmt.Printf("starting (%d): %s\n", jobPayload.Try, jobPayload.URL) + fmt.Printf("starting (try: %d): %s\n", jobPayload.Try, jobPayload.URL) context, err := browser.NewContext(playwright.BrowserNewContextOptions{ UserAgent: playwright.String("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36"), diff --git a/generated-enums.go b/generated-enums.go index bbbc215e..ff825e6f 100644 --- a/generated-enums.go +++ b/generated-enums.go @@ -77,6 +77,42 @@ var ( KeyboardModifierShift = getKeyboardModifier("Shift") ) +func getScreenshotAnimations(in string) *ScreenshotAnimations { + v := ScreenshotAnimations(in) + return &v +} + +type ScreenshotAnimations string + +var ( + ScreenshotAnimationsDisabled *ScreenshotAnimations = getScreenshotAnimations("disabled") + ScreenshotAnimationsAllow = getScreenshotAnimations("allow") +) + +func getScreenshotFonts(in string) *ScreenshotFonts { + v := ScreenshotFonts(in) + return &v +} + +type ScreenshotFonts string + +var ( + ScreenshotFontsReady *ScreenshotFonts = getScreenshotFonts("ready") + ScreenshotFontsNowait = getScreenshotFonts("nowait") +) + +func getScreenshotSize(in string) *ScreenshotSize { + v := ScreenshotSize(in) + return &v +} + +type ScreenshotSize string + +var ( + ScreenshotSizeCss *ScreenshotSize = getScreenshotSize("css") + ScreenshotSizeDevice = getScreenshotSize("device") +) + func getScreenshotType(in string) *ScreenshotType { v := ScreenshotType(in) return &v @@ -130,6 +166,7 @@ var ( WaitUntilStateLoad *WaitUntilState = getWaitUntilState("load") WaitUntilStateDomcontentloaded = getWaitUntilState("domcontentloaded") WaitUntilStateNetworkidle = getWaitUntilState("networkidle") + WaitUntilStateCommit = getWaitUntilState("commit") ) func getLoadState(in string) *LoadState { diff --git a/generated-interfaces.go b/generated-interfaces.go index 43f0d707..6b52e48f 100644 --- a/generated-interfaces.go +++ b/generated-interfaces.go @@ -169,7 +169,7 @@ type Tracing interface { // Start a new trace chunk. If you'd like to record multiple traces on the same `BrowserContext`, use // Tracing.start`] once, and then create multiple trace chunks with [`method: Tracing.startChunk() and // Tracing.stopChunk(). - StartChunk() error + StartChunk(options ...TracingStartChunkOptions) error // Stop the trace chunk. See Tracing.startChunk() for more details about multiple trace chunks. StopChunk(options ...TracingStopChunkOptions) error } @@ -246,9 +246,6 @@ type Dialog interface { // `Download` objects are dispatched by page via the [`event: Page.download`] event. // All the downloaded files belonging to the browser context are deleted when the browser context is closed. // Download event is emitted once the download starts. Download path becomes available once download completes: -// > NOTE: Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the -// downloaded content. If `acceptDownloads` is not set, download events are emitted, but the actual download is not -// performed and user has no access to the downloaded files. type Download interface { // Deletes the downloaded file. Will wait for the download to finish if necessary. Delete() error @@ -279,12 +276,11 @@ type Download interface { // ElementHandle represents an in-page DOM element. ElementHandles can be created with the Page.querySelector() // method. +// > NOTE: The use of ElementHandle is discouraged, use `Locator` objects and web-first assertions instead. // ElementHandle prevents DOM element from garbage collection unless the handle is disposed with // JSHandle.dispose(). ElementHandles are auto-disposed when their origin frame gets navigated. // ElementHandle instances can be used as an argument in Page.evalOnSelector`] and [`method: Page.evaluate() // methods. -// > NOTE: In most cases, you would want to use the `Locator` object instead. You should only use `ElementHandle` if you -// want to retain a handle to a particular DOM Node that you intend to pass into Page.evaluate() as an argument. // The difference between the `Locator` and ElementHandle is that the ElementHandle points to a particular element, while // `Locator` captures the logic of how to retrieve an element. // In the example below, handle points to a particular DOM element on page. If that element changes text or is used by @@ -645,6 +641,8 @@ type Frame interface { // `JSHandle` instances can be passed as an argument to the Frame.evaluateHandle(): EvaluateHandle(expression string, options ...interface{}) (JSHandle, error) // Returns the return value of `expression`. + // > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky + // tests. Use Locator.evaluate(), other `Locator` helper methods or web-first assertions instead. // The method finds an element matching the specified selector within the frame and passes it as a first argument to // `expression`. See [Working with selectors](./selectors.md) for more details. If no elements match the selector, the // method throws an error. @@ -653,6 +651,8 @@ type Frame interface { // Examples: EvalOnSelector(selector string, expression string, options ...interface{}) (interface{}, error) // Returns the return value of `expression`. + // > NOTE: In most cases, Locator.evaluateAll(), other `Locator` helper methods and web-first assertions do a + // better job. // The method finds all elements matching the specified selector within the frame and passes an array of matched elements // as a first argument to `expression`. See [Working with selectors](./selectors.md) for more details. // If `expression` returns a [Promise], then Frame.evalOnSelectorAll() would wait for the promise to resolve and @@ -745,10 +745,12 @@ type Frame interface { // modifier, modifier is pressed and being held while the subsequent key is being pressed. Press(selector, key string, options ...PagePressOptions) error // Returns the ElementHandle pointing to the frame element. + // > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects and web-first assertions instead. // The method finds an element matching the specified selector within the frame. See // [Working with selectors](./selectors.md) for more details. If no elements match the selector, returns `null`. QuerySelector(selector string) (ElementHandle, error) // Returns the ElementHandles pointing to the frame elements. + // > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects instead. // The method finds all elements matching the specified selector within the frame. See // [Working with selectors](./selectors.md) for more details. If no elements match the selector, returns empty array. QuerySelectorAll(selector string) ([]ElementHandle, error) @@ -821,6 +823,8 @@ type Frame interface { WaitForURL(url string, options ...FrameWaitForURLOptions) error // Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or // `detached`. + // > NOTE: Playwright automatically waits for element to be ready before performing an action. Using `Locator` objects and + // web-first assertions make the code wait-for-selector-free. // Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at // the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the // selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. @@ -1087,6 +1091,8 @@ type Page interface { // A string can also be passed in instead of a function: // `JSHandle` instances can be passed as an argument to the Page.evaluateHandle(): EvaluateHandle(expression string, options ...interface{}) (JSHandle, error) + // > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky + // tests. Use Locator.evaluate(), other `Locator` helper methods or web-first assertions instead. // The method finds an element matching the specified selector within the page and passes it as a first argument to // `expression`. If no elements match the selector, the method throws an error. Returns the value of `expression`. // If `expression` returns a [Promise], then Page.evalOnSelector() would wait for the promise to resolve and @@ -1094,6 +1100,8 @@ type Page interface { // Examples: // Shortcut for main frame's Frame.evalOnSelector(). EvalOnSelector(selector string, expression string, options ...interface{}) (interface{}, error) + // > NOTE: In most cases, Locator.evaluateAll(), other `Locator` helper methods and web-first assertions do a + // better job. // The method finds all elements matching the specified selector within the page and passes an array of matched elements as // a first argument to `expression`. Returns the result of `expression` invocation. // If `expression` returns a [Promise], then Page.evalOnSelectorAll() would wait for the promise to resolve and @@ -1236,16 +1244,18 @@ type Page interface { // Shortcuts such as `key: "Control+o"` or `key: "Control+Shift+T"` are supported as well. When specified with the // modifier, modifier is pressed and being held while the subsequent key is being pressed. Press(selector, key string, options ...PagePressOptions) error + // > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects and web-first assertions instead. // The method finds an element matching the specified selector within the page. If no elements match the selector, the - // return value resolves to `null`. To wait for an element on the page, use Page.waitForSelector(). + // return value resolves to `null`. To wait for an element on the page, use Locator.waitFor(). // Shortcut for main frame's Frame.querySelector(). QuerySelector(selector string) (ElementHandle, error) + // > NOTE: The use of `ElementHandle` is discouraged, use `Locator` objects and web-first assertions instead. // The method finds all elements matching the specified selector within the page. If no elements match the selector, the // return value resolves to `[]`. // Shortcut for main frame's Frame.querySelectorAll(). QuerySelectorAll(selector string) ([]ElementHandle, error) - // Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the - // last redirect. + // This method reloads the current page, in the same way as if the user had triggered a browser refresh. Returns the main + // resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect. Reload(options ...PageReloadOptions) (Response, error) // Routing provides the capability to modify network requests that are made by a page. // Once routing is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted. @@ -1298,9 +1308,10 @@ type Page interface { SetInputFiles(selector string, files []InputFile, options ...FrameSetInputFilesOptions) error // In the case of multiple pages in a single browser, each page can have its own viewport size. However, // Browser.newContext() allows to set viewport size (and more) for all pages in the context at once. - // `page.setViewportSize` will resize the page. A lot of websites don't expect phones to change size, so you should set the - // viewport size before navigating to the page. Page.setViewportSize() will also reset `screen` size, use - // Browser.newContext() with `screen` and `viewport` parameters if you need better control of these properties. + // Page.setViewportSize() will resize the page. A lot of websites don't expect phones to change size, so you + // should set the viewport size before navigating to the page. Page.setViewportSize() will also reset `screen` + // size, use Browser.newContext() with `screen` and `viewport` parameters if you need better control of these + // properties. SetViewportSize(width, height int) error // This method taps an element matching `selector` by performing the following steps: // 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM. @@ -1374,6 +1385,8 @@ type Page interface { WaitForResponse(url interface{}, options ...interface{}) Response // Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or // `detached`. + // > NOTE: Playwright automatically waits for element to be ready before performing an action. Using `Locator` objects and + // web-first assertions make the code wait-for-selector-free. // Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at // the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the // selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. diff --git a/generated-structs.go b/generated-structs.go index f4a021d6..ae7c2d52 100644 --- a/generated-structs.go +++ b/generated-structs.go @@ -1,8 +1,8 @@ package playwright type BrowserNewContextOptions struct { - // Whether to automatically download all the attachments. Defaults to `false` where - // all the downloads are canceled. + // Whether to automatically download all the attachments. Defaults to `true` where + // all the downloads are accepted. AcceptDownloads *bool `json:"acceptDownloads"` // When using Page.Goto(), Page.Route(), Page.WaitForURL(), Page.WaitForRequest(), // or Page.WaitForResponse() it takes the base URL in consideration by using the [`URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) @@ -10,6 +10,8 @@ type BrowserNewContextOptions struct { // baseURL: `http://localhost:3000` and navigating to `/bar.html` results in `http://localhost:3000/bar.html` // baseURL: `http://localhost:3000/foo/` and navigating to `./bar.html` results in // `http://localhost:3000/foo/bar.html` + // baseURL: `http://localhost:3000/foo` (without trailing slash) and navigating to + // `./bar.html` results in `http://localhost:3000/bar.html` BaseURL *string `json:"baseURL"` // Toggles bypassing page's Content-Security-Policy. BypassCSP *bool `json:"bypassCSP"` @@ -138,8 +140,8 @@ type BrowserViewport struct { Height *int `json:"height"` } type BrowserNewPageOptions struct { - // Whether to automatically download all the attachments. Defaults to `false` where - // all the downloads are canceled. + // Whether to automatically download all the attachments. Defaults to `true` where + // all the downloads are accepted. AcceptDownloads *bool `json:"acceptDownloads"` // When using Page.Goto(), Page.Route(), Page.WaitForURL(), Page.WaitForRequest(), // or Page.WaitForResponse() it takes the base URL in consideration by using the [`URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) @@ -147,6 +149,8 @@ type BrowserNewPageOptions struct { // baseURL: `http://localhost:3000` and navigating to `/bar.html` results in `http://localhost:3000/bar.html` // baseURL: `http://localhost:3000/foo/` and navigating to `./bar.html` results in // `http://localhost:3000/foo/bar.html` + // baseURL: `http://localhost:3000/foo` (without trailing slash) and navigating to + // `./bar.html` results in `http://localhost:3000/bar.html` BaseURL *string `json:"baseURL"` // Toggles bypassing page's Content-Security-Policy. BypassCSP *bool `json:"bypassCSP"` @@ -384,8 +388,8 @@ type BrowserTypeProxy struct { Password *string `json:"password"` } type BrowserTypeLaunchPersistentContextOptions struct { - // Whether to automatically download all the attachments. Defaults to `false` where - // all the downloads are canceled. + // Whether to automatically download all the attachments. Defaults to `true` where + // all the downloads are accepted. AcceptDownloads *bool `json:"acceptDownloads"` // Additional arguments to pass to the browser instance. The list of Chromium flags // can be found [here](http://peter.sh/experiments/chromium-command-line-switches/). @@ -396,6 +400,8 @@ type BrowserTypeLaunchPersistentContextOptions struct { // baseURL: `http://localhost:3000` and navigating to `/bar.html` results in `http://localhost:3000/bar.html` // baseURL: `http://localhost:3000/foo/` and navigating to `./bar.html` results in // `http://localhost:3000/foo/bar.html` + // baseURL: `http://localhost:3000/foo` (without trailing slash) and navigating to + // `./bar.html` results in `http://localhost:3000/bar.html` BaseURL *string `json:"baseURL"` // Toggles bypassing page's Content-Security-Policy. BypassCSP *bool `json:"bypassCSP"` @@ -694,6 +700,17 @@ type ElementHandlePressOptions struct { Timeout *float64 `json:"timeout"` } type ElementHandleScreenshotOptions struct { + // When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. + // Animations get different treatment depending on their duration: + // finite animations are fast-forwarded to completion, so they'll fire `transitionend` + // event. + // infinite animations are canceled to initial state, and then played over after the + // screenshot. + // Defaults to `"allow"` that leaves animations untouched. + Animations *ScreenshotAnimations `json:"animations"` + // When set to `"ready"`, screenshot will wait for [`document.fonts.ready`](https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/ready) + // promise to resolve in all frames. Defaults to `"nowait"`. + Fonts *ScreenshotFonts `json:"fonts"` // Hides default white background and allows capturing screenshots with transparency. // Not applicable to `jpeg` images. Defaults to `false`. OmitBackground *bool `json:"omitBackground"` @@ -703,6 +720,11 @@ type ElementHandleScreenshotOptions struct { Path *string `json:"path"` // The quality of the image, between 0-100. Not applicable to `png` images. Quality *int `json:"quality"` + // When set to `"css"`, screenshot will have a single pixel per each css pixel on the + // page. For high-dpi devices, this will keep screenshots small. Using `"device"` option + // will produce a single pixel per each device pixel, so screenhots of high-dpi devices + // will be twice as large or even larger. Defaults to `"device"`. + Size *ScreenshotSize `json:"size"` // Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. // The default value can be changed by using the BrowserContext.SetDefaultTimeout() // or Page.SetDefaultTimeout() methods. @@ -1081,6 +1103,8 @@ type FrameGotoOptions struct { // `'load'` - consider operation to be finished when the `load` event is fired. // `'networkidle'` - consider operation to be finished when there are no network connections // for at least `500` ms. + // `'commit'` - consider operation to be finished when network response is received + // and the document started loading. WaitUntil *WaitUntilState `json:"waitUntil"` } type FrameHoverOptions struct { @@ -1256,6 +1280,8 @@ type FrameSetContentOptions struct { // `'load'` - consider operation to be finished when the `load` event is fired. // `'networkidle'` - consider operation to be finished when there are no network connections // for at least `500` ms. + // `'commit'` - consider operation to be finished when network response is received + // and the document started loading. WaitUntil *WaitUntilState `json:"waitUntil"` } type FrameSetInputFilesOptions struct { @@ -1379,6 +1405,8 @@ type FrameWaitForNavigationOptions struct { // `'load'` - consider operation to be finished when the `load` event is fired. // `'networkidle'` - consider operation to be finished when there are no network connections // for at least `500` ms. + // `'commit'` - consider operation to be finished when network response is received + // and the document started loading. WaitUntil *WaitUntilState `json:"waitUntil"` } type FrameWaitForSelectorOptions struct { @@ -1411,6 +1439,8 @@ type FrameWaitForURLOptions struct { // `'load'` - consider operation to be finished when the `load` event is fired. // `'networkidle'` - consider operation to be finished when there are no network connections // for at least `500` ms. + // `'commit'` - consider operation to be finished when network response is received + // and the document started loading. WaitUntil *WaitUntilState `json:"waitUntil"` } type JSHandleEvaluateOptions struct { @@ -1535,6 +1565,37 @@ type LocatorDispatchEventOptions struct { // or Page.SetDefaultTimeout() methods. Timeout *float64 `json:"timeout"` } +type LocatorDragToOptions struct { + // Whether to bypass the [actionability](./actionability.md) checks. Defaults to `false`. + 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`. + 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. + SourcePosition *LocatorDragToOptionsSourcePosition `json:"sourcePosition"` + // Drops on the target 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. + TargetPosition *LocatorDragToOptionsTargetPosition `json:"targetPosition"` + // Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. + // The default value can be changed by using the BrowserContext.SetDefaultTimeout() + // or Page.SetDefaultTimeout() methods. + Timeout *float64 `json:"timeout"` + // When set, this method only performs the [actionability](./actionability.md) checks + // and skips the action. Defaults to `false`. Useful to wait until the element is ready + // for the action without performing it. + Trial *bool `json:"trial"` +} +type LocatorSourcePosition struct { + X *float64 `json:"x"` + Y *float64 `json:"y"` +} +type LocatorTargetPosition struct { + X *float64 `json:"x"` + Y *float64 `json:"y"` +} type LocatorElementHandleOptions struct { // Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. // The default value can be changed by using the BrowserContext.SetDefaultTimeout() @@ -1667,6 +1728,17 @@ type LocatorPressOptions struct { Timeout *float64 `json:"timeout"` } type LocatorScreenshotOptions struct { + // When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. + // Animations get different treatment depending on their duration: + // finite animations are fast-forwarded to completion, so they'll fire `transitionend` + // event. + // infinite animations are canceled to initial state, and then played over after the + // screenshot. + // Defaults to `"allow"` that leaves animations untouched. + Animations *ScreenshotAnimations `json:"animations"` + // When set to `"ready"`, screenshot will wait for [`document.fonts.ready`](https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/ready) + // promise to resolve in all frames. Defaults to `"nowait"`. + Fonts *ScreenshotFonts `json:"fonts"` // Hides default white background and allows capturing screenshots with transparency. // Not applicable to `jpeg` images. Defaults to `false`. OmitBackground *bool `json:"omitBackground"` @@ -1676,6 +1748,11 @@ type LocatorScreenshotOptions struct { Path *string `json:"path"` // The quality of the image, between 0-100. Not applicable to `png` images. Quality *int `json:"quality"` + // When set to `"css"`, screenshot will have a single pixel per each css pixel on the + // page. For high-dpi devices, this will keep screenshots small. Using `"device"` option + // will produce a single pixel per each device pixel, so screenhots of high-dpi devices + // will be twice as large or even larger. Defaults to `"device"`. + Size *ScreenshotSize `json:"size"` // Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. // The default value can be changed by using the BrowserContext.SetDefaultTimeout() // or Page.SetDefaultTimeout() methods. @@ -1819,6 +1896,19 @@ type LocatorWaitForOptions struct { // or Page.SetDefaultTimeout() methods. Timeout *float64 `json:"timeout"` } +type LocatorAssertionsToBeCheckedOptions struct { + Checked *bool `json:"checked"` +} +type LocatorAssertionsToContainTextOptions struct { + // Whether to use `element.innerText` instead of `element.textContent` when retrieving + // DOM node text. + UseInnerText *bool `json:"useInnerText"` +} +type LocatorAssertionsToHaveTextOptions struct { + // Whether to use `element.innerText` instead of `element.textContent` when retrieving + // DOM node text. + UseInnerText *bool `json:"useInnerText"` +} type MouseClickOptions struct { // Defaults to `left`. Button *MouseButton `json:"button"` @@ -2095,6 +2185,8 @@ type PageGoBackOptions struct { // `'load'` - consider operation to be finished when the `load` event is fired. // `'networkidle'` - consider operation to be finished when there are no network connections // for at least `500` ms. + // `'commit'` - consider operation to be finished when network response is received + // and the document started loading. WaitUntil *WaitUntilState `json:"waitUntil"` } type PageGoForwardOptions struct { @@ -2109,6 +2201,8 @@ type PageGoForwardOptions struct { // `'load'` - consider operation to be finished when the `load` event is fired. // `'networkidle'` - consider operation to be finished when there are no network connections // for at least `500` ms. + // `'commit'` - consider operation to be finished when network response is received + // and the document started loading. WaitUntil *WaitUntilState `json:"waitUntil"` } type PageGotoOptions struct { @@ -2126,6 +2220,8 @@ type PageGotoOptions struct { // `'load'` - consider operation to be finished when the `load` event is fired. // `'networkidle'` - consider operation to be finished when there are no network connections // for at least `500` ms. + // `'commit'` - consider operation to be finished when network response is received + // and the document started loading. WaitUntil *WaitUntilState `json:"waitUntil"` } type PageHoverOptions struct { @@ -2313,6 +2409,8 @@ type PageReloadOptions struct { // `'load'` - consider operation to be finished when the `load` event is fired. // `'networkidle'` - consider operation to be finished when there are no network connections // for at least `500` ms. + // `'commit'` - consider operation to be finished when network response is received + // and the document started loading. WaitUntil *WaitUntilState `json:"waitUntil"` } type PageRouteOptions struct { @@ -2320,9 +2418,20 @@ type PageRouteOptions struct { Times *int `json:"times"` } type PageScreenshotOptions struct { + // When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. + // Animations get different treatment depending on their duration: + // finite animations are fast-forwarded to completion, so they'll fire `transitionend` + // event. + // infinite animations are canceled to initial state, and then played over after the + // screenshot. + // Defaults to `"allow"` that leaves animations untouched. + Animations *ScreenshotAnimations `json:"animations"` // An object which specifies clipping of the resulting image. Should have the following // fields: Clip *PageScreenshotOptionsClip `json:"clip"` + // When set to `"ready"`, screenshot will wait for [`document.fonts.ready`](https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/ready) + // promise to resolve in all frames. Defaults to `"nowait"`. + Fonts *ScreenshotFonts `json:"fonts"` // When true, takes a screenshot of the full scrollable page, instead of the currently // visible viewport. Defaults to `false`. FullPage *bool `json:"fullPage"` @@ -2335,6 +2444,11 @@ type PageScreenshotOptions struct { Path *string `json:"path"` // The quality of the image, between 0-100. Not applicable to `png` images. Quality *int `json:"quality"` + // When set to `"css"`, screenshot will have a single pixel per each css pixel on the + // page. For high-dpi devices, this will keep screenshots small. Using `"device"` option + // will produce a single pixel per each device pixel, so screenhots of high-dpi devices + // will be twice as large or even larger. Defaults to `"device"`. + Size *ScreenshotSize `json:"size"` // Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. // The default value can be changed by using the BrowserContext.SetDefaultTimeout() // or Page.SetDefaultTimeout() methods. @@ -2403,6 +2517,8 @@ type PageSetContentOptions struct { // `'load'` - consider operation to be finished when the `load` event is fired. // `'networkidle'` - consider operation to be finished when there are no network connections // for at least `500` ms. + // `'commit'` - consider operation to be finished when network response is received + // and the document started loading. WaitUntil *WaitUntilState `json:"waitUntil"` } type PageSetInputFilesOptions struct { @@ -2538,6 +2654,8 @@ type PageWaitForNavigationOptions struct { // `'load'` - consider operation to be finished when the `load` event is fired. // `'networkidle'` - consider operation to be finished when there are no network connections // for at least `500` ms. + // `'commit'` - consider operation to be finished when network response is received + // and the document started loading. WaitUntil *WaitUntilState `json:"waitUntil"` } type PageWaitForRequestOptions struct { @@ -2582,6 +2700,8 @@ type PageWaitForURLOptions struct { // `'load'` - consider operation to be finished when the `load` event is fired. // `'networkidle'` - consider operation to be finished when there are no network connections // for at least `500` ms. + // `'commit'` - consider operation to be finished when network response is received + // and the document started loading. WaitUntil *WaitUntilState `json:"waitUntil"` } @@ -2735,8 +2855,16 @@ type TracingStartOptions struct { // Whether to capture screenshots during tracing. Screenshots are used to build a timeline // preview. Screenshots *bool `json:"screenshots"` - // Whether to capture DOM snapshot on every action. + // If this option is true tracing will + // capture DOM snapshot on every action + // record network activity Snapshots *bool `json:"snapshots"` + // Trace name to be shown in the Trace Viewer. + Title *string `json:"title"` +} +type TracingStartChunkOptions struct { + // Trace name to be shown in the Trace Viewer. + Title *string `json:"title"` } type TracingStopOptions struct { // Export trace into the file with the given path. @@ -3065,6 +3193,14 @@ type LocatorDblclickOptionsPosition struct { X *float64 `json:"x"` Y *float64 `json:"y"` } +type LocatorDragToOptionsSourcePosition struct { + X *float64 `json:"x"` + Y *float64 `json:"y"` +} +type LocatorDragToOptionsTargetPosition struct { + X *float64 `json:"x"` + Y *float64 `json:"y"` +} type LocatorHoverOptionsPosition struct { X *float64 `json:"x"` Y *float64 `json:"y"` diff --git a/objectFactory.go b/objectFactory.go index e0575696..1d06e90b 100644 --- a/objectFactory.go +++ b/objectFactory.go @@ -26,6 +26,12 @@ func createObjectFactory(parent *channelOwner, objectType string, guid string, i return newFrame(parent, objectType, guid, initializer) case "JSHandle": return newJSHandle(parent, objectType, guid, initializer) + case "LocalUtils": + return nil + case "Tracing": + return newTracing(parent, objectType, guid, initializer) + case "APIRequestContext": + return nil case "Page": return newPage(parent, objectType, guid, initializer) case "Playwright": diff --git a/patches/main.patch b/patches/main.patch index 1b79b63b..e26135cd 100644 --- a/patches/main.patch +++ b/patches/main.patch @@ -1,5 +1,5 @@ diff --git a/docs/src/api/class-browsercontext.md b/docs/src/api/class-browsercontext.md -index e28cff153d28f73a9a42a36c9ec2f60be549013d..2143f1d78f31a6b266c1e9fff5c90c7df5cdd12f 100644 +index 660de17f9e668adebd9ce310ba82879cd14d32e9..6a14a8d872d4943637386fbb658e08bdd508030f 100644 --- a/docs/src/api/class-browsercontext.md +++ b/docs/src/api/class-browsercontext.md @@ -215,6 +215,7 @@ await context.AddCookiesAsync(new[] { cookie1, cookie2 }); @@ -29,7 +29,7 @@ index e28cff153d28f73a9a42a36c9ec2f60be549013d..2143f1d78f31a6b266c1e9fff5c90c7d ### param: BrowserContext.addInitScript.arg * langs: js -@@ -1022,7 +1033,7 @@ it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/We +@@ -1021,7 +1032,7 @@ it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/We handler function to route the request. ### param: BrowserContext.route.handler @@ -38,7 +38,7 @@ index e28cff153d28f73a9a42a36c9ec2f60be549013d..2143f1d78f31a6b266c1e9fff5c90c7d - `handler` <[function]\([Route]\)> handler function to route the request. -@@ -1187,7 +1198,7 @@ A glob pattern, regex pattern or predicate receiving [URL] used to register a ro +@@ -1186,7 +1197,7 @@ A glob pattern, regex pattern or predicate receiving [URL] used to register a ro [`method: BrowserContext.route`]. ### param: BrowserContext.unroute.handler @@ -47,92 +47,11 @@ index e28cff153d28f73a9a42a36c9ec2f60be549013d..2143f1d78f31a6b266c1e9fff5c90c7d - `handler` <[function]\([Route], [Request]\)> Optional handler function used to register a routing with [`method: BrowserContext.route`]. -diff --git a/docs/src/api/class-browsertype.md b/docs/src/api/class-browsertype.md -index 16c4062a210a52e411da22f8904f37b4ce69d98b..b1f55bce93da017c1d8127ed9a4fd0f76e93804a 100644 ---- a/docs/src/api/class-browsertype.md -+++ b/docs/src/api/class-browsertype.md -@@ -85,22 +85,25 @@ class BrowserTypeExamples - ``` - - ## async method: BrowserType.connect --* langs: js, python, java -+* langs: js, python, java, go - - returns: <[Browser]> - - This methods attaches Playwright to an existing browser instance. - - ### param: BrowserType.connect.wsEndpoint -+* langs: java, python, js, go - - `wsEndpoint` <[string]> - - A browser websocket endpoint to connect to. - - ### option: BrowserType.connect.headers -+* langs: java, python, js, go - - `headers` <[Object]<[string], [string]>> - - Additional HTTP headers to be sent with web socket connect request. Optional. - - ### option: BrowserType.connect.slowMo -+* langs: java, python, js, go - - `slowMo` <[float]> - - Slows down Playwright operations by the specified amount of milliseconds. Useful so that you -@@ -113,13 +116,14 @@ can see what is going on. Defaults to 0. - Logger sink for Playwright logging. Optional. - - ### option: BrowserType.connect.timeout -+* langs: java, python, js, go - - `timeout` <[float]> - - Maximum time in milliseconds to wait for the connection to be established. Defaults to - `30000` (30 seconds). Pass `0` to disable timeout. - - ## async method: BrowserType.connectOverCDP --* langs: java, js, python -+* langs: java, js, python, go - - returns: <[Browser]> - - This methods attaches Playwright to an existing browser instance using the Chrome DevTools Protocol. -@@ -131,7 +135,7 @@ Connecting over the Chrome DevTools Protocol is only supported for Chromium-base - ::: - - ### param: BrowserType.connectOverCDP.endpointURL --* langs: java, python, js -+* langs: java, python, js, go - - `endpointURL` <[string]> - - A CDP websocket endpoint or http url to connect to. For example `http://localhost:9222/` or `ws://127.0.0.1:9222/devtools/browser/387adf4c-243f-4051-a181-46798f4a46f4`. -@@ -143,13 +147,13 @@ A CDP websocket endpoint or http url to connect to. For example `http://localhos - Deprecated, use the first argument instead. Optional. - - ### option: BrowserType.connectOverCDP.headers --* langs: java, python, js -+* langs: java, python, js, go - - `headers` <[Object]<[string], [string]>> - - Additional HTTP headers to be sent with connect request. Optional. - - ### option: BrowserType.connectOverCDP.slowMo --* langs: java, python, js -+* langs: java, python, js, go - - `slowMo` <[float]> - - Slows down Playwright operations by the specified amount of milliseconds. Useful so that you -@@ -162,7 +166,7 @@ can see what is going on. Defaults to 0. - Logger sink for Playwright logging. Optional. - - ### option: BrowserType.connectOverCDP.timeout --* langs: java, python, js -+* langs: java, python, js, go - - `timeout` <[float]> - - Maximum time in milliseconds to wait for the connection to be established. Defaults to diff --git a/docs/src/api/class-frame.md b/docs/src/api/class-frame.md -index 929d1453cc30235701fc4a9dd80d40ae2f45374c..f3d14908335e44047b7653cf798d12a505d240a4 100644 +index 34b59c1a05eae03d9bde75e4a2a34fff180b8b2d..67c810045ea3c4b3a1bd9b87029703c85cc9e3b0 100644 --- a/docs/src/api/class-frame.md +++ b/docs/src/api/class-frame.md -@@ -1395,7 +1395,7 @@ await page.MainFrame.WaitForFunctionAsync("selector => !!document.querySelector( +@@ -1449,7 +1449,7 @@ await page.MainFrame.WaitForFunctionAsync("selector => !!document.querySelector( Optional argument to pass to [`param: expression`]. @@ -142,10 +61,10 @@ index 929d1453cc30235701fc4a9dd80d40ae2f45374c..f3d14908335e44047b7653cf798d12a5 ### option: Frame.waitForFunction.polling = %%-csharp-java-wait-for-function-polling-%% diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md -index ba018552b6743a274f916be5716e1ac2881ec334..16afa1aa70ff2bd4aa755ee990bbf11ae2ad0b67 100644 +index 5979b8d5528b771fd01e1d70d5f9a247b6d183c5..4b0bceb89242f328435020d6d782133a001ea328 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md -@@ -520,6 +520,18 @@ Script to be evaluated in all pages in the browser context. +@@ -522,6 +522,18 @@ Script to be evaluated in all pages in the browser context. Optional argument to pass to [`param: script`] (only supported when passing a function). @@ -164,7 +83,7 @@ index ba018552b6743a274f916be5716e1ac2881ec334..16afa1aa70ff2bd4aa755ee990bbf11a ## async method: Page.addScriptTag - returns: <[ElementHandle]> -@@ -967,7 +979,7 @@ Changes the CSS media type of the page. The only allowed values are `'screen'`, +@@ -969,7 +981,7 @@ Changes the CSS media type of the page. The only allowed values are `'screen'`, Passing `null` disables CSS media emulation. ### option: Page.emulateMedia.media @@ -173,7 +92,7 @@ index ba018552b6743a274f916be5716e1ac2881ec334..16afa1aa70ff2bd4aa755ee990bbf11a - `media` <[Media]<"screen"|"print"|"null">> Changes the CSS media type of the page. The only allowed values are `'Screen'`, `'Print'` and `'Null'`. -@@ -981,7 +993,7 @@ Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'` +@@ -983,7 +995,7 @@ Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'` `null` disables color scheme emulation. ### option: Page.emulateMedia.colorScheme @@ -182,7 +101,7 @@ index ba018552b6743a274f916be5716e1ac2881ec334..16afa1aa70ff2bd4aa755ee990bbf11a - `colorScheme` <[ColorScheme]<"light"|"dark"|"no-preference"|"null">> Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. Passing -@@ -994,7 +1006,7 @@ Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'` +@@ -996,7 +1008,7 @@ Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'` Emulates `'prefers-reduced-motion'` media feature, supported values are `'reduce'`, `'no-preference'`. Passing `null` disables reduced motion emulation. ### option: Page.emulateMedia.reducedMotion @@ -191,7 +110,7 @@ index ba018552b6743a274f916be5716e1ac2881ec334..16afa1aa70ff2bd4aa755ee990bbf11a - `reducedMotion` <[ReducedMotion]<"reduce"|"no-preference"|"null">> Emulates `'prefers-reduced-motion'` media feature, supported values are `'reduce'`, `'no-preference'`. Passing `null` disables reduced motion emulation. -@@ -2236,7 +2248,7 @@ Paper format. If set, takes priority over [`option: width`] or [`option: height` +@@ -2284,7 +2296,7 @@ Paper format. If set, takes priority over [`option: width`] or [`option: height` Paper width, accepts values labeled with units. ### option: Page.pdf.width @@ -200,7 +119,7 @@ index ba018552b6743a274f916be5716e1ac2881ec334..16afa1aa70ff2bd4aa755ee990bbf11a - `width` <[string]> Paper width, accepts values labeled with units. -@@ -2248,7 +2260,7 @@ Paper width, accepts values labeled with units. +@@ -2296,7 +2308,7 @@ Paper width, accepts values labeled with units. Paper height, accepts values labeled with units. ### option: Page.pdf.height @@ -209,7 +128,7 @@ index ba018552b6743a274f916be5716e1ac2881ec334..16afa1aa70ff2bd4aa755ee990bbf11a - `height` <[string]> Paper height, accepts values labeled with units. -@@ -2264,7 +2276,7 @@ Paper height, accepts values labeled with units. +@@ -2312,7 +2324,7 @@ Paper height, accepts values labeled with units. Paper margins, defaults to none. ### option: Page.pdf.margin @@ -218,7 +137,7 @@ index ba018552b6743a274f916be5716e1ac2881ec334..16afa1aa70ff2bd4aa755ee990bbf11a - `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`. -@@ -2570,7 +2582,7 @@ A glob pattern, regex pattern or predicate receiving [URL] to match while routin +@@ -2627,7 +2639,7 @@ A glob pattern, regex pattern or predicate receiving [URL] to match while routin When a [`option: baseURL`] via the context options was provided and the passed URL is a path, it gets merged via the [`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor. ### param: Page.route.handler @@ -227,7 +146,7 @@ index ba018552b6743a274f916be5716e1ac2881ec334..16afa1aa70ff2bd4aa755ee990bbf11a - `handler` <[function]\([Route], [Request]\)> handler function to route the request. -@@ -2992,7 +3004,7 @@ the [`param: url`]. +@@ -3018,7 +3030,7 @@ the [`param: url`]. A glob pattern, regex pattern or predicate receiving [URL] to match while routing. ### param: Page.unroute.handler @@ -236,7 +155,7 @@ index ba018552b6743a274f916be5716e1ac2881ec334..16afa1aa70ff2bd4aa755ee990bbf11a - `handler` <[function]\([Route], [Request]\)> Optional handler function to route the request. -@@ -3238,7 +3250,7 @@ Shortcut for main frame's [`method: Frame.waitForFunction`]. +@@ -3268,7 +3280,7 @@ Shortcut for main frame's [`method: Frame.waitForFunction`]. Optional argument to pass to [`param: expression`]. @@ -246,7 +165,7 @@ index ba018552b6743a274f916be5716e1ac2881ec334..16afa1aa70ff2bd4aa755ee990bbf11a ### option: Page.waitForFunction.polling = %%-csharp-java-wait-for-function-polling-%% diff --git a/docs/src/api/class-route.md b/docs/src/api/class-route.md -index b36a78f02c3d66e438f1f3f6d9c78a6ec01b3f35..e304fe69e3dae822b18b0ae7dc86ce31993378c9 100644 +index 61dd9e3ad4e9b83a8132bc61c026d2c18b35d979..fc440fe38af9dfbd4f6d3c7ef651890657c16008 100644 --- a/docs/src/api/class-route.md +++ b/docs/src/api/class-route.md @@ -103,10 +103,17 @@ If set changes the request URL. New URL must have same protocol as original one. @@ -281,10 +200,10 @@ index b36a78f02c3d66e438f1f3f6d9c78a6ec01b3f35..e304fe69e3dae822b18b0ae7dc86ce31 * langs: csharp, java - `body` <[string]> diff --git a/docs/src/api/params.md b/docs/src/api/params.md -index 07f1abcc0217be269b5cb71739cc88f8c37f81f9..d8605d79df0f68b66e12aa62fb77beffb3d48587 100644 +index f214cf943ae2c95c9377a093f0132e237b9bea2e..393b12018edf730bc98bb0aa233c595f759fa7d0 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md -@@ -145,8 +145,8 @@ Defaults to `'visible'`. Can be either: +@@ -146,8 +146,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. @@ -295,7 +214,7 @@ index 07f1abcc0217be269b5cb71739cc88f8c37f81f9..d8605d79df0f68b66e12aa62fb77beff - `polling` <[float]|"raf"> If [`option: polling`] is `'raf'`, then [`param: expression`] is constantly executed in `requestAnimationFrame` -@@ -193,7 +193,7 @@ Dangerous option; use with care. Defaults to `false`. +@@ -194,7 +194,7 @@ Dangerous option; use with care. Defaults to `false`. Network proxy settings. ## csharp-java-browser-option-env @@ -304,7 +223,7 @@ index 07f1abcc0217be269b5cb71739cc88f8c37f81f9..d8605d79df0f68b66e12aa62fb77beff - `env` <[Object]<[string], [string]>> Specify environment variables that will be visible to the browser. Defaults to `process.env`. -@@ -205,7 +205,7 @@ Specify environment variables that will be visible to the browser. Defaults to ` +@@ -206,7 +206,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`. ## js-python-context-option-storage-state @@ -313,7 +232,7 @@ index 07f1abcc0217be269b5cb71739cc88f8c37f81f9..d8605d79df0f68b66e12aa62fb77beff - `storageState` <[path]|[Object]> - `cookies` <[Array]<[Object]>> cookies to set for context - `name` <[string]> -@@ -233,7 +233,7 @@ Populates context with given storage state. This option can be used to initializ +@@ -234,7 +234,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 @@ -322,7 +241,7 @@ index 07f1abcc0217be269b5cb71739cc88f8c37f81f9..d8605d79df0f68b66e12aa62fb77beff - `storageStatePath` <[path]> Populates context with given storage state. This option can be used to initialize context with logged-in information -@@ -387,7 +387,7 @@ Function to be evaluated in the worker context. +@@ -407,7 +407,7 @@ Function to be evaluated in the worker context. Function to be evaluated in the worker context. ## python-context-option-viewport @@ -331,7 +250,7 @@ index 07f1abcc0217be269b5cb71739cc88f8c37f81f9..d8605d79df0f68b66e12aa62fb77beff - `viewport` <[null]|[Object]> - `width` <[int]> page width in pixels. - `height` <[int]> page height in pixels. -@@ -537,7 +537,7 @@ call [`method: BrowserContext.close`] for the HAR to be saved. +@@ -557,7 +557,7 @@ call [`method: BrowserContext.close`] for the HAR to be saved. Optional setting to control whether to omit request content from the HAR. Defaults to `false`. ## context-option-recordvideo @@ -340,6 +259,29 @@ index 07f1abcc0217be269b5cb71739cc88f8c37f81f9..d8605d79df0f68b66e12aa62fb77beff - `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` +@@ -884,12 +884,14 @@ Slows down Playwright operations by the specified amount of milliseconds. Useful + - %%-browser-option-tracesdir-%% + + ## locator-option-has-text ++* langs: js, python, csharp + - `hasText` <[string]|[RegExp]> + + Matches elements containing specified text somewhere inside, possibly in a child or a descendant element. + For example, `"Playwright"` matches `
Playwright
`. + + ## locator-option-has ++* langs: js, python, csharp + - `has` <[Locator]> + + Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. +@@ -934,6 +936,7 @@ saved to the disk. + Specify screenshot type, defaults to `png`. + + ## screenshot-option-mask ++* langs: js, python, csharp + - `mask` <[Array]<[Locator]>> + + Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with diff --git a/utils/doclint/generateGoApi.js b/utils/doclint/generateGoApi.js new file mode 100644 index 0000000000000000000000000000000000000000..df722cfb131676d6b73ade666eb3b0322333879a diff --git a/playwright b/playwright index 4803e0fe..acae63c4 160000 --- a/playwright +++ b/playwright @@ -1 +1 @@ -Subproject commit 4803e0fe72f560a14ac34661aeea5072255dd116 +Subproject commit acae63c409446365c397782593c8c20f101cb313 diff --git a/run.go b/run.go index f6842e52..84eae76d 100644 --- a/run.go +++ b/run.go @@ -15,7 +15,7 @@ import ( "runtime" ) -const playwrightCliVersion = "1.16.3-1635814179000" +const playwrightCliVersion = "1.20.0-beta-1647057403000" type PlaywrightDriver struct { DriverDirectory, DriverBinaryLocation, Version string @@ -243,9 +243,6 @@ func Run(options ...*RunOptions) (*Playwright, error) { if err != nil { return nil, fmt.Errorf("could not get driver instance: %w", err) } - if err := driver.install(); err != nil { - return nil, fmt.Errorf("could not install driver: %w", err) - } connection, err := driver.run() if err != nil { return nil, err diff --git a/scripts/apply-patch.sh b/scripts/apply-patch.sh index 993f53d5..b54b8ee5 100755 --- a/scripts/apply-patch.sh +++ b/scripts/apply-patch.sh @@ -9,18 +9,17 @@ echo "Applying patches..." pushd "$SCRIPTS_DIR/.." git submodule update --init -mkdir -p tests/assets -cp -r playwright/tests/assets/* tests/assets/ pushd playwright git checkout HEAD --detach if git show-ref -q --heads "$BRANCH_NAME_BUILD"; then + git checkout main git branch -D "$BRANCH_NAME_BUILD" fi git checkout -b "$BRANCH_NAME_BUILD" -git apply --whitespace=nowarn ../patches/* +git apply --3way --whitespace=nowarn ../patches/* git add -A git commit -m "Applied patches" diff --git a/scripts/data/interfaces.json b/scripts/data/interfaces.json index d519cc1c..7869d6a3 100644 --- a/scripts/data/interfaces.json +++ b/scripts/data/interfaces.json @@ -170,7 +170,7 @@ "error" ], "StartChunk": [ - null, + "options ...TracingStartChunkOptions", "error" ], "StopChunk": [ diff --git a/scripts/generate-api.sh b/scripts/generate-api.sh index 27830b8e..c7adc6a2 100755 --- a/scripts/generate-api.sh +++ b/scripts/generate-api.sh @@ -6,6 +6,8 @@ PWD=$(pwd -P) $PWD/scripts/apply-patch.sh +go run scripts/install-browsers/main.go + echo "Generating Interfaces" node scripts/generate-interfaces.js > generated-interfaces.go go fmt generated-interfaces.go > /dev/null diff --git a/tests/assets/css-transition.html b/tests/assets/css-transition.html new file mode 100644 index 00000000..449c1548 --- /dev/null +++ b/tests/assets/css-transition.html @@ -0,0 +1,21 @@ + + +
+ diff --git a/tests/assets/empty-standard-mode.html b/tests/assets/empty-standard-mode.html new file mode 100644 index 00000000..0e76edd6 --- /dev/null +++ b/tests/assets/empty-standard-mode.html @@ -0,0 +1 @@ + diff --git a/tests/assets/error.html b/tests/assets/error.html index 9532d14c..0851c4df 100644 --- a/tests/assets/error.html +++ b/tests/assets/error.html @@ -1,4 +1,4 @@ - diff --git a/tests/assets/modernizr.html b/tests/assets/modernizr.html index 77981834..5096ffba 100644 --- a/tests/assets/modernizr.html +++ b/tests/assets/modernizr.html @@ -10,6 +10,11 @@ let value = Modernizr[name]; report[name] = value; } + +report['devicemotion2'] = 'ondevicemotion' in window; +report['deviceorientation2'] = 'orientation' in window; +report['deviceorientation3'] = 'ondeviceorientation' in window; + document.body.style.whiteSpace = 'pre'; document.body.textContent = JSON.stringify(report, undefined, 4); window.report = JSON.parse(document.body.textContent); diff --git a/tests/assets/modernizr/mobile-safari-14-1.json b/tests/assets/modernizr/mobile-safari-14-1.json index bb30a7dc..1391463a 100644 --- a/tests/assets/modernizr/mobile-safari-14-1.json +++ b/tests/assets/modernizr/mobile-safari-14-1.json @@ -90,7 +90,10 @@ "promises": true, "es6string": true, "devicemotion": true, + "devicemotion2": true, "deviceorientation": true, + "deviceorientation2": true, + "deviceorientation3": true, "filereader": true, "urlparser": true, "urlsearchparams": true, @@ -180,7 +183,7 @@ "websocketsbinary": true, "atobbtoa": true, "atob-btoa": true, - "sharedworkers": false, + "sharedworkers": true, "bdi": true, "xhrresponsetypearraybuffer": true, "xhrresponsetypeblob": true, diff --git a/tests/assets/modernizr/safari-14-1.json b/tests/assets/modernizr/safari-14-1.json index 5cb80869..55373b37 100644 --- a/tests/assets/modernizr/safari-14-1.json +++ b/tests/assets/modernizr/safari-14-1.json @@ -90,7 +90,10 @@ "promises": true, "es6string": true, "devicemotion": false, + "devicemotion2": false, "deviceorientation": false, + "deviceorientation2": false, + "deviceorientation3": false, "filereader": true, "urlparser": true, "urlsearchparams": true, @@ -180,7 +183,7 @@ "websocketsbinary": true, "atobbtoa": true, "atob-btoa": true, - "sharedworkers": false, + "sharedworkers": true, "bdi": true, "xhrresponsetypearraybuffer": true, "xhrresponsetypeblob": true, diff --git a/tests/assets/mui.html b/tests/assets/mui.html new file mode 100644 index 00000000..2eed5cc5 --- /dev/null +++ b/tests/assets/mui.html @@ -0,0 +1,13 @@ + + + + + + +
+ + diff --git a/tests/assets/rotate-pseudo.html b/tests/assets/rotate-pseudo.html new file mode 100644 index 00000000..dca33ecd --- /dev/null +++ b/tests/assets/rotate-pseudo.html @@ -0,0 +1,32 @@ + + + + + +
+ + diff --git a/tests/assets/rotate-z-shadow-dom.html b/tests/assets/rotate-z-shadow-dom.html new file mode 100644 index 00000000..0a6e3f72 --- /dev/null +++ b/tests/assets/rotate-z-shadow-dom.html @@ -0,0 +1,31 @@ + + + + + diff --git a/tests/assets/rotate-z.html b/tests/assets/rotate-z.html index 9a272dc8..53977894 100644 --- a/tests/assets/rotate-z.html +++ b/tests/assets/rotate-z.html @@ -13,7 +13,7 @@ animation-iteration-count: infinite; animation-timing-function: linear; } - + @keyframes z-spin { 0% { transform: rotateZ(0deg); } 100% { transform: rotateZ(360deg); } diff --git a/tests/assets/web-animation.html b/tests/assets/web-animation.html new file mode 100644 index 00000000..ea7a5df7 --- /dev/null +++ b/tests/assets/web-animation.html @@ -0,0 +1,23 @@ + + +
+ diff --git a/tests/assets/webfont/README.md b/tests/assets/webfont/README.md new file mode 100644 index 00000000..5bcee9ad --- /dev/null +++ b/tests/assets/webfont/README.md @@ -0,0 +1,3 @@ +This icon font was generated: +- using SVG icons from https://github.com/primer/octicons +- bundling icons into webfonts using https://github.com/fontello/fontello diff --git a/tests/assets/webfont/iconfont.svg b/tests/assets/webfont/iconfont.svg new file mode 100644 index 00000000..9d2a4ca9 --- /dev/null +++ b/tests/assets/webfont/iconfont.svg @@ -0,0 +1,14 @@ + + + +Copyright (C) 2022 by original authors @ fontello.com + + + + + + + + + + diff --git a/tests/assets/webfont/iconfont.woff2 b/tests/assets/webfont/iconfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..ceba03549a59bd18dea3d36df96a2438540c9c50 GIT binary patch literal 2656 zcmV-m3ZM0NPew8T0RR910199L4*&oF02hz|0162J0RR9100000000000000000000 z0000SR0d!Gg9Zo=37iZO2nvJ%gb51>00A}vBm)ctAO(d@2R00W92eRJdEd>ugcKqIOq} z9QL2)O8eg=DUndb!lN*CZf>%(-9O18f+~SW1xS*>wMGE>6S7LP^*x4L9>c#?8co@( zWFJvKBm#J8Wf&D*v|Mz#U<$-c`@ZLo86I)#t$7 z;g^@cX%htsOB0X#n(2j;d`*CmUN=9>7X2pA0g+%uU_m2DCSG=kImYk==V-jK7{WH* zNKga_&CkQops~i|Oo7!*O=DJ`<}{5KPK&#@o= zN^~yM_*OO=H@>30{&CBYwAc2#Z1P6k+tw1zb$FyJk*TDoVBO?7Ac~|9I&8;FkT1Y;+uraB5sS$`;4T3UDuLQENQM* z6i1cScgL=ZBuGv+R?~Cd3^h9csSsOhzhkPmsl0LZT~3yL7LkX9MAszxIIb3O0S_-s z^t3U#-?+!32`pArYlF0rgsU0wKw5|_u74Y832qaSl=-n`uIY`um^>50MLh3~hJ4+P z$j{ipy(JnD<3)?npEcBU49l%iiL*?kwvx~;^yk|jOXj-K)NTNJrIe*g^G?2Hj!Ey) zo8+DOeBKAL(Nxb7lX)J<0g@!L`3!E8$hMftnZrGDvIDsoyESrC{Wj7b{h3@Ajk|Ox zxnvKMhvy$sGo5)pNoLo!0{KgMZ`1SlPPFrmmA`ZW8Z)zxp}gYuNRH&j3`BWs*%Uc9 zM@kdg-=rqOf*~p6ZQW5$j88a+oJ5_uN2Aj=||1}UoiDp}Yr)7$oJi!oN73LYBCtzal}CoZ4Jfg&`D3xVRH z5GoOhN`X?e@Lbd`MRL&7zlDE7TLe6hbGqB ze@D&1HnL+C^N{?*QP8bwsDa`IDEv^=LQw}rJroU4G(yn?MKd%v4E4rJE!7JpNi&=E zX6>0HiEwuE#^WRBI_cB$TXp>Y+b_JEz!vIdSi+m&c*HY*g1bU9bh z@2H!;i*q}n8(OD#VH=EcbhzCkQ4htsE#-Fvh(55}tuqwWJSyE#ua)jeK>UURJ?IYf zfnK?6glpON+J~m3Jf%)6u!!=f-Tnds`MDOYkmsy|XS2~*j!-gbtUOOy}X18la48Ur>amti)R*Q`g0 z6ijsl!dVykO0>&i3UXku8CH>mRV7(}d-cSjSiGXp64V~KdJ~4-k^~z0hVYm=_2wOF zg^^C-h8u1B+_0y2TLLZEYe&~7%9y!Fj6|y8gZ=>vPTIJ^_AQCP)HUEZFDYhvy@)+okd#f4+195ab)xEZG?3JsA&5l-OS{O^&HT|m5 z%PJWb%dL#FzNuGdw|D&=UxeoE^9ZFm{}ZbYtg54~!uIX$w)0&j-e(*k5EhujHSQ9O<{t^BMNCH>v5q-H#}gUa zAx_vsIB5_0rzRMs(-1^(Msw+`BXlm2;a%apJ&X(XFfQ7|xTJwDJ3?0+;j1ul1lQ~l zT(?JX!yds+4Rp&9y6s5ro#4B^JGE6(cKN$Tjqe}x*Ob@9KtkD&P&@|)3rPpu23SMvS#n*g3=H7Wj#3xr(@p`x1-tcQU z>*B`WX5HER$E-`6evdhLX=3iIFc*2|Hmq~&sC(A+;@kDI_I0LtS(&+IxtWh24=!5u z`q|mxiT7G*VfKhtaEGEpQ#+kiJTqzPiL=}C%4ON^_{N$ z#om}ZI?r8Pzke41^H24cx)EP(WC^&%ja)=4kJ6rtUa@gwyJsvBBT9=(;&Hh=aXd6C z0e)bvwUreMB0b#=^%bp^t$u&L-=F8RD*}-oTNGG|87!9=u}l)tTH=W41X}dkKyy)H zTe!I^(CJhcHWf9M7P{?{00Id7|6(z*GkfqKceb7b_-jq=J478V%`r3&1I9lk;26gYnBsb1I~&?7CtsC zvT?I>k(U6;d;7@eF&Z%*V3wD9i-a7>UZlv9YS!R{*nl&%$f8JAvJK9}A}^cd$UZ*m z<(Gf*oif(s{OR3|Pe$t(WliL5(CUeK^@L>*^cR%}o#0SEOPSFYZe8s5rn8zyjwjoX z9-V%!F?^9Q_+2#m8J=#3dThoxz(G!Nm>H7n<|q!0jM0QcJFQu9I}YO{-Qj@3ooCoj zg1tB-IL1+SGx-SN2;phu{S2P6Bo-ea%tSHrJ{GUDl9L>>cA4O?pyzqsG*-L!W>|;s z&_x{UrU*L OX|-JQJ!{e?8U+Ay83p73 literal 0 HcmV?d00001 diff --git a/tests/assets/webfont/webfont.html b/tests/assets/webfont/webfont.html new file mode 100644 index 00000000..51675943 --- /dev/null +++ b/tests/assets/webfont/webfont.html @@ -0,0 +1,18 @@ + + + ++- + diff --git a/tests/remote_server_test.go b/tests/remote_server_test.go index d8afac0d..f3a2dafd 100644 --- a/tests/remote_server_test.go +++ b/tests/remote_server_test.go @@ -27,7 +27,7 @@ func newRemoteServer() (*remoteServer, error) { node = "node.exe" } cliJs := filepath.Join(driver.DriverDirectory, "package", "lib", "cli", "cli.js") - cmd := exec.Command(filepath.Join(driver.DriverDirectory, node), cliJs, "launch-server", browserName) + cmd := exec.Command(filepath.Join(driver.DriverDirectory, node), cliJs, "launch-server", "--browser", browserName) cmd.Stderr = os.Stderr stdout, err := cmd.StdoutPipe() if err != nil { diff --git a/tracing.go b/tracing.go index 6809d6b3..0c1c93d0 100644 --- a/tracing.go +++ b/tracing.go @@ -1,71 +1,85 @@ package playwright type tracingImpl struct { - context *browserContextImpl - channel *channel + channelOwner } func (t *tracingImpl) Start(options ...TracingStartOptions) error { if _, err := t.channel.Send("tracingStart", options); err != nil { return err } - if _, err := t.channel.Send("tracingStartChunk", options); err != nil { + title := "" + if len(options) == 1 && options[0].Title != nil { + title = *options[0].Title + } + if _, err := t.channel.Send("tracingStartChunk", map[string]interface{}{ + "title": title, + }); err != nil { return err } return nil } -func (t *tracingImpl) StartChunk() error { - _, err := t.channel.Send("tracingStartChunk") +func (t *tracingImpl) StartChunk(options ...TracingStartChunkOptions) error { + _, err := t.channel.Send("tracingStartChunk", options) return err } -func (t *tracingImpl) Stop(options ...TracingStopOptions) error { + +func (t *tracingImpl) StopChunk(options ...TracingStopChunkOptions) error { path := "" if len(options) == 1 && options[0].Path != nil { path = *options[0].Path } - if err := t.stopChunk(path); err != nil { - return err - } - if _, err := t.channel.Send("tracingStop"); err != nil { + if err := t.doStopChunk(path); err != nil { return err } return nil } -func (t *tracingImpl) StopChunk(options ...TracingStopChunkOptions) error { + +func (t *tracingImpl) Stop(options ...TracingStopOptions) error { path := "" if len(options) == 1 && options[0].Path != nil { path = *options[0].Path + return t.doStopChunk(path) } - if err := t.stopChunk(path); err != nil { - return err - } - return nil + _, err := t.channel.Send("tracingStopChunk", options) + return err } -func (t *tracingImpl) stopChunk(path string) error { - save := true - if path == "" { - save = false +func (t *tracingImpl) doStopChunk(filePath string) error { + isLocal := !t.connection.isRemote + mode := "doNotSave" + if filePath != "" { + if isLocal { + mode = "compressTraceAndSources" + } else { + mode = "compressTrace" + } } artifactChannel, err := t.channel.Send("tracingStopChunk", map[string]interface{}{ - "save": save, + "mode": mode, }) if err != nil { return err } - if artifactChannel != nil { - artifact := fromChannel(artifactChannel).(*artifactImpl) - if path != "" { - if err := artifact.SaveAs(path); err != nil { - return err - } - } - return artifact.Delete() + // Not interested in artifacts. + if filePath == "" { + return nil } - return nil + // The artifact may be missing if the browser closed while stopping tracing. + if artifactChannel == nil { + return nil + } + // Save trace to the final local file. + artifact := fromChannel(artifactChannel).(*artifactImpl) + if err := artifact.SaveAs(filePath); err != nil { + return err + } + return artifact.Delete() } -func newTracing(context *browserContextImpl) *tracingImpl { - return &tracingImpl{context, context.channel} +func newTracing(parent *channelOwner, objectType string, guid string, initializer map[string]interface{}) *tracingImpl { + bt := &tracingImpl{} + bt.createChannelOwner(bt, parent, objectType, guid, initializer) + return bt }