Playwright for Go a browser automation library to control Chromium, Firefox and WebKit with a single API.

Overview

🎭 Playwright for

PkgGoDev License Go Report Card Build Status Join Slack Coverage Status Chromium version Firefox version WebKit version

API reference | Example recipes

Playwright is a Go library to automate Chromium, Firefox and WebKit with a single API. Playwright is built to enable cross-browser web automation that is ever-green, capable, reliable and fast.

Linux macOS Windows
Chromium 90.0.4392.0
WebKit 14.1
Firefox 85.0b5

Headless execution is supported for all the browsers on all platforms.

Installation

go get github.com/mxschmitt/playwright-go

Capabilities

Playwright is built to automate the broad and growing set of web browser capabilities used by Single Page Apps and Progressive Web Apps.

  • Scenarios that span multiple page, domains and iframes
  • Auto-wait for elements to be ready before executing actions (like click, fill)
  • Intercept network activity for stubbing and mocking network requests
  • Emulate mobile devices, geolocation, permissions
  • Support for web components via shadow-piercing selectors
  • Native input events for mouse and keyboard
  • Upload and download files

Example

The following example crawls the current top voted items from Hacker News.

package main

import (
	"fmt"
	"log"

	"github.com/mxschmitt/playwright-go"
)

func main() {
	pw, err := playwright.Run()
	if err != nil {
		log.Fatalf("could not start playwright: %v", err)
	}
	browser, err := pw.Chromium.Launch()
	if err != nil {
		log.Fatalf("could not launch browser: %v", err)
	}
	page, err := browser.NewPage()
	if err != nil {
		log.Fatalf("could not create page: %v", err)
	}
	if _, err = page.Goto("https://news.ycombinator.com"); err != nil {
		log.Fatalf("could not goto: %v", err)
	}
	entries, err := page.QuerySelectorAll(".athing")
	if err != nil {
		log.Fatalf("could not get entries: %v", err)
	}
	for i, entry := range entries {
		titleElement, err := entry.QuerySelector("td.title > a")
		if err != nil {
			log.Fatalf("could not get title element: %v", err)
		}
		title, err := titleElement.TextContent()
		if err != nil {
			log.Fatalf("could not get text content: %v", err)
		}
		fmt.Printf("%d: %s\n", i+1, title)
	}
	if err = browser.Close(); err != nil {
		log.Fatalf("could not close browser: %v", err)
	}
	if err = pw.Stop(); err != nil {
		log.Fatalf("could not stop Playwright: %v", err)
	}
}

More examples

How does it work?

Playwright is a Node.js library which uses:

  • Chrome DevTools Protocol to communicate with Chromium
  • Patched Firefox to communicate with Firefox
  • Patched WebKit to communicate with WebKit

These patches are based on the original sources of the browsers and don't modify the browser behaviour so the browsers are basically the same (see here) as you see them in the wild. The support for different programming languages is based on exposing a RPC server in the Node.js land which can be used to allow other languages to use Playwright without implementing all the custom logic:

The bridge between Node.js and the other languages is basically a Node.js runtime combined with Playwright which gets shipped for each of these languages (around 50MB) and then communicates over stdio to send the relevant commands. This will also download the pre-compiled browsers.

Is Playwright for Go ready?

We are ready for your feedback, but we are still covering Playwright Go with the tests.

Resources

Issues
  • response.Body does not return the byte array

    response.Body does not return the byte array

    This is issue might relates to #141

    The following is an example to reproduce this bug.

    package main
    
    import (
    	"fmt"
    	"log"
    	"time"
    
    	"github.com/mxschmitt/playwright-go"
    )
    
    func main() {
    	pw, err := playwright.Run()
    	if err != nil {
    		log.Fatalf("could not start playwright: %v", err)
    	}
    	browser, err := pw.Chromium.Launch(playwright.BrowserTypeLaunchOptions{Headless: playwright.Bool(false)})
    	if err != nil {
    		log.Fatalf("could not launch browser: %v", err)
    	}
    	page, err := browser.NewPage()
    	if err != nil {
    		log.Fatalf("could not create page: %v", err)
    	}
    	eventsChan := make(chan string)
    	go func(eventsChan chan string) {
    		for c := range eventsChan {
    			fmt.Println(c)
    		}
    	}(eventsChan)
    	page.On("response", func(response playwright.Response) {
    		// the following code block causes the problem
    		// body, err := response.Body()
    		// if err != nil {
    		// 	log.Fatalf("get body failed: %v", err)
    		// }
    		// fmt.Println("body len: ", len(body))
    
    		eventsChan <- fmt.Sprintf("%d %s", response.Status(), response.URL())
    	})
    	if _, err = page.Goto("https://news.ycombinator.com"); err != nil {
    		log.Fatalf("could not goto: %v", err)
    	}
    
    	time.Sleep(3 * time.Second)
    	if err = browser.Close(); err != nil {
    		log.Fatalf("could not close browser: %v", err)
    	}
    	if err = pw.Stop(); err != nil {
    		log.Fatalf("could not stop Playwright: %v", err)
    	}
    }
    
    

    Tested version go.mod

    go 1.16
    
    require github.com/mxschmitt/playwright-go v0.1100.0 // indirect
    
    opened by lotusirous 9
  • Version Packages

    Version Packages

    @kumaraditya303 Thanks for your great work and all your contributions to this repository. For your commit "roll to 1.14" that matches the latest version of Playwright, do you have any plan to version it or publish the release?

    opened by AngangGuo 9
  • Improve versioning with Git tags / GH releases.

    Improve versioning with Git tags / GH releases.

    Hello, thanks for the lib It works great! I faced with some limitations:

    • I would like to avoid downloading https://github.com/mxschmitt/playwright-go/blob/c9d1531e0354a7f267237b3ac55595a8f18170e4/run.go#L29 after every container start. I assumed that playwright is already installed on the official mcr.microsoft.com/playwright:bionic images.

    • It looks like that playwright is installed from an external source https://github.com/mxschmitt/playwright-go/blob/c9d1531e0354a7f267237b3ac55595a8f18170e4/run.go#L15 not the official ones.

    • How can I install a different playwright version? The current is 1.7

    enhancement 
    opened by StarpTech 9
  • [Feature Question] BrowserContext.backgroundPages() doesn't exist? :)

    [Feature Question] BrowserContext.backgroundPages() doesn't exist? :)

    BrowserContext in this example: https://playwright.dev/docs/chrome-extensions/ (from JavaScript) supports "backgroundPages", a way to get handles on extensions.

    Is this supported in Playwright? It isn't from what I can see at the moment from examining the "Generated structs".

    Do you know if this will get added or if there are plans for it to be added?

    Many thanks & appreciate your work, Neil

    enhancement 
    opened by neilspage 7
  • Missing types for page error events.

    Missing types for page error events.

    Hi, I can't see the type definition of the page errors. For example:

    page, _ := browserContext.NewPage()
    page.Once("pageerror", func(err ???) {
    	c.Logger().Errorf("an error on the page was detected: %s", err)
    })
    

    I also recommend using custom function types e.g

    type RequestFailedEventHandler = func(request *Request)
    
    opened by StarpTech 7
  • Getting fatal panic after upgrading to latest commit from release version

    Getting fatal panic after upgrading to latest commit from release version

    Hi,

    We are getting a fatal panic when going to a specific site, that we didn't get on v0.1400.0 Release, and also a commit version after that specified below.

    Latest commit tested that did not have this issue: 7e45483

    All commits we test that are after this commit, we end up with a fatal panic, which did not happen on the same site prior to this. A big difference I can see is that you go from Playwright 1.14.1 -> 1.16.0-next.. So maybe the problem is there?

    Here is the full panic message:

    events.js:377
          throw er; // Unhandled 'error' event
          ^
    
    Error: EPIPE: broken pipe, write
        at Socket._write (internal/net.js:55:25)
        at writeOrBuffer (internal/streams/writable.js:358:12)
        at Socket.Writable.write (internal/streams/writable.js:303:10)
        at Transport.send (C:\Users\osterman01\AppData\Local\ms-playwright-go\1.16.0-next-1631944242000\package\lib\protocol\transport.js:54:21)
        at DispatcherConnection.dispatcherConnection.onmessage (C:\Users\osterman01\AppData\Local\ms-playwright-go\1.16.0-next-1631944242000\package\lib\cli\driver.js:67:57)
        at DispatcherConnection.sendMessageToClient (C:\Users\osterman01\AppData\Local\ms-playwright-go\1.16.0-next-1631944242000\package\lib\dispatchers\dispatcher.js:186:10)
        at BrowserContextDispatcher._dispatchEvent (C:\Users\osterman01\AppData\Local\ms-playwright-go\1.16.0-next-1631944242000\package\lib\dispatchers\dispatcher.js:108:22)
        at CRBrowserContext.<anonymous> (C:\Users\osterman01\AppData\Local\ms-playwright-go\1.16.0-next-1631944242000\package\lib\dispatchers\browserContextDispatcher.js:102:81)
        at CRBrowserContext.emit (events.js:400:28)
        at FrameManager.requestReceivedResponse (C:\Users\osterman01\AppData\Local\ms-playwright-go\1.16.0-next-1631944242000\package\lib\server\frames.js:295:32)
    Emitted 'error' event on Socket instance at:
        at emitErrorNT (internal/streams/destroy.js:106:8)
        at errorOrDestroy (internal/streams/destroy.js:168:7)
        at onwriteError (internal/streams/writable.js:391:3)
        at processTicksAndRejections (internal/process/task_queues.js:84:21)
        at runNextTicks (internal/process/task_queues.js:64:3)
        at processImmediate (internal/timers.js:437:9) {
      errno: -4047,
      syscall: 'write',
      code: 'EPIPE'
    }
    
    Debugger finished with the exit code 0
    
    p2-bug 
    opened by KiqoCode 6
  • Add missing functionality/methods

    Add missing functionality/methods

    Current report (node scripts/validate-interfaces.js):

    Missing API interface functions:

    • [x] BrowserContext.SetHTTPCredentials
    • [x] BrowserContext.StorageState
    • [x] ElementHandle.WaitForElementState
    • [x] ElementHandle.WaitForSelector
    enhancement good first issue 
    opened by mxschmitt 6
  • Always downloading Playwright driver

    Always downloading Playwright driver

    I noticed that in the current master branch it was always downloading the driver. I found the issue, in PlaywrightDriver.isUpToDateDriver It's checking the output of PW, for example:

    /Users/sam/Library/Caches/ms-playwright-go/1.16.0-next-1634703014000/playwright.sh --version
    Version 1.16.0-next
    

    With the constant:

    const playwrightCliVersion = "1.16.0-next-1634703014000"
    

    Using:

    	if bytes.Contains(output, []byte(d.Version)) {
    		return true, nil
    	}
    

    The extra -1634703014000 on the constant is the issue. I've fixed it locally by adding this to the end of isUpToDateDriver:

    	if strings.HasPrefix(string(output), "Version ") {
    		// Get rid of trailing new line
    		outputStr := strings.TrimSpace(string(output))
    		if len(outputStr) > 8 && strings.Contains(d.Version, outputStr[8:]) {
    			return true, nil
    		}
    	}
    

    I'll submit a PR with the change.

    If you have any suggestions for changes I'm happy to change.

    upstream 
    opened by SamHennessy 5
  • [internal]: fix that there is XML in the doc comments

    [internal]: fix that there is XML in the doc comments

    • [ ] fix that there is XML in the doc comments -> it should not be there (was not correct since a few months)
    • [x] fix that there are csharp examples in the generated_interfaces.go
    • [x] Re-introduce EmulateMedia
    p2-bug 
    opened by mxschmitt 5
  • Interface vs Struct

    Interface vs Struct

    Thanks for this great library and your hardwork to make it great.

    From https://pkg.go.dev/github.com/mxschmitt/playwright-go#pkg-index, the methods show out if the type is struct(like Playwright):

    type Playwright
        func Run(options ...*RunOptions) (*Playwright, error)
        func (c *Playwright) Dispose()
        func (p *Playwright) Stop() error
    

    But No method shows out if the type is defined as interface(like Page), we need to go to the type definition to find the available methods.

    type Page
    

    Is it possible to define the Page as struct?

    type Page struct {
        // non export fields
    }
    
    func (*Page) Click(selector string, options ...PageClickOptions) error
    func (*Page) Fill(selector, text string, options ...FrameFillOptions) error
    ... ...
    

    What do you think about it? Thanks.

    feedback 
    opened by AngangGuo 5
  • Not working on WSL 2

    Not working on WSL 2

    Hi,

    I'm using playwright on this project hippokampe specifically in the api module. This app is already tested in vagrant and linux pc, with positive results, but in the case of WSL 2, it's not working properly.

    I debugged the project, and I can conclude that the problem it's raised right here. I don't receive an error but blocks the execution, like an infinite loop.

    Thanks

    triaging 
    opened by davixcky 5
  • Anti-bot Example

    Anti-bot Example

    I am new to Playwright and went through the examples. I am wondering whether it is possible to use apify/fingerprint-injector and apify/fingerprint-generator with the Go version, or not?

    rod also provides an anti-bot example go-rod/stealth. I know Playwright turns the WebDriver flag off by default. But, I am looking for a more advanced and comprehensive solution/example.

    Thank you!

    opened by NuLL3rr0r 0
  • Does playwright-go has Stealth Mode support built-in?

    Does playwright-go has Stealth Mode support built-in?

    I've just head of Playwright-go and would like to evaluate it. One thing I need badly is Stealth Mode which could be used as Anti-Bot Detectoon similar to go-rod. I couldn't find anything in the examples/ folder for Playwright-go.

    opened by NuLL3rr0r 0
  • Error during installation

    Error during installation

    Since this morning i've tried the last 3 releases, but they all seem to fail on driver download.

    I receive the following error:

    2022/06/14 08:28:41 Downloading driver to /home/cage/.cache/ms-playwright-go/1.20.0-beta-1647057403000
    2022/06/14 08:28:56 could not install playwright: could not install driver: could not install driver: could not download driver: Get "https://playwright.azureedge.net/builds/driver/next/playwright-1.20.0-beta-1647057403000-linux.zip": stream error: stream ID 1; CANCEL
    

    Updated to latest version, but still getting the same error. Happens to anybody else or it is just me ?

    opened by Chimerax2 2
  • [PoC] feat: add web first assertions (#271)

    [PoC] feat: add web first assertions (#271)

    This is an implementation for web first assertions (#271).

    An example of usage is bellow,

    assertions := playwright.NewPlaywrightAssertions()
    
    err := assertions.ExpectLocator(locator).ToHaveText("example")
    if err != nil {
        // handle error
    }
    

    The current implementation still works, but I think there are some areas for improvements. Belows are some of my considerations.

    • PlaywrightAssertions interface is possibly unneeded. It may be simpler to call Expect function directory instead of through PlaywrightAssertions interface.
    // example
    
    err := playwright.ExpectLocator(locator).ToHaveText("example")
    
    • I'm not sure it's more useful to be integrated with *testing.T. Current implementation returns error to handle it by ourselves.
    // example
    
    assertions := playwright.NewPlaywrightAssertions(t) // `t` is `*testing.T`
    // no return value, error is reported in `ToHaveText` method
    assertions.ExpectLocator(locator).ToHaveText("example")
    

    There may be other improvements other than the above, so please let me know if anyone has some good ideas!

    opened by masaushi 3
  • [bug/issue] Locator option Has does not work correctly

    [bug/issue] Locator option Has does not work correctly

    I have 2 points about locators.

    1. When we create new Locator using Page we can pass PageLocatorOptions. But now if we pass Has option it does not work correctly and returns an error with message "Malformed token".

    For example, this code will return the error because of wrong selector concatenation.

      inputLocator, err := page.Locator("input[name='some']")
      require.NoError(t, err)
    
      listLocator, err := page.Locator("ul", playwright.PageLocatorOptions{Has: inputLocator})
      require.NoError(t, err)
    
       text, err := listLocator.InnerText()
    
    1. The Locator.Locator method does not have a LocatorLocatorOptions parameter. It would be very useful to add the ability to use this option
    p2-bug 
    opened by StanislavTaran 0
Releases(v0.2000.1)
  • v0.2000.1(Apr 27, 2022)

    What's Changed

    • feat: add locator functionality (#238) by @masaushi in https://github.com/playwright-community/playwright-go/pull/267
    • chore: add support for noViewport by @mxschmitt in https://github.com/playwright-community/playwright-go/pull/258
    • chore: rework parallel crawling example by @mxschmitt in https://github.com/playwright-community/playwright-go/pull/261
    • Add platform "mac-arm64" and "linux-arm64" by @zengxs in https://github.com/playwright-community/playwright-go/pull/264
    • chore: add IgnoreDefaultArgs by @zengxs in https://github.com/playwright-community/playwright-go/pull/265
    • chore: fix flaky network tests by @mxschmitt in https://github.com/playwright-community/playwright-go/pull/260

    New Contributors / Special thanks

    • @zengxs made their first contribution in https://github.com/playwright-community/playwright-go/pull/264
    • @masaushi made their first contribution in https://github.com/playwright-community/playwright-go/pull/267

    Thank you to both of you who invested time and effort into the project! 💯

    Full Changelog: https://github.com/playwright-community/playwright-go/compare/v0.2000.0...v0.2000.1

    Source code(tar.gz)
    Source code(zip)
  • v0.2000.0(Mar 12, 2022)

    This version is on pair drive-wise with the upcoming Playwright 1.20 version.

    Breaking change:

    You need to either install the driver+browsers via CLI or via the API. It does not happen automatically anymore.

    Via the CLI:

    go run github.com/playwright-community/playwright-go/cmd/playwright install
    # Or
    go install github.com/playwright-community/playwright-go/cmd/playwright
    playwright install --with-deps
    

    Or via the API:

    err := playwright.Install()
    
    Source code(tar.gz)
    Source code(zip)
  • v0.1400.0(Aug 27, 2021)

  • v0.1400(Aug 26, 2021)

  • v0.1100.0(Mar 28, 2021)

    • feat(install): allow to install and skip certain browser (#113)
    • docs: update link to Playwright API (#114)
    • fix(ElementHandle): don't panic when QuerySelector not exists (#112)
    Source code(tar.gz)
    Source code(zip)
  • v0.192-beta.1(Mar 16, 2021)

  • v0.171.1(Jan 4, 2021)

    Changelog:

    • chore: add Frame.Tap/Page.Tap/Page.Frame methods (#74)
    • chore: update readme on browser roll (#76)
    • chore: add missing methods (Tap/Touchscreen/WebSocket.IsClosed) (#78)
    • chore: restructure tests (#77)
    • feat: add websocket functionality and tests (#79)
    • feat: add Page on pageerror event (#82)
    • chore: waitForEvent cleanup (#81)
    • chore: cleanup inner core iteration 1 (#86)
    • chore: fix flaky websocket tests (#87)
    • tests: added BindingCall tests (#88)
    • tests: add more worker and element tests (#89)
    Source code(tar.gz)
    Source code(zip)
  • v0.171.0(Dec 29, 2020)

Owner
Max Schmitt
Open Source enthusiast, security researcher and full stack web developer.
Max Schmitt
Generate PlantUML diagrams from Chrome or Firefox network inspections

hoofli Generate PlantUML diagrams from Chrome or Firefox network inspections This tool reads browser HAR files stored on your local disk and transform

Pascal Dennerly 3 Feb 22, 2022
End to end functional test and automation framework

Declarative end to end functional testing (endly) This library is compatible with Go 1.12+ Please refer to CHANGELOG.md if you encounter breaking chan

Viant, Inc 209 Jun 26, 2022
A Devtools driver for web automation and scraping

Overview Documentation | API reference Rod is a high-level driver directly based on DevTools Protocol. It's designed for web automation and scraping.

Rod 2.5k Jun 29, 2022
Ritchie CLI is an open-source tool that allows to create, store and share any kind of automation, executing them through command lines, to run operations or start workflows ⚙️ 🖥 💡

Table of contents 1. About 2. Getting Started i. Installation ii. Initialize rit locally iii. Add your first formulas repository iv. Run the Hello Wor

ZUP IT INNOVATION 548 Jun 22, 2022
Go testing in the browser. Integrates with `go test`. Write behavioral tests in Go.

GoConvey is awesome Go testing Welcome to GoConvey, a yummy Go testing tool for gophers. Works with go test. Use it in the terminal or browser accordi

SmartyStreets 7.3k Jun 28, 2022
Go testing in the browser. Integrates with `go test`. Write behavioral tests in Go.

GoConvey is awesome Go testing Welcome to GoConvey, a yummy Go testing tool for gophers. Works with go test. Use it in the terminal or browser accordi

SmartyStreets 7.3k Jun 25, 2022
Selenium Hub successor running browsers within containers. Scalable, immutable, self hosted Selenium-Grid on any platform with single binary.

Selenoid Selenoid is a powerful implementation of Selenium hub using Docker containers to launch browsers. Features One-command Installation Start bro

Aerokube 2.2k Jun 23, 2022
fuzzer for a single http parameter which checks if the response does/does not contain a certain given string

single http parameter fuzzer DISCLAIMER: ONLY USE THIS PROGRAM ON TARGETS YOU HAVE PERMISSION TO FUZZ! Initially used as a "poor man's" http fuzzer fo

null 0 Dec 19, 2021
A Go library help testing your RESTful API application

RESTit A Go micro-framework to help writing RESTful API integration test Package RESTit provides helps to those who want to write an integration test

RESTit 55 Nov 25, 2021
Fortio load testing library, command line tool, advanced echo server and web UI in go (golang). Allows to specify a set query-per-second load and record latency histograms and other useful stats.

Fortio Fortio (Φορτίο) started as, and is, Istio's load testing tool and now graduated to be its own project. Fortio is also used by, among others, Me

Fortio (Φορτίο) 2.6k Jun 24, 2022
End-to-end HTTP and REST API testing for Go.

httpexpect Concise, declarative, and easy to use end-to-end HTTP and REST API testing for Go (golang). Basically, httpexpect is a set of chainable bui

Victor Gaydov 1.9k Jun 26, 2022
Lightweight service virtualization/API simulation tool for developers and testers

API simulations for development and testing Hoverfly is a lightweight, open source API simulation tool. Using Hoverfly, you can create realistic simul

null 1.9k Jun 25, 2022
This repository includes consumer driven contract test for provider, unit test and counter api.

This repository includes consumer driven contract test for provider, unit test and counter api.

Ahmet Zümberoğlu 0 Feb 1, 2022
A toolkit with common assertions and mocks that plays nicely with the standard library

Testify - Thou Shalt Write Tests ℹ️ We are working on testify v2 and would love to hear what you'd like to see in it, have your say here: https://cutt

Stretchr, Inc. 16.9k Jun 30, 2022
HTTP load testing tool and library. It's over 9000!

Vegeta Vegeta is a versatile HTTP load testing tool built out of a need to drill HTTP services with a constant request rate. It can be used both as a

Tomás Senart 19.8k Jun 27, 2022
A library for generating fake data such as names, addresses, and phone numbers.

faker Faker is a library for generating fake data such as names, addresses, and phone numbers. It is a (mostly) API-compatible port of Ruby Faker gem

Dmitri Goutnik 296 Jun 26, 2022
A WebDriver client and acceptance testing library for Go

Agouti Agouti is a library for writing browser-based acceptance tests in Google Go. It provides Gomega matchers and plays nicely with Ginkgo or Spec.

Stephen Levine 801 Jun 23, 2022
A simple and expressive HTTP server mocking library for end-to-end tests in Go.

mockhttp A simple and expressive HTTP server mocking library for end-to-end tests in Go. Installation go get -d github.com/americanas-go/mockhttp Exa

Americanas Go 6 Dec 19, 2021
Expressive end-to-end HTTP API testing made easy in Go

baloo Expressive and versatile end-to-end HTTP API testing made easy in Go (golang), built on top of gentleman HTTP client toolkit. Take a look to the

Tom 725 May 12, 2022