rod

package module
v0.51.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2020 License: MIT Imports: 34 Imported by: 689

README

Overview

GoDoc codecov goreport Discord Chat

logo

Rod is a High-level Devtools driver directly based on DevTools Protocol. It's designed for web automation and scraping. rod also tries to expose low-level interfaces to users, so that whenever a function is missing users can easily send control requests to the browser directly.

Features

  • Chained context design, intuitive to timeout or cancel the long-running task
  • Debugging friendly, auto input tracing, remote monitoring headless browser
  • Thread-safe for all operations
  • Automatically find or download browser
  • No external dependencies, CI tested on Linux, Mac, and Windows
  • High-level helpers like WaitStable, WaitRequestIdle, HijackRequests, GetDownloadFile, etc
  • Two-step WaitEvent design, never miss an event
  • Correctly handles nested iframes
  • No zombie browser process after the crash (how it works)

Examples

Please check the examples_test.go file first, then check the examples folder.

For more detailed examples, please search the unit tests. Such as the usage of method HandleAuth, you can search all the *_test.go files that contain HandleAuth or HandleAuthE, for example, use Github online search in repository. You can also search the GitHub issues, they contain a lot of usage examples too.

Here is a comparison of the examples between rod and chromedp.

If you have questions, please raise an issue or join the chat room.

How it works

Here's the common start process of rod:

  1. Try to connect to a Devtools endpoint (WebSocket), if not found try to launch a local browser, if still not found try to download one, then connect again. The lib to handle it is launcher.

  2. Use the JSON-RPC to talk to the Devtools endpoint to control the browser. The lib handles it is cdp.

  3. The type definitions of the JSON-RPC are in lib proto.

  4. To control a specific page, rod will first inject a js helper script to it. rod uses it to query and manipulate the page content. The js lib is in assets.

Object model:

object model

FAQ

TOC
Q: How to use rod with docker

To let rod work with docker is very easy:

  1. Run the rod image docker run -p 9222:9222 rodorg/rod

  2. Open another terminal and run a go program like this example

The rod image can dynamically launch a browser for each remote driver with customizable browser flags. It's tuned for screenshots and fonts among popular natural languages. You can easily load balance requests to the cluster of this image, each container can create multiple browser instances at the same time.

You can also use it to launch a browser manually:

docker run -p 9222:9222 rodorg/rod chromium-browser --headless --no-sandbox --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0
Q: Why there is always an "about:blank" page

It's an issue of the browser itself. If we enable the --no-first-run flag and we don't create a blank page, it will create a hello page which will consume more power.

Q: Does it support other browsers like Firefox or Edge

Rod should work with any browser that supports DevTools Protocol.

  • Microsoft Edge can pass all the unit tests.
  • Firefox is supporting this protocol.
  • Safari doesn't have any plan to support it yet.
  • IE won't support it.
Q: Why is it called rod

Rod is related to puppetry, see rod Puppet. So we are the puppeteer, the browser is the puppet, we use the rod to control the puppet. So in this sense, puppeteer.js sounds strange, we are controlling a puppeteer?

Q: How to contribute

Please check this doc.

Q: How versioning is handled

Semver is used.

Before v1.0.0 whenever the second section changed, such as v0.1.0 to v0.2.0, there must be some public API changes, such as changes of function names or parameter types. If only the last section changed, no public API will be changed.

You can use the Github's release comparison to see the automated changelog, for example, compare v0.44.2 with v0.44.0.

Q: Why another puppeteer like lib

There are a lot of great projects, but no one is perfect, choose the best one that fits your needs is important.

  • chromedp

    For direct code comparison you can check here. If you compare the example called logic between rod and chromedp, you will find out how much simpler rod is.

    With chromedp, you have to use their verbose DSL like tasks to handle the main logic, because chromedp uses several wrappers to handle execution with context and options which makes it very hard to understand their code when bugs happen. The heavily used interfaces also makes the static types useless when tracking issues. In contrast, rod uses classical object model to abstract browser, page, and element.

    The main problem of chromedp is their architecture is based on DOM node id, but puppeteer and rod are based on remote object id. In consequence, it will prevent chromedp's maintainers from adding high-level functions that are coupled with runtime. For example, this ticket had opened for 3 years.

    Rod is more configurable, such as you can even replace the WebSocket lib with the lib you like.

    When a crash happens, chromedp will leave the zombie browser process on Windows and Mac.

    Rod has a simpler code structure and better test coverage, you should find it's easier to contribute code to rod. Therefore compared with chromedp, rod has the potential to have more nice functions from the community in the future.

  • puppeteer

    With puppeteer, you have to handle promise/async/await a lot. End to end tests requires a lot of sync operations to simulate human inputs, because Puppeteer is based on Nodejs all IO operations are async calls, so usually, people end up typing tons of async/await. The overhead grows when your project grows.

    Rod is type-safe by default. It has type bindings with all the API of Devtools protocol.

    Rod will disable domain events whenever possible, puppeteer will always enable all the domains. It will consume a lot of resources when driving a remote browser.

  • selenium

    Selenium is based on webdriver protocol which has much less functions compare to devtools protocol. Such as it can't handle closed shadow DOM. No way to save page as PDF. No support for tools like Profiler or Performance, etc.

    Harder to set up and maintain because of extra dependencies like a browser driver.

    Though selenium sells itself for better cross-browser support, it's usually very hard to make it work for all major browsers.

    There are plenty of articles about "selenium vs puppeteer", you can treat rod as the Golang version of puppeteer.

  • cypress

    Cypress is very limited, for closed shadow dom or cross-domain iframes it's almost unusable. Read their limitation doc for more details.

    If you want to cooperate with us to create a testing focused framework base on rod to overcome the limitation of cypress, please contact us.

Documentation

Overview

Example (Basic)

Example_basic is a simple test that opens https://github.com/, searches for "git", and then gets the header element which gives the description for Git.

package main

import (
	"context"
	"errors"
	"fmt"
	"time"

	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/input"
)

func main() {
	// Launch a new browser with default options, and connect to it.
	browser := rod.New().MustConnect()

	// Even you forget to close, rod will close it after main process ends.
	defer browser.MustClose()

	// Timeout will be passed to all chained function calls.
	// The code will panic out if any chained call is used after the timeout.
	page := browser.Timeout(time.Minute).MustPage("https://github.com")

	// Make sure viewport is always consistent.
	page.MustViewport(1200, 600, 1, false)

	// We use css selector to get the search input element and input "git"
	page.MustElement("input").MustInput("git").MustPress(input.Enter)

	// Wait until css selector get the element then get the text content of it.
	// You can also pass multiple selectors to race the result, useful when dealing with multiple possible results.
	text := page.MustElement(".codesearch-results p").MustText()

	fmt.Println(text)

	// Get all input elements. Rod supports query elements by css selector, xpath, and regex.
	// For more detailed usage, check the query_test.go file.
	fmt.Println(len(page.MustElements("input")))

	// Eval js on the page
	page.MustEval(`console.log("hello world")`)

	// Pass parameters as json objects to the js function. This one will return 3
	fmt.Println(page.MustEval(`(a, b) => a + b`, 1, 2).Int())

	// When eval on an element, you can use "this" to access the DOM element.
	fmt.Println(page.MustElement("title").MustEval(`this.innerText`).String())

	// To handle errors in rod, you can use rod.Try or E suffixed function family like "page.ElementE"
	// https://github.com/go-rod/rod#q-why-functions-dont-return-error-values
	err := rod.Try(func() {
		// Here we will catch timeout or query error
		page.Timeout(time.Second / 2).MustElement("element-not-exists")
	})
	if errors.Is(err, context.DeadlineExceeded) {
		fmt.Println("after 0.5 seconds, the element is still not rendered")
	}

}
Output:

Git is the most widely used version control system.
5
3
Search · git · GitHub
after 0.5 seconds, the element is still not rendered
Example (Customize_browser_launch)

Example_customize_browser_launch will show how we can further customise the browser with the launcher library. The launcher lib comes with many default flags (switches), this example adds and removes a few.

package main

import (
	"fmt"

	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/launcher"
)

func main() {
	// Documentation for default switches can be found at the source of the
	// launcher.New function, as well as at
	// https://peter.sh/experiments/chromium-command-line-switches/.
	url := launcher.New().
		// Set a flag- Adding the HTTP proxy server.
		Set("proxy-server", "127.0.0.1:8080").
		// Delete a flag- remove the mock-keychain flag
		Delete("use-mock-keychain").
		MustLaunch()

	browser := rod.New().ControlURL(url).MustConnect()
	defer browser.MustClose()

	// Adding authentication to the proxy, for the next auth request.
	// We use CLI tool "mitmproxy --proxyauth user:pass" as an example.
	browser.MustHandleAuth("user", "pass")

	// mitmproxy needs a cert config to support https. We use http here instead,
	// for example
	fmt.Println(browser.MustPage("http://example.com/").MustElement("title").MustText())

	// Skip
	
Output:

Example (Customize_retry_strategy)

Example_customize_retry_strategy allows us to change the retry/polling options that is used to query elements. This is useful when you want to customize the element query retry logic.

package main

import (
	"context"
	"errors"
	"fmt"
	"time"

	"github.com/go-rod/rod"
)

func main() {
	browser := rod.New().Timeout(time.Minute).MustConnect()
	defer browser.MustClose()

	page := browser.MustPage("https://github.com")

	// sleep for 0.5 seconds before every retry
	sleeper := func(context.Context) error {
		time.Sleep(time.Second / 2)
		return nil
	}
	el, _ := page.Sleeper(sleeper).Element("input")

	// If sleeper is nil page.ElementE will query without retrying.
	// If nothing found it will return an error.
	el, err := page.Sleeper(nil).Element("input")
	if errors.Is(err, rod.ErrElementNotFound) {
		fmt.Println("element not found")
	} else if err != nil {
		panic(err)
	}

	fmt.Println(el.MustEval(`this.name`).String())

}
Output:

q
Example (Direct_cdp)

Example_direct_cdp shows how we can use Rod when it doesn't have a function or a feature that you would like to use. You can easily call the cdp interface.

package main

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/proto"
)

func main() {
	browser := rod.New().Timeout(time.Minute).MustConnect()
	defer browser.MustClose()

	// The code here shows how SetCookies works.
	// Normally, you use something like
	// browser.Page("").SetCookies(...).Navigate(url).

	page := browser.MustPage("")

	// Call the cdp interface directly.
	// We set the cookie before we visit the website.
	// The "proto" lib contains every JSON schema you may need to communicate
	// with browser
	res, err := proto.NetworkSetCookie{
		Name:  "rod",
		Value: "test",
		URL:   "https://example.com",
	}.Call(page)
	if err != nil {
		panic(err)
	}

	fmt.Println(res.Success)

	page.MustNavigate("https://example.com")

	// Eval injects a script into the page. We use this to return the cookies
	// that JS detects to validate our cdp call.
	cookie := page.MustEval(`document.cookie`).String()

	fmt.Println(cookie)

	// You can also use your own raw JSON to send a json request.
	params, _ := json.Marshal(map[string]string{
		"name":  "rod",
		"value": "test",
		"url":   "https://example.com",
	})
	ctx, client, sessionID := page.CallContext()
	_, _ = client.Call(ctx, sessionID, "Network.SetCookie", params)

}
Output:

true
rod=test
Example (Handle_events)

Example_handle_events is an example showing how we can use Rod to subscribe to events.

package main

import (
	"fmt"
	"time"

	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/proto"
)

func main() {
	browser := rod.New().Timeout(time.Minute).MustConnect()
	defer browser.MustClose()

	page := browser.MustPage("")

	done := make(chan int)

	// Listen to all events of console output.
	go page.EachEvent(func(e *proto.RuntimeConsoleAPICalled) {
		log := page.MustObjectsToJSON(e.Args).Join(" ")
		fmt.Println(log)
		close(done)
	})()

	wait := page.WaitEvent(&proto.PageLoadEventFired{})
	page.MustNavigate("https://example.com")
	wait()

	// EachEvent allows us to achieve the same functionality as above.
	if false {
		// Subscribe events before they happen, run the "wait()" to start consuming
		// the events. We can return an optional stop signal unsubscribe events.
		wait := page.EachEvent(func(e *proto.PageLoadEventFired) (stop bool) {
			return true
		})
		page.MustNavigate("https://example.com")
		wait()
	}

	page.MustEval(`console.log("hello", "world")`)

	<-done

}
Output:

hello world
Example (Headless_with_debug)

Example_headless_with_debug shows how we can start a browser with debug information and headless mode disabled to show the browser in the foreground. Rod provides a lot of debug options, you can use the Set method to enable them or use environment variables. (Default environment variables can be found in "lib/defaults").

package main

import (
	"fmt"
	"time"

	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/input"
	"github.com/go-rod/rod/lib/launcher"
)

func main() {
	// Headless runs the browser on foreground, you can also use env "rod=show"
	// Devtools opens the tab in each new tab opened automatically
	l := launcher.New().
		Headless(false).
		Devtools(true)
	defer l.Cleanup()
	url := l.MustLaunch()

	// Trace shows verbose debug information for each action executed
	// Slowmotion is a debug related function that waits 2 seconds between
	// each action, making it easier to inspect what your code is doing.
	browser := rod.New().
		Timeout(time.Minute).
		ControlURL(url).
		Trace(true).
		Slowmotion(2 * time.Second).
		MustConnect()

	// ServeMonitor plays screenshots of each tab. This feature is extremely
	// useful when debugging with headless mode.
	browser.ServeMonitor(":9777", true)

	defer browser.MustClose()

	page := browser.MustPage("https://www.wikipedia.org/")

	page.MustElement("#searchLanguage").MustSelect("[lang=zh]")
	page.MustElement("#searchInput").MustInput("热干面")
	page.Keyboard.MustPress(input.Enter)

	fmt.Println(page.MustElement("#firstHeading").MustText())

	// Response gets the binary of the image as a []byte.
	img := page.MustElement(`[alt="Hot Dry Noodles.jpg"]`).MustResource()
	fmt.Println(len(img)) // print the size of the image

	// Pause temporarily halts JavaScript execution on the website.
	// You can resume execution in the devtools window by clicking the resume
	// button in the "source" tab.
	page.MustPause()

	// Skip
	
Output:

Example (Hijack_requests)

Example_hijack_requests shows how we can intercept requests and modify both the request and the response.

package main

import (
	"fmt"
	"time"

	"github.com/go-rod/rod"
)

func main() {
	browser := rod.New().Timeout(time.Minute).MustConnect()
	defer browser.MustClose()

	router := browser.HijackRequests()
	defer router.MustStop()

	router.MustAdd("*.js", func(ctx *rod.Hijack) {
		// Here we update the request's header. Rod gives functionality to
		// change or update all parts of the request. Refer to the documentation
		// for more information.
		ctx.Request.SetHeader("My-Header", "test")

		// LoadResponse runs the default request to the destination of the request.
		// Not calling this will require you to mock the entire response.
		// This can be done with the SetXxx (Status, Header, Body) functions on the
		// response struct.
		ctx.MustLoadResponse()

		// Here we append some code to every js file.
		// The code will update the document title to "hi"
		ctx.Response.SetBody(ctx.Response.StringBody() + "\n document.title = 'hi' ")
	})

	go router.Run()

	browser.MustPage("https://www.wikipedia.org/").MustWait(`document.title === 'hi'`)

	fmt.Println("done")

}
Output:

done
Example (States)

Example_states allows us to update the state of the current page. In this example we enable network access.

package main

import (
	"fmt"
	"time"

	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/proto"
)

func main() {
	browser := rod.New().Timeout(time.Minute).MustConnect()
	defer browser.MustClose()

	page := browser.MustPage("")

	// LoadState detects whether the  network is enabled or not.
	fmt.Println(page.LoadState(&proto.NetworkEnable{}))

	_ = proto.NetworkEnable{}.Call(page)

	// Now that we called the request on the page, we check see if the state
	// result updates to true.
	fmt.Println(page.LoadState(&proto.NetworkEnable{}))

}
Output:

false
true
Example (Wait_for_animation)

Example_wait_for_animation is an example to simulate humans more accurately. If a button is moving too fast, you cannot click it as a human. To more accurately simulate human inputs, actions triggered by Rod can be based on mouse point location, so you can allow Rod to wait for the button to become stable before it tries clicking it.

package main

import (
	"fmt"
	"time"

	"github.com/go-rod/rod"
)

func main() {
	browser := rod.New().Timeout(time.Minute).MustConnect()
	defer browser.MustClose()

	page := browser.MustPage("https://getbootstrap.com/docs/4.0/components/modal/")

	page.MustWaitLoad().MustElement("[data-target='#exampleModalLive']").MustClick()

	saveBtn := page.MustElementMatches("#exampleModalLive button", "Close")

	// Here, WaitStable will wait until the save button's position becomes
	// stable. The timeout is 5 seconds, after which it times out (or after 1
	// minute since the browser was created). Timeouts from parents are
	// inherited to the children as well.
	saveBtn.Timeout(5 * time.Second).MustWaitStable().MustClick().MustWaitInvisible()

	fmt.Println("done")

}
Output:

done
Example (Wait_for_request)

Example_wait_for_request shows an example where Rod will wait for all requests on the page to complete (such as network request) before interacting with the page.

package main

import (
	"fmt"
	"time"

	"github.com/go-rod/rod"
)

func main() {
	browser := rod.New().Timeout(time.Minute).MustConnect()
	defer browser.MustClose()

	page := browser.MustPage("https://duckduckgo.com/")

	// WaitRequestIdle will wait for all possible ajax calls to complete before
	// continuing on with further execution calls.
	wait := page.MustWaitRequestIdle()
	page.MustElement("#search_form_input_homepage").MustClick().MustInput("test")
	time.Sleep(300 * time.Millisecond) // Wait for js debounce.
	wait()

	// We want to make sure that after waiting, there are some autocomplete
	// suggestions available.
	fmt.Println(len(page.MustElements(".search__autocomplete .acp")) > 0)

}
Output:

true

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrValue error
	ErrValue = errors.New("error value")
	// ErrExpectElement error
	ErrExpectElement = errors.New("expect js to return an element")
	// ErrExpectElements error
	ErrExpectElements = errors.New("expect js to return an array of elements")
	// ErrElementNotFound error
	ErrElementNotFound = errors.New("cannot find element")
	// ErrWaitJSTimeout error
	ErrWaitJSTimeout = errors.New("wait js timeout")
	// ErrSrcNotFound error
	ErrSrcNotFound = errors.New("element doesn't have src attribute")
	// ErrEval error
	ErrEval = errors.New("eval error")
	// ErrNavigation error
	ErrNavigation = errors.New("navigation failed")
	// ErrNotClickable error
	ErrNotClickable = errors.New("element is not clickable")
)

Sleeper is the default sleeper for retry, it uses backoff to grow the interval. The growth looks like: A(0) = 100ms, A(n) = A(n-1) * random[1.9, 2.1), A(n) < 1s

Functions

func Event

func Event(msg *cdp.Event, evt proto.Payload) bool

Event helps to convert a cdp.Event to proto.Payload. Returns false if the conversion fails

func SprintFnThis

func SprintFnThis(js string) string

SprintFnThis wrap js with this, wrap function call if it's js expression

func Try added in v0.46.0

func Try(fn func()) (err error)

Try try fn with recover, return the panic as value

Types

type Array

type Array []interface{}

Array of any type

func ArrayFromList added in v0.45.0

func ArrayFromList(list interface{}) Array

ArrayFromList converts a random list into Array type

type Browser

type Browser struct {

	// BrowserContextID is the id for incognito window
	BrowserContextID proto.BrowserBrowserContextID
	// contains filtered or unexported fields
}

Browser represents the browser It doesn't depends on file system, it should work with remote browser seamlessly. To check the env var you can use to quickly enable options from CLI, check here: https://pkg.go.dev/github.com/go-rod/rod/lib/defaults

func New

func New() *Browser

New creates a controller

func (*Browser) CDPCall added in v0.49.0

func (b *Browser) CDPCall(c CDPCall) *Browser

CDPCall overrides the cdp.Client.Call

func (*Browser) Call

func (b *Browser) Call(ctx context.Context, sessionID, methodName string, params json.RawMessage) (res []byte, err error)

Call raw cdp interface directly

func (*Browser) CallContext

func (b *Browser) CallContext() (context.Context, proto.Client, string)

CallContext parameters for proto

func (*Browser) CancelTimeout

func (b *Browser) CancelTimeout() *Browser

CancelTimeout context

func (*Browser) Client

func (b *Browser) Client(c *cdp.Client) *Browser

Client set the cdp client

func (*Browser) Close

func (b *Browser) Close() error

Close doc is similar to the method MustClose

func (*Browser) Connect

func (b *Browser) Connect() (err error)

Connect doc is similar to the method MustConnect

func (*Browser) Context

func (b *Browser) Context(ctx context.Context, cancel func()) *Browser

Context creates a clone with a context that inherits the previous one

func (*Browser) ControlURL

func (b *Browser) ControlURL(url string) *Browser

ControlURL set the url to remote control browser.

func (*Browser) DefaultViewport added in v0.49.3

func (b *Browser) DefaultViewport(viewport *proto.EmulationSetDeviceMetricsOverride) *Browser

DefaultViewport sets the default viewport for new page in the future. Default size is 1200x900. Set it to nil to disable it.

func (*Browser) DisableDomain

func (b *Browser) DisableDomain(ctx context.Context, sessionID proto.TargetSessionID, method proto.Payload) (recover func())

DisableDomain and returns a recover function to restore previous state

func (*Browser) EachEvent

func (b *Browser) EachEvent(fn interface{}) (wait func())

EachEvent of the specified event type, if the fn returns true the event loop will stop. The fn can accpet multiple events, such as EachEvent(func(e1 *proto.PageLoadEventFired, e2 *proto.PageLifecycleEvent) {}), only one argument will be non-null, others will null.

func (*Browser) EnableDomain

func (b *Browser) EnableDomain(ctx context.Context, sessionID proto.TargetSessionID, method proto.Payload) (recover func())

EnableDomain and returns a recover function to restore previous state

func (*Browser) Event

func (b *Browser) Event() *goob.Observable

Event returns the observable for browser events

func (*Browser) GetContext

func (b *Browser) GetContext() context.Context

GetContext returns the current context

func (*Browser) HandleAuth

func (b *Browser) HandleAuth(username, password string) func() error

HandleAuth for the next basic HTTP authentication. It will prevent the popup that requires user to input user name and password. Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication

func (*Browser) HijackRequests

func (b *Browser) HijackRequests() *HijackRouter

HijackRequests creates a new router instance for requests hijacking. When use Fetch domain outside the router should be stopped. Enabling hijacking disables page caching, but such as 304 Not Modified will still work as expected.

func (*Browser) Incognito

func (b *Browser) Incognito() (*Browser, error)

Incognito creates a new incognito browser

func (*Browser) LoadState

func (b *Browser) LoadState(sessionID proto.TargetSessionID, method proto.Payload) (has bool)

LoadState into the method, seesionID can be empty.

func (*Browser) MustClose added in v0.50.0

func (b *Browser) MustClose()

MustClose the browser and release related resources

func (*Browser) MustConnect added in v0.50.0

func (b *Browser) MustConnect() *Browser

MustConnect to the browser and start to control it. If fails to connect, try to run a local browser, if local browser not found try to download one.

func (*Browser) MustHandleAuth added in v0.50.0

func (b *Browser) MustHandleAuth(username, password string)

MustHandleAuth for the next basic HTTP authentication. It will prevent the popup that requires user to input user name and password. Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication

func (*Browser) MustIncognito added in v0.50.0

func (b *Browser) MustIncognito() *Browser

MustIncognito creates a new incognito browser

func (*Browser) MustPage added in v0.50.0

func (b *Browser) MustPage(url string) *Page

MustPage creates a new tab If url is empty, the default target will be "about:blank".

func (*Browser) MustPageFromTargetID added in v0.50.0

func (b *Browser) MustPageFromTargetID(targetID proto.TargetTargetID) *Page

MustPageFromTargetID creates a Page instance from a targetID

func (*Browser) MustPages added in v0.50.0

func (b *Browser) MustPages() Pages

MustPages returns all visible pages

func (*Browser) Page

func (b *Browser) Page(url string) (*Page, error)

Page doc is similar to the method MustPage If url is empty, the default target will be "about:blank".

func (*Browser) PageFromTarget added in v0.50.0

func (b *Browser) PageFromTarget(targetID proto.TargetTargetID) (*Page, error)

PageFromTarget creates a Page instance from a targetID

func (*Browser) Pages

func (b *Browser) Pages() (Pages, error)

Pages doc is similar to the method MustPages

func (*Browser) Quiet added in v0.43.1

func (b *Browser) Quiet(quiet bool) *Browser

Quiet enables/disables log of the. Only useful when Trace is set to true.

func (*Browser) ServeMonitor

func (b *Browser) ServeMonitor(host string, openBrowser bool) *kit.ServerContext

ServeMonitor starts the monitor server. If openBrowser is true, it will try to launcher a browser to play the screenshots. The reason why not to use "chrome://inspect/#devices" is one target cannot be driven by multiple controllers.

func (*Browser) Sleeper added in v0.50.0

func (b *Browser) Sleeper(sleeper kit.Sleeper) *Browser

Sleeper for chained sub-operations

func (*Browser) Slowmotion

func (b *Browser) Slowmotion(delay time.Duration) *Browser

Slowmotion set the delay for each control action, such as the simulation of the human inputs

func (*Browser) Timeout

func (b *Browser) Timeout(d time.Duration) *Browser

Timeout for chained sub-operations

func (*Browser) Trace

func (b *Browser) Trace(enable bool) *Browser

Trace enables/disables the visual tracing of the input actions on the page

func (*Browser) TraceLog added in v0.46.5

func (b *Browser) TraceLog(msg func(string), js func(string, Array), err func(error)) *Browser

TraceLog overrides the default log functions for trace

func (*Browser) WaitEvent

func (b *Browser) WaitEvent(e proto.Payload) (wait func())

WaitEvent waits for the next event for one time. It will also load the data into the event object.

type CDPCall added in v0.49.0

type CDPCall func(ctx context.Context, sessionID, method string, params interface{}) ([]byte, error)

CDPCall type for cdp.Client.CDPCall

type Element

type Element struct {
	ObjectID proto.RuntimeRemoteObjectID
	// contains filtered or unexported fields
}

Element represents the DOM element

func (*Element) Attribute

func (el *Element) Attribute(name string) (*string, error)

Attribute is similar to the method Attribute

func (*Element) Blur

func (el *Element) Blur() error

Blur is similar to the method Blur

func (*Element) Box

func (el *Element) Box() (*proto.DOMRect, error)

Box returns the size of an element and its position relative to the main frame.

func (*Element) CallContext

func (el *Element) CallContext() (context.Context, proto.Client, string)

CallContext parameters for proto

func (*Element) CancelTimeout

func (el *Element) CancelTimeout() *Element

CancelTimeout context

func (*Element) CanvasToImage added in v0.45.1

func (el *Element) CanvasToImage(format string, quality float64) ([]byte, error)

CanvasToImage get image data of a canvas. The default format is image/png. The default quality is 0.92. doc: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL

func (*Element) Click

func (el *Element) Click(button proto.InputMouseButton) error

Click will press then release the button just like a human.

func (*Element) Clickable added in v0.48.0

func (el *Element) Clickable() (bool, error)

Clickable checks if the element is behind another element, such as when invisible or covered by a modal.

func (*Element) ContainsElement added in v0.48.0

func (el *Element) ContainsElement(target *Element) (bool, error)

ContainsElement check if the target is equal or inside the element.

func (*Element) Context

func (el *Element) Context(ctx context.Context, cancel func()) *Element

Context creates a clone with a context that inherits the previous one

func (*Element) Describe

func (el *Element) Describe(depth int, pierce bool) (*proto.DOMNode, error)

Describe doc is similar to the method MustDescribe please see https://chromedevtools.github.io/devtools-protocol/tot/DOM/#method-describeNode

func (*Element) Element

func (el *Element) Element(selectors ...string) (*Element, error)

Element doc is similar to the method MustElement

func (*Element) ElementByJS

func (el *Element) ElementByJS(opts *EvalOptions) (*Element, error)

ElementByJS doc is similar to the method MustElementByJS

func (*Element) ElementMatches

func (el *Element) ElementMatches(pairs ...string) (*Element, error)

ElementMatches doc is similar to the method MustElementMatches

func (*Element) ElementX

func (el *Element) ElementX(xPaths ...string) (*Element, error)

ElementX doc is similar to the method MustElementX

func (*Element) Elements

func (el *Element) Elements(selector string) (Elements, error)

Elements doc is similar to the method MustElements

func (*Element) ElementsByJS

func (el *Element) ElementsByJS(opts *EvalOptions) (Elements, error)

ElementsByJS doc is similar to the method MustElementsByJS

func (*Element) ElementsX

func (el *Element) ElementsX(xpath string) (Elements, error)

ElementsX doc is similar to the method MustElementsX

func (*Element) Eval

func (el *Element) Eval(js string, params ...interface{}) (*proto.RuntimeRemoteObject, error)

Eval doc is similar to the method MustEval

func (*Element) EvalWithOptions added in v0.50.0

func (el *Element) EvalWithOptions(opts *EvalOptions) (*proto.RuntimeRemoteObject, error)

EvalWithOptions of Eval

func (*Element) Focus

func (el *Element) Focus() error

Focus doc is similar to the method MustFocus

func (*Element) Frame

func (el *Element) Frame() *Page

Frame creates a page instance that represents the iframe

func (*Element) GetContext

func (el *Element) GetContext() context.Context

GetContext returns the current context

func (*Element) HTML

func (el *Element) HTML() (string, error)

HTML doc is similar to the method MustHTML

func (*Element) Has

func (el *Element) Has(selector string) (bool, error)

Has doc is similar to the method MustHas

func (*Element) HasMatches

func (el *Element) HasMatches(selector, regex string) (bool, error)

HasMatches doc is similar to the method MustHasMatches

func (*Element) HasX

func (el *Element) HasX(selector string) (bool, error)

HasX doc is similar to the method MustHasX

func (*Element) Hover added in v0.49.1

func (el *Element) Hover() error

Hover the mouse over the center of the element.

func (*Element) Input

func (el *Element) Input(text string) error

Input doc is similar to the method MustInput

func (*Element) Matches added in v0.45.0

func (el *Element) Matches(selector string) (bool, error)

Matches checks if the element can be selected by the css selector

func (*Element) MustAttribute added in v0.50.0

func (el *Element) MustAttribute(name string) *string

MustAttribute returns the value of a specified attribute on the element. Please check the Property function before you use it, usually you don't want to use MustAttribute. https://stackoverflow.com/questions/6003819/what-is-the-difference-between-properties-and-attributes-in-html

func (*Element) MustBlur added in v0.50.0

func (el *Element) MustBlur() *Element

MustBlur will call the blur function on the element. On inputs, this will deselect the element.

func (*Element) MustBox added in v0.50.0

func (el *Element) MustBox() *proto.DOMRect

MustBox returns the size of an element and its position relative to the main frame.

func (*Element) MustCanvasToImage added in v0.50.0

func (el *Element) MustCanvasToImage(format string, quality float64) []byte

MustCanvasToImage get image data of a canvas. The default format is image/png. The default quality is 0.92. doc: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL

func (*Element) MustClick added in v0.50.0

func (el *Element) MustClick() *Element

MustClick the element

func (*Element) MustClickable added in v0.50.0

func (el *Element) MustClickable() bool

MustClickable checks if the element is behind another element, such as when covered by a modal.

func (*Element) MustContainsElement added in v0.50.0

func (el *Element) MustContainsElement(target *Element) bool

MustContainsElement check if the target is equal or inside the element.

func (*Element) MustDescribe added in v0.50.0

func (el *Element) MustDescribe() *proto.DOMNode

MustDescribe returns the element info Returned json: https://chromedevtools.github.io/devtools-protocol/tot/DOM#type-Node

func (*Element) MustElement added in v0.50.0

func (el *Element) MustElement(selector string) *Element

MustElement returns the first child that matches the css selector

func (*Element) MustElementByJS added in v0.50.0

func (el *Element) MustElementByJS(js string, params ...interface{}) *Element

MustElementByJS returns the element from the return value of the js

func (*Element) MustElementMatches added in v0.50.0

func (el *Element) MustElementMatches(selector, regex string) *Element

MustElementMatches returns the first element in the page that matches the CSS selector and its text matches the regex. The regex is the js regex, not golang's.

func (*Element) MustElementX added in v0.50.0

func (el *Element) MustElementX(xpath string) *Element

MustElementX returns the first child that matches the XPath selector

func (*Element) MustElements added in v0.50.0

func (el *Element) MustElements(selector string) Elements

MustElements returns all elements that match the css selector

func (*Element) MustElementsByJS added in v0.50.0

func (el *Element) MustElementsByJS(js string, params ...interface{}) Elements

MustElementsByJS returns the elements from the return value of the js

func (*Element) MustElementsX added in v0.50.0

func (el *Element) MustElementsX(xpath string) Elements

MustElementsX returns all elements that match the XPath selector

func (*Element) MustEval added in v0.50.0

func (el *Element) MustEval(js string, params ...interface{}) proto.JSON

MustEval evaluates js function on the element, the first param must be a js function definition For example: el.MustEval(`name => this.getAttribute(name)`, "value")

func (*Element) MustFocus added in v0.50.0

func (el *Element) MustFocus() *Element

MustFocus sets focus on the specified element

func (*Element) MustHTML added in v0.50.0

func (el *Element) MustHTML() string

MustHTML gets the outerHTML of the element

func (*Element) MustHas added in v0.50.0

func (el *Element) MustHas(selector string) bool

MustHas an element that matches the css selector

func (*Element) MustHasMatches added in v0.50.0

func (el *Element) MustHasMatches(selector, regex string) bool

MustHasMatches an element that matches the css selector and its text matches the regex.

func (*Element) MustHasX added in v0.50.0

func (el *Element) MustHasX(selector string) bool

MustHasX an element that matches the XPath selector

func (*Element) MustHover added in v0.50.0

func (el *Element) MustHover() *Element

MustHover the mouse over the center of the element.

func (*Element) MustInput added in v0.50.0

func (el *Element) MustInput(text string) *Element

MustInput wll click the element and input the text. To empty the input you can use something like el.SelectAllText().MustInput("")

func (*Element) MustMatches added in v0.50.0

func (el *Element) MustMatches(selector string) bool

MustMatches checks if the element can be selected by the css selector

func (*Element) MustNext added in v0.50.0

func (el *Element) MustNext() *Element

MustNext returns the next sibling element

func (*Element) MustNodeID added in v0.50.0

func (el *Element) MustNodeID() proto.DOMNodeID

MustNodeID of the node

func (*Element) MustParent added in v0.50.0

func (el *Element) MustParent() *Element

MustParent returns the parent element

func (*Element) MustParents added in v0.50.0

func (el *Element) MustParents(selector string) Elements

MustParents that match the selector

func (*Element) MustPress added in v0.50.0

func (el *Element) MustPress(key rune) *Element

MustPress a key

func (*Element) MustPrevious added in v0.50.0

func (el *Element) MustPrevious() *Element

MustPrevious returns the previous sibling element

func (*Element) MustProperty added in v0.50.0

func (el *Element) MustProperty(name string) proto.JSON

MustProperty returns the value of a specified property on the element. It's similar to Attribute but attributes can only be string, properties can be types like bool, float, etc. https://stackoverflow.com/questions/6003819/what-is-the-difference-between-properties-and-attributes-in-html

func (*Element) MustRelease added in v0.50.0

func (el *Element) MustRelease()

MustRelease remote object on browser

func (*Element) MustResource added in v0.50.0

func (el *Element) MustResource() []byte

MustResource returns the binary of the "src" properly, such as the image or audio file.

func (*Element) MustScreenshot added in v0.50.0

func (el *Element) MustScreenshot(toFile ...string) []byte

MustScreenshot of the area of the element

func (*Element) MustScrollIntoView added in v0.50.0

func (el *Element) MustScrollIntoView() *Element

MustScrollIntoView scrolls the current element into the visible area of the browser window if it's not already within the visible area.

func (*Element) MustSelect added in v0.50.0

func (el *Element) MustSelect(selectors ...string) *Element

MustSelect the option elements that match the selectors, the selector can be text content or css selector

func (*Element) MustSelectAllText added in v0.50.0

func (el *Element) MustSelectAllText() *Element

MustSelectAllText selects all text

func (*Element) MustSelectText added in v0.50.0

func (el *Element) MustSelectText(regex string) *Element

MustSelectText selects the text that matches the regular expression

func (*Element) MustSetFiles added in v0.50.0

func (el *Element) MustSetFiles(paths ...string) *Element

MustSetFiles sets files for the given file input element

func (*Element) MustShadowRoot added in v0.50.0

func (el *Element) MustShadowRoot() *Element

MustShadowRoot returns the shadow root of this element

func (*Element) MustText added in v0.50.0

func (el *Element) MustText() string

MustText gets the innerText of the element

func (*Element) MustVisible added in v0.50.0

func (el *Element) MustVisible() bool

MustVisible returns true if the element is visible on the page

func (*Element) MustWait added in v0.50.0

func (el *Element) MustWait(js string, params ...interface{}) *Element

MustWait until the js returns true

func (*Element) MustWaitInvisible added in v0.50.0

func (el *Element) MustWaitInvisible() *Element

MustWaitInvisible until the element is not visible or removed

func (*Element) MustWaitLoad added in v0.50.0

func (el *Element) MustWaitLoad() *Element

MustWaitLoad for element like <img />

func (*Element) MustWaitStable added in v0.50.0

func (el *Element) MustWaitStable() *Element

MustWaitStable waits until the size and position are stable. Useful when waiting for the animation of modal or button to complete so that we can simulate the mouse to move to it and click on it.

func (*Element) MustWaitVisible added in v0.50.0

func (el *Element) MustWaitVisible() *Element

MustWaitVisible until the element is visible

func (*Element) Next

func (el *Element) Next() (*Element, error)

Next doc is similar to the method MustNext

func (*Element) NodeID added in v0.49.0

func (el *Element) NodeID() (proto.DOMNodeID, error)

NodeID of the node

func (*Element) Parent

func (el *Element) Parent() (*Element, error)

Parent doc is similar to the method MustParent

func (*Element) Parents

func (el *Element) Parents(selector string) (Elements, error)

Parents that match the selector

func (*Element) Press

func (el *Element) Press(key rune) error

Press doc is similar to the method MustPress

func (*Element) Previous

func (el *Element) Previous() (*Element, error)

Previous doc is similar to the method MustPrevious

func (*Element) Property

func (el *Element) Property(name string) (proto.JSON, error)

Property is similar to the method Property

func (*Element) Release

func (el *Element) Release() error

Release doc is similar to the method MustRelease

func (*Element) Resource

func (el *Element) Resource() ([]byte, error)

Resource doc is similar to the method MustResource

func (*Element) Screenshot

func (el *Element) Screenshot(format proto.PageCaptureScreenshotFormat, quality int) ([]byte, error)

Screenshot of the area of the element

func (*Element) ScrollIntoView

func (el *Element) ScrollIntoView() error

ScrollIntoView doc is similar to the method MustScrollIntoViewIfNeeded

func (*Element) Select

func (el *Element) Select(selectors []string) error

Select doc is similar to the method MustSelect

func (*Element) SelectAllText

func (el *Element) SelectAllText() error

SelectAllText doc is similar to the method MustSelectAllText

func (*Element) SelectText

func (el *Element) SelectText(regex string) error

SelectText doc is similar to the method MustSelectText

func (*Element) SetFiles

func (el *Element) SetFiles(paths []string) error

SetFiles doc is similar to the method MustSetFiles

func (*Element) ShadowRoot

func (el *Element) ShadowRoot() (*Element, error)

ShadowRoot returns the shadow root of this element

func (*Element) Sleeper added in v0.50.0

func (el *Element) Sleeper(sleeper kit.Sleeper) *Element

Sleeper for chained sub-operations

func (*Element) Text

func (el *Element) Text() (string, error)

Text doc is similar to the method MustText

func (*Element) Timeout

func (el *Element) Timeout(d time.Duration) *Element

Timeout for chained sub-operations

func (*Element) Trace

func (el *Element) Trace(msg string) (removeOverlay func())

Trace with an overlay on the element

func (*Element) Visible

func (el *Element) Visible() (bool, error)

Visible doc is similar to the method MustVisible

func (*Element) Wait

func (el *Element) Wait(js string, params ...interface{}) error

Wait doc is similar to the method MustWait

func (*Element) WaitInvisible

func (el *Element) WaitInvisible() error

WaitInvisible doc is similar to the method MustWaitInvisible

func (*Element) WaitLoad added in v0.49.0

func (el *Element) WaitLoad() error

WaitLoad for element like <img />

func (*Element) WaitStable

func (el *Element) WaitStable(interval time.Duration) error

WaitStable not using requestAnimation here because it can trigger to many checks, or miss checks for jQuery css animation.

func (*Element) WaitVisible

func (el *Element) WaitVisible() error

WaitVisible doc is similar to the method MustWaitVisible

type Elements

type Elements []*Element

Elements provides some helpers to deal with element list

func (Elements) Empty

func (els Elements) Empty() bool

Empty returns true if the list is empty

func (Elements) First

func (els Elements) First() *Element

First returns the first element, if the list is empty returns nil

func (Elements) Last

func (els Elements) Last() *Element

Last returns the last element, if the list is empty returns nil

type Error

type Error struct {
	Code    error
	Details interface{}
}

Error ...

func (*Error) Error

func (e *Error) Error() string

Error ...

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap ...

type EvalOptions added in v0.50.0

type EvalOptions struct {
	// If enabled the eval will return an reference id for the
	// remote object. If disabled the remote object will be return as json.
	ByValue bool

	// ThisID is the this object when eval the js
	ThisID proto.RuntimeRemoteObjectID

	// JS function code to eval
	JS string

	// JSArgs of the js function
	JSArgs Array
}

EvalOptions object

func NewEvalOptions added in v0.50.0

func NewEvalOptions(js string, jsArgs Array) *EvalOptions

NewEvalOptions creates a new EvalPayload

func (*EvalOptions) ByObject added in v0.50.0

func (e *EvalOptions) ByObject() *EvalOptions

ByObject disables ByValue.

func (*EvalOptions) This added in v0.50.0

This set the ThisID

type Hijack

type Hijack struct {
	Request  *HijackRequest
	Response *HijackResponse
	OnError  func(error)

	// Skip to next handler
	Skip bool
	// contains filtered or unexported fields
}

Hijack context

func (*Hijack) ContinueRequest added in v0.42.0

func (h *Hijack) ContinueRequest(cq *proto.FetchContinueRequest)

ContinueRequest without hijacking

func (*Hijack) LoadResponse

func (h *Hijack) LoadResponse(loadBody bool) error

LoadResponse will send request to the real destination and load the response as default response to override.

func (*Hijack) MustLoadResponse added in v0.50.0

func (h *Hijack) MustLoadResponse()

MustLoadResponse will send request to the real destination and load the response as default response to override.

type HijackRequest

type HijackRequest struct {
	// contains filtered or unexported fields
}

HijackRequest context

func (*HijackRequest) Body

func (ctx *HijackRequest) Body() string

Body of the request, devtools API doesn't support binary data yet, only string can be captured.

func (*HijackRequest) Header

func (ctx *HijackRequest) Header(key string) string

Header via a key

func (*HijackRequest) Headers

func (ctx *HijackRequest) Headers() proto.NetworkHeaders

Headers of request

func (*HijackRequest) JSONBody

func (ctx *HijackRequest) JSONBody() gjson.Result

JSONBody of the request

func (*HijackRequest) Method

func (ctx *HijackRequest) Method() string

Method of the request

func (*HijackRequest) SetBody

func (ctx *HijackRequest) SetBody(obj interface{}) *HijackRequest

SetBody of the request, if obj is []byte or string, raw body will be used, else it will be encoded as json.

func (*HijackRequest) SetClient added in v0.41.0

func (ctx *HijackRequest) SetClient(client *http.Client) *HijackRequest

SetClient for http

func (*HijackRequest) SetHeader

func (ctx *HijackRequest) SetHeader(pairs ...string) *HijackRequest

SetHeader via key-value pairs

func (*HijackRequest) SetMethod

func (ctx *HijackRequest) SetMethod(name string) *HijackRequest

SetMethod of request

func (*HijackRequest) SetQuery

func (ctx *HijackRequest) SetQuery(pairs ...interface{}) *HijackRequest

SetQuery of the request, example Query(k, v, k, v ...)

func (*HijackRequest) SetURL

func (ctx *HijackRequest) SetURL(url string) *HijackRequest

SetURL of the request

func (*HijackRequest) Type added in v0.49.1

Type of the resource

func (*HijackRequest) URL

func (ctx *HijackRequest) URL() *url.URL

URL of the request

type HijackResponse

type HijackResponse struct {
	// contains filtered or unexported fields
}

HijackResponse context

func (*HijackResponse) Body

func (ctx *HijackResponse) Body() ([]byte, error)

Body of response

func (*HijackResponse) BodyStream added in v0.42.0

func (ctx *HijackResponse) BodyStream() (io.Reader, error)

BodyStream returns the stream of the body

func (*HijackResponse) Fail added in v0.48.1

Fail request

func (*HijackResponse) Header

func (ctx *HijackResponse) Header(key string) (string, error)

Header via key

func (*HijackResponse) Headers

func (ctx *HijackResponse) Headers() (http.Header, error)

Headers of request

func (*HijackResponse) JSONBody

func (ctx *HijackResponse) JSONBody() gjson.Result

JSONBody of response

func (*HijackResponse) MustBody added in v0.50.0

func (ctx *HijackResponse) MustBody() []byte

MustBody of response

func (*HijackResponse) MustBodyStream added in v0.50.0

func (ctx *HijackResponse) MustBodyStream() io.Reader

MustBodyStream returns the stream of the body

func (*HijackResponse) MustHeader added in v0.50.0

func (ctx *HijackResponse) MustHeader(key string) string

MustHeader via key

func (*HijackResponse) MustHeaders added in v0.50.0

func (ctx *HijackResponse) MustHeaders() http.Header

MustHeaders of request

func (*HijackResponse) MustStatusCode added in v0.50.0

func (ctx *HijackResponse) MustStatusCode() int

MustStatusCode of response

func (*HijackResponse) SetBody

func (ctx *HijackResponse) SetBody(obj interface{}) *HijackResponse

SetBody of response, if obj is []byte, raw body will be used, else it will be encoded as json

func (*HijackResponse) SetHeader

func (ctx *HijackResponse) SetHeader(pairs ...string)

SetHeader via key-value pairs

func (*HijackResponse) SetStatusCode

func (ctx *HijackResponse) SetStatusCode(code int)

SetStatusCode of response

func (*HijackResponse) StatusCode

func (ctx *HijackResponse) StatusCode() (int, error)

StatusCode of response

func (*HijackResponse) StringBody

func (ctx *HijackResponse) StringBody() string

StringBody of response

type HijackRouter

type HijackRouter struct {
	// contains filtered or unexported fields
}

HijackRouter context

func (*HijackRouter) Add

func (r *HijackRouter) Add(pattern string, resourceType proto.NetworkResourceType, handler func(*Hijack)) error

Add a hijack handler to router, the doc of the pattern is the same as "proto.FetchRequestPattern.URLPattern". You can add new handler even after the "Run" is called.

func (*HijackRouter) MustAdd added in v0.50.0

func (r *HijackRouter) MustAdd(pattern string, handler func(*Hijack))

MustAdd a hijack handler to router, the doc of the pattern is the same as "proto.FetchRequestPattern.URLPattern". You can add new handler even after the "Run" is called.

func (*HijackRouter) MustRemove added in v0.50.0

func (r *HijackRouter) MustRemove(pattern string)

MustRemove handler via the pattern

func (*HijackRouter) MustStop added in v0.50.0

func (r *HijackRouter) MustStop()

MustStop the router

func (*HijackRouter) Remove

func (r *HijackRouter) Remove(pattern string) error

Remove handler via the pattern

func (*HijackRouter) Run

func (r *HijackRouter) Run()

Run the router, after you call it, you shouldn't add new handler to it.

func (*HijackRouter) Stop

func (r *HijackRouter) Stop() error

Stop the router

type Keyboard

type Keyboard struct {
	// contains filtered or unexported fields
}

Keyboard represents the keyboard on a page, it's always related the main frame

func (*Keyboard) Down

func (k *Keyboard) Down(key rune) error

Down doc is similar to the method MustDown

func (*Keyboard) InsertText

func (k *Keyboard) InsertText(text string) error

InsertText doc is similar to the method MustInsertText

func (*Keyboard) MustDown added in v0.50.0

func (k *Keyboard) MustDown(key rune) *Keyboard

MustDown holds key down

func (*Keyboard) MustInsertText added in v0.50.0

func (k *Keyboard) MustInsertText(text string) *Keyboard

MustInsertText like paste text into the page

func (*Keyboard) MustPress added in v0.50.0

func (k *Keyboard) MustPress(key rune) *Keyboard

MustPress a key

func (*Keyboard) MustUp added in v0.50.0

func (k *Keyboard) MustUp(key rune) *Keyboard

MustUp releases the key

func (*Keyboard) Press

func (k *Keyboard) Press(key rune) error

Press doc is similar to the method MustPress

func (*Keyboard) Up

func (k *Keyboard) Up(key rune) error

Up doc is similar to the method MustUp

type Mouse

type Mouse struct {
	// contains filtered or unexported fields
}

Mouse represents the mouse on a page, it's always related the main frame

func (*Mouse) Click

func (m *Mouse) Click(button proto.InputMouseButton) error

Click doc is similar to the method MustClick

func (*Mouse) Down

func (m *Mouse) Down(button proto.InputMouseButton, clicks int64) error

Down doc is similar to the method MustDown

func (*Mouse) Move

func (m *Mouse) Move(x, y float64, steps int) error

Move to the absolute position with specified steps

func (*Mouse) MustClick added in v0.50.0

func (m *Mouse) MustClick(button proto.InputMouseButton) *Mouse

MustClick will press then release the button

func (*Mouse) MustDown added in v0.50.0

func (m *Mouse) MustDown(button proto.InputMouseButton) *Mouse

MustDown holds the button down

func (*Mouse) MustMove added in v0.50.0

func (m *Mouse) MustMove(x, y float64) *Mouse

MustMove to the absolute position

func (*Mouse) MustScroll added in v0.50.0

func (m *Mouse) MustScroll(x, y float64) *Mouse

MustScroll with the relative offset

func (*Mouse) MustUp added in v0.50.0

func (m *Mouse) MustUp(button proto.InputMouseButton) *Mouse

MustUp release the button

func (*Mouse) Scroll

func (m *Mouse) Scroll(offsetX, offsetY float64, steps int) error

Scroll the relative offset with specified steps

func (*Mouse) Up

func (m *Mouse) Up(button proto.InputMouseButton, clicks int64) error

Up doc is similar to the method MustUp

type Page

type Page struct {
	TargetID  proto.TargetTargetID
	SessionID proto.TargetSessionID

	// devices
	Mouse    *Mouse
	Keyboard *Keyboard
	// contains filtered or unexported fields
}

Page represents the webpage We try to hold as less states as possible

func (*Page) AddScriptTag

func (p *Page) AddScriptTag(url, content string) error

AddScriptTag to page. If url is empty, content will be used.

func (*Page) AddStyleTag

func (p *Page) AddStyleTag(url, content string) error

AddStyleTag to page. If url is empty, content will be used.

func (*Page) CallContext

func (p *Page) CallContext() (context.Context, proto.Client, string)

CallContext parameters for proto

func (*Page) CancelTimeout

func (p *Page) CancelTimeout() *Page

CancelTimeout context

func (*Page) Close

func (p *Page) Close() error

Close page

func (*Page) Context

func (p *Page) Context(ctx context.Context, cancel func()) *Page

Context creates a clone with a context that inherits the previous one

func (*Page) Cookies

func (p *Page) Cookies(urls []string) ([]*proto.NetworkCookie, error)

Cookies returns the page cookies. By default it will return the cookies for current page. The urls is the list of URLs for which applicable cookies will be fetched.

func (*Page) DisableDomain

func (p *Page) DisableDomain(method proto.Payload) (recover func())

DisableDomain and returns a recover function to restore previous state

func (*Page) EachEvent

func (p *Page) EachEvent(fn interface{}) (wait func())

EachEvent of the specified event type, if the fn returns true the event loop will stop. The fn can accpet multiple events, such as EachEvent(func(e1 *proto.PageLoadEventFired, e2 *proto.PageLifecycleEvent) {}), only one argument will be non-null, others will null.

func (*Page) Element

func (p *Page) Element(selectors ...string) (*Element, error)

Element finds element by css selector

func (*Page) ElementByJS

func (p *Page) ElementByJS(opts *EvalOptions) (*Element, error)

ElementByJS returns the element from the return value of the js function. If sleeper is nil, no retry will be performed. thisID is the this value of the js function, when thisID is "", the this context will be the "window". If the js function returns "null", ElementByJS will retry, you can use custom sleeper to make it only retry once.

func (*Page) ElementFromNode added in v0.47.0

func (p *Page) ElementFromNode(id proto.DOMNodeID) (*Element, error)

ElementFromNode creates an Element from the node id

func (*Page) ElementFromObject added in v0.47.0

func (p *Page) ElementFromObject(id proto.RuntimeRemoteObjectID) *Element

ElementFromObject creates an Element from the remote object id.

func (*Page) ElementFromPoint added in v0.48.0

func (p *Page) ElementFromPoint(x, y int64) (*Element, error)

ElementFromPoint creates an Element from the absolute point on the page. The point should include the window scroll offset.

func (*Page) ElementMatches

func (p *Page) ElementMatches(pairs ...string) (*Element, error)

ElementMatches doc is similar to the method MustElementMatches

func (*Page) ElementX

func (p *Page) ElementX(xPaths ...string) (*Element, error)

ElementX finds elements by XPath

func (*Page) Elements

func (p *Page) Elements(selector string) (Elements, error)

Elements doc is similar to the method MustElements

func (*Page) ElementsByJS

func (p *Page) ElementsByJS(opts *EvalOptions) (Elements, error)

ElementsByJS is different from ElementByJSE, it doesn't do retry

func (*Page) ElementsX

func (p *Page) ElementsX(xpath string) (Elements, error)

ElementsX doc is similar to the method MustElementsX

func (*Page) Emulate added in v0.42.1

func (p *Page) Emulate(device devices.DeviceType, landscape bool) error

Emulate the device, such as iPhone9. If device is empty, it will clear the override.

func (*Page) EnableDomain

func (p *Page) EnableDomain(method proto.Payload) (recover func())

EnableDomain and returns a recover function to restore previous state

func (*Page) Eval

func (p *Page) Eval(js string, jsArgs ...interface{}) (*proto.RuntimeRemoteObject, error)

Eval evalutes javascript on the page.

func (*Page) EvalOnNewDocument added in v0.44.0

func (p *Page) EvalOnNewDocument(js string) (proto.PageScriptIdentifier, error)

EvalOnNewDocument Evaluates given script in every frame upon creation (before loading frame's scripts).

func (*Page) EvalWithOptions added in v0.50.0

func (p *Page) EvalWithOptions(opts *EvalOptions) (*proto.RuntimeRemoteObject, error)

EvalWithOptions thisID is the remote objectID that will be the this of the js function, if it's empty "window" will be used. Set the byValue to true to reduce memory occupation. If the item in jsArgs is proto.RuntimeRemoteObjectID, the remote object will be used, else the item will be treated as JSON value.

func (*Page) Expose added in v0.49.1

func (p *Page) Expose(name string) (callback chan string, stop func(), err error)

Expose function to the page's window object. Must bind before navigate to the page. Bindings survive reloads. Binding function takes exactly one argument, this argument should be string.

func (*Page) ExposeJSHelper added in v0.45.0

func (p *Page) ExposeJSHelper() *Page

ExposeJSHelper to page's window object, so you can debug helper.js in the browser console. Such as run `rod.elementMatches("div", "ok")` in the browser console to test the Page.ElementMatches.

func (*Page) GetContext

func (p *Page) GetContext() context.Context

GetContext returns the current context

func (*Page) GetDownloadFile

func (p *Page) GetDownloadFile(pattern string, resourceType proto.NetworkResourceType) func() (http.Header, io.Reader, error)

GetDownloadFile of the next download url that matches the pattern, returns the file content. The handler will be used once and removed.

func (*Page) GetWindow

func (p *Page) GetWindow() (*proto.BrowserBounds, error)

GetWindow doc is similar to the method MustGetWindow

func (*Page) HandleDialog

func (p *Page) HandleDialog(accept bool, promptText string) func() error

HandleDialog doc is similar to the method MustHandleDialog. Because the js will be paused, you should put the code that triggers in a goroutine.

func (*Page) Has

func (p *Page) Has(selectors ...string) (bool, error)

Has doc is similar to the method MustHas

func (*Page) HasMatches

func (p *Page) HasMatches(pairs ...string) (bool, error)

HasMatches doc is similar to the method MustHasMatches

func (*Page) HasX

func (p *Page) HasX(selectors ...string) (bool, error)

HasX doc is similar to the method MustHasX

func (*Page) HijackRequests

func (p *Page) HijackRequests() *HijackRouter

HijackRequests same as Browser.HijackRequests, but scoped with the page

func (*Page) Info added in v0.42.1

func (p *Page) Info() (*proto.TargetTargetInfo, error)

Info of the page, such as the URL or title of the page

func (*Page) IsIframe

func (p *Page) IsIframe() bool

IsIframe tells if it's iframe

func (*Page) LoadState

func (p *Page) LoadState(method proto.Payload) (has bool)

LoadState into the method.

func (*Page) MustAddScriptTag added in v0.50.0

func (p *Page) MustAddScriptTag(url string) *Page

MustAddScriptTag to page. If url is empty, content will be used.

func (*Page) MustAddStyleTag added in v0.50.0

func (p *Page) MustAddStyleTag(url string) *Page

MustAddStyleTag to page. If url is empty, content will be used.

func (*Page) MustClose added in v0.50.0

func (p *Page) MustClose()

MustClose page

func (*Page) MustCookies added in v0.50.0

func (p *Page) MustCookies(urls ...string) []*proto.NetworkCookie

MustCookies returns the page cookies. By default it will return the cookies for current page. The urls is the list of URLs for which applicable cookies will be fetched.

func (*Page) MustElement added in v0.50.0

func (p *Page) MustElement(selectors ...string) *Element

MustElement retries until an element in the page that matches one of the CSS selectors

func (*Page) MustElementByJS added in v0.50.0

func (p *Page) MustElementByJS(js string, params ...interface{}) *Element

MustElementByJS retries until returns the element from the return value of the js function

func (*Page) MustElementFromNode added in v0.50.0

func (p *Page) MustElementFromNode(id proto.DOMNodeID) *Element

MustElementFromNode creates an Element from the node id

func (*Page) MustElementFromPoint added in v0.50.0

func (p *Page) MustElementFromPoint(left, top int) *Element

MustElementFromPoint creates an Element from the absolute point on the page. The point should include the window scroll offset.

func (*Page) MustElementMatches added in v0.50.0

func (p *Page) MustElementMatches(pairs ...string) *Element

MustElementMatches retries until an element in the page that matches one of the pairs. Each pairs is a css selector and a regex. A sample call will look like page.MustElementMatches("div", "click me"). The regex is the js regex, not golang's.

func (*Page) MustElementX added in v0.50.0

func (p *Page) MustElementX(xPaths ...string) *Element

MustElementX retries until an element in the page that matches one of the XPath selectors

func (*Page) MustElements added in v0.50.0

func (p *Page) MustElements(selector string) Elements

MustElements returns all elements that match the css selector

func (*Page) MustElementsByJS added in v0.50.0

func (p *Page) MustElementsByJS(js string, params ...interface{}) Elements

MustElementsByJS returns the elements from the return value of the js

func (*Page) MustElementsX added in v0.50.0

func (p *Page) MustElementsX(xpath string) Elements

MustElementsX returns all elements that match the XPath selector

func (*Page) MustEmulate added in v0.50.0

func (p *Page) MustEmulate(device devices.DeviceType) *Page

MustEmulate the device, such as iPhone9. If device is empty, it will clear the override.

func (*Page) MustEval added in v0.50.0

func (p *Page) MustEval(js string, params ...interface{}) proto.JSON

MustEval js on the page. The first param must be a js function definition. For example page.MustEval(`n => n + 1`, 1) will return 2

func (*Page) MustEvalOnNewDocument added in v0.50.0

func (p *Page) MustEvalOnNewDocument(js string)

MustEvalOnNewDocument Evaluates given script in every frame upon creation (before loading frame's scripts).

func (*Page) MustExpose added in v0.50.0

func (p *Page) MustExpose(name string) (callback chan string, stop func())

MustExpose function to the page's window object. Must bind before navigate to the page. Bindings survive reloads. Binding function takes exactly one argument, this argument should be string.

func (*Page) MustGetDownloadFile added in v0.50.0

func (p *Page) MustGetDownloadFile(pattern string) func() []byte

MustGetDownloadFile of the next download url that matches the pattern, returns the file content.

func (*Page) MustGetWindow added in v0.50.0

func (p *Page) MustGetWindow() *proto.BrowserBounds

MustGetWindow get window bounds

func (*Page) MustHandleDialog added in v0.50.0

func (p *Page) MustHandleDialog(accept bool, promptText string) (wait func())

MustHandleDialog accepts or dismisses next JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) Because alert will block js, usually you have to run the wait function inside a goroutine. Check the unit test for it for more information.

func (*Page) MustHas added in v0.50.0

func (p *Page) MustHas(selector string) bool

MustHas an element that matches the css selector

func (*Page) MustHasMatches added in v0.50.0

func (p *Page) MustHasMatches(selector, regex string) bool

MustHasMatches an element that matches the css selector and its text matches the regex.

func (*Page) MustHasX added in v0.50.0

func (p *Page) MustHasX(selector string) bool

MustHasX an element that matches the XPath selector

func (*Page) MustInfo added in v0.50.0

func (p *Page) MustInfo() *proto.TargetTargetInfo

MustInfo of the page, such as the URL or title of the page

func (*Page) MustNavigate added in v0.50.0

func (p *Page) MustNavigate(url string) *Page

MustNavigate to url If url is empty, it will navigate to "about:blank".

func (*Page) MustObjectToJSON added in v0.50.0

func (p *Page) MustObjectToJSON(obj *proto.RuntimeRemoteObject) proto.JSON

MustObjectToJSON by remote object

func (*Page) MustObjectsToJSON added in v0.50.0

func (p *Page) MustObjectsToJSON(list []*proto.RuntimeRemoteObject) proto.JSON

MustObjectsToJSON by remote objects

func (*Page) MustPDF added in v0.50.0

func (p *Page) MustPDF() []byte

MustPDF prints page as MustPDF

func (*Page) MustPause added in v0.50.0

func (p *Page) MustPause() *Page

MustPause stops on the next JavaScript statement

func (*Page) MustRelease added in v0.50.0

func (p *Page) MustRelease(objectID proto.RuntimeRemoteObjectID) *Page

MustRelease remote object

func (*Page) MustScreenshot added in v0.50.0

func (p *Page) MustScreenshot(toFile ...string) []byte

MustScreenshot the page and returns the binary of the image If the toFile is "", it will save output to "tmp/screenshots" folder, time as the file name.

func (*Page) MustScreenshotFullPage added in v0.50.0

func (p *Page) MustScreenshotFullPage(toFile ...string) []byte

MustScreenshotFullPage including all scrollable content and returns the binary of the image.

func (*Page) MustSearch added in v0.50.0

func (p *Page) MustSearch(queries ...string) *Element

MustSearch for each given query in the DOM tree until find one, before that it will keep retrying. The query can be plain text or css selector or xpath. It will search nested iframes and shadow doms too.

func (*Page) MustSetCookies added in v0.50.0

func (p *Page) MustSetCookies(cookies ...*proto.NetworkCookieParam) *Page

MustSetCookies of the page. Cookie format: https://chromedevtools.github.io/devtools-protocol/tot/Network#method-setCookie

func (*Page) MustSetExtraHeaders added in v0.50.0

func (p *Page) MustSetExtraHeaders(dict ...string) (cleanup func())

MustSetExtraHeaders whether to always send extra HTTP headers with the requests from this page. The arguments are key-value pairs, you can set multiple key-value pairs at the same time.

func (*Page) MustSetUserAgent added in v0.50.0

func (p *Page) MustSetUserAgent(req *proto.NetworkSetUserAgentOverride) *Page

MustSetUserAgent Allows overriding user agent with the given string. If req is nil, the default user agent will be the same as a mac chrome.

func (*Page) MustStopLoading added in v0.50.0

func (p *Page) MustStopLoading() *Page

MustStopLoading forces the page stop all navigations and pending resource fetches.

func (*Page) MustViewport added in v0.50.0

func (p *Page) MustViewport(width, height int64, deviceScaleFactor float64, mobile bool) *Page

MustViewport overrides the values of device screen dimensions.

func (*Page) MustWait added in v0.50.0

func (p *Page) MustWait(js string, params ...interface{})

MustWait js function until it returns true

func (*Page) MustWaitIdle added in v0.50.0

func (p *Page) MustWaitIdle() *Page

MustWaitIdle wait until the next window.requestIdleCallback is called.

func (*Page) MustWaitLoad added in v0.50.0

func (p *Page) MustWaitLoad() *Page

MustWaitLoad wait until the `window.onload` is complete, resolve immediately if already fired.

func (*Page) MustWaitOpen added in v0.50.0

func (p *Page) MustWaitOpen() (wait func() (newPage *Page))

MustWaitOpen waits for a new page opened by the current one

func (*Page) MustWaitPauseOpen added in v0.50.0

func (p *Page) MustWaitPauseOpen() (wait func() *Page, resume func())

MustWaitPauseOpen waits for a page opened by the current page, before opening pause the js execution. Because the js will be paused, you should put the code that triggers it in a goroutine, such as the click.

func (*Page) MustWaitRequestIdle added in v0.50.0

func (p *Page) MustWaitRequestIdle(excludes ...string) (wait func())

MustWaitRequestIdle returns a wait function that waits until the page doesn't send request for 300ms. You can pass regular expressions to exclude the requests by their url.

func (*Page) MustWindow added in v0.50.0

func (p *Page) MustWindow(left, top, width, height int64) *Page

MustWindow set the window location and size

func (*Page) MustWindowFullscreen added in v0.50.0

func (p *Page) MustWindowFullscreen() *Page

MustWindowFullscreen the window

func (*Page) MustWindowMaximize added in v0.50.0

func (p *Page) MustWindowMaximize() *Page

MustWindowMaximize the window

func (*Page) MustWindowMinimize added in v0.50.0

func (p *Page) MustWindowMinimize() *Page

MustWindowMinimize the window

func (*Page) MustWindowNormal added in v0.50.0

func (p *Page) MustWindowNormal() *Page

MustWindowNormal the window size

func (*Page) Navigate

func (p *Page) Navigate(url string) error

Navigate doc is similar to the method MustNavigate If url is empty, it will navigate to "about:blank".

func (*Page) ObjectToJSON

func (p *Page) ObjectToJSON(obj *proto.RuntimeRemoteObject) (proto.JSON, error)

ObjectToJSON by object id

func (*Page) Overlay

func (p *Page) Overlay(left, top, width, height float64, msg string) (remove func())

Overlay a rectangle on the main frame with specified message

func (*Page) PDF

func (p *Page) PDF(req *proto.PagePrintToPDF) ([]byte, error)

PDF prints page as PDF

func (*Page) Pause

func (p *Page) Pause() error

Pause doc is similar to the method MustPause

func (*Page) Release

func (p *Page) Release(objectID proto.RuntimeRemoteObjectID) error

Release doc is similar to the method MustRelease

func (*Page) Root

func (p *Page) Root() *Page

Root page of the iframe, if it's not a iframe returns itself

func (*Page) Search added in v0.47.0

func (p *Page) Search(from, to int, queries ...string) (Elements, error)

Search for each given query in the DOM tree until the result count is not zero, before that it will keep retrying. The query can be plain text or css selector or xpath. It will search nested iframes and shadow doms too.

func (*Page) SetCookies

func (p *Page) SetCookies(cookies []*proto.NetworkCookieParam) error

SetCookies of the page. Cookie format: https://chromedevtools.github.io/devtools-protocol/tot/Network#method-setCookie

func (*Page) SetExtraHeaders

func (p *Page) SetExtraHeaders(dict []string) (func(), error)

SetExtraHeaders whether to always send extra HTTP headers with the requests from this page.

func (*Page) SetUserAgent

func (p *Page) SetUserAgent(req *proto.NetworkSetUserAgentOverride) error

SetUserAgent Allows overriding user agent with the given string. If req is nil, the default user agent will be the same as a mac chrome.

func (*Page) Sleeper

func (p *Page) Sleeper(sleeper kit.Sleeper) *Page

Sleeper for chained sub-operations

func (*Page) StopLoading

func (p *Page) StopLoading() error

StopLoading forces the page stop navigation and pending resource fetches.

func (*Page) Timeout

func (p *Page) Timeout(d time.Duration) *Page

Timeout for chained sub-operations

func (*Page) Viewport

func (p *Page) Viewport(params *proto.EmulationSetDeviceMetricsOverride) error

Viewport doc is similar to the method MustViewport. If params is nil, it will clear the override.

func (*Page) Wait

func (p *Page) Wait(thisID proto.RuntimeRemoteObjectID, js string, params Array) error

Wait js function until it returns true

func (*Page) WaitEvent

func (p *Page) WaitEvent(e proto.Payload) (wait func())

WaitEvent waits for the next event for one time. It will also load the data into the event object.

func (*Page) WaitIdle

func (p *Page) WaitIdle(timeout time.Duration) (err error)

WaitIdle doc is similar to the method MustWaitIdle

func (*Page) WaitLoad

func (p *Page) WaitLoad() error

WaitLoad doc is similar to the method MustWaitLoad

func (*Page) WaitOpen

func (p *Page) WaitOpen() func() (*Page, error)

WaitOpen doc is similar to the method MustWaitPage

func (*Page) WaitPauseOpen added in v0.49.3

func (p *Page) WaitPauseOpen() (wait func() (*Page, error), resume func() error, err error)

WaitPauseOpen waits for a page opened by the current page, before opening pause the js execution. Because the js will be paused, you should put the code that triggers it in a goroutine.

func (*Page) WaitRequestIdle

func (p *Page) WaitRequestIdle(d time.Duration, includes, excludes []string) func()

WaitRequestIdle returns a wait function that waits until no request for d duration. Use the includes and excludes regexp list to filter the requests by their url. Such as set n to 1 if there's a polling request.

type Pages

type Pages []*Page

Pages provides some helpers to deal with page list

func (Pages) Find

func (ps Pages) Find(selector string) (*Page, error)

Find the page that has the specified element with the css selector

func (Pages) FindByURL

func (ps Pages) FindByURL(regex string) (*Page, error)

FindByURL returns the page that has the url that matches the regex

func (Pages) MustFind added in v0.50.3

func (ps Pages) MustFind(selector string) *Page

MustFind the page that has the specified element with the css selector

func (Pages) MustFindByURL added in v0.50.0

func (ps Pages) MustFindByURL(regex string) *Page

MustFindByURL returns the page that has the url that matches the regex

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL