rod

package module
v0.49.1 Latest Latest
Warning

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

Go to latest
Published: Jul 29, 2020 License: MIT Imports: 31 Imported by: 585

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

  • Fluent interface design to reduce verbose code
  • 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
  • Two styles of error handling to choose.
  • 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: Why functions don't return error values

Please read the E suffixed function family.

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.

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().Connect()

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

	// 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).Page("https://github.com")

	// Resize the window make sure window size is always consistent.
	page.Window(0, 0, 1200, 600)

	// We use css selector to get the search input element and input "git"
	page.Element("input").Input("git").Press(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.Element(".codesearch-results p").Text()

	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.Elements("input")))

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

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

	// When eval on an element, you can use "this" to access the DOM element.
	fmt.Println(page.Element("title").Eval(`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).Element("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").
		Launch()

	browser := rod.New().ControlURL(url).Connect()
	defer browser.Close()

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

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

	// 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).Connect()
	defer browser.Close()

	page := browser.Page("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.ElementE(sleeper, "", []string{"input"})

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

	fmt.Println(el.Eval(`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).Connect()
	defer browser.Close()

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

	page := browser.Page("")

	// 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.Navigate("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.Eval(`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).Connect()
	defer browser.Close()

	page := browser.Page("")

	done := make(chan int)

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

	wait := page.WaitEvent(&proto.PageLoadEventFired{})
	page.Navigate("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.Navigate("https://example.com")
		wait()
	}

	page.Eval(`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
	url := launcher.New().
		Headless(false).
		Devtools(true).
		Launch()

	// 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).
		Connect()

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

	defer browser.Close()

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

	page.Element("#searchLanguage").Select("[lang=zh]")
	page.Element("#searchInput").Input("热干面")
	page.Keyboard.Press(input.Enter)

	fmt.Println(page.Element("#firstHeading").Text())

	// Response gets the binary of the image as a []byte.
	img := page.Element(`[alt="Hot Dry Noodles.jpg"]`).Resource()
	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.Pause()

	// 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).Connect()
	defer browser.Close()

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

	router.Add("*.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.LoadResponse()

		// 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.Page("https://www.wikipedia.org/").Wait(`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).Connect()
	defer browser.Close()

	page := browser.Page("")

	// 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).Connect()
	defer browser.Close()

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

	page.WaitLoad().Element("[data-target='#exampleModalLive']").Click()

	saveBtn := page.ElementMatches("#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).WaitStable().Click().WaitInvisible()

	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).Connect()
	defer browser.Close()

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

	// WaitRequestIdle will wait for all possible ajax calls to complete before
	// continuing on with further execution calls.
	wait := page.WaitRequestIdle()
	page.Element("#search_form_input_homepage").Click().Input("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.Elements(".search__autocomplete .acp")) > 0)

}
Output:

true

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrValue error
	ErrValue = errors.New("[rod] error value")
	// ErrExpectElement error
	ErrExpectElement = errors.New("[rod] expect js to return an element")
	// ErrExpectElements error
	ErrExpectElements = errors.New("[rod] expect js to return an array of elements")
	// ErrElementNotFound error
	ErrElementNotFound = errors.New("[rod] cannot find element")
	// ErrWaitJSTimeout error
	ErrWaitJSTimeout = errors.New("[rod] wait js timeout")
	// ErrSrcNotFound error
	ErrSrcNotFound = errors.New("[rod] element doesn't have src attribute")
	// ErrEval error
	ErrEval = errors.New("[rod] eval error")
	// ErrNavigation error
	ErrNavigation = errors.New("[rod] navigation failed")
	// ErrNotClickable error
	ErrNotClickable = errors.New("[rod] element is not clickable")
)
View Source
var Sleeper = func() kit.Sleeper {
	return kit.BackoffSleeper(100*time.Millisecond, time.Second, nil)
}

Sleeper returns 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()

Close the browser and release related resources

func (*Browser) CloseE

func (b *Browser) CloseE() error

CloseE doc is similar to the method Close

func (*Browser) Connect

func (b *Browser) Connect() *Browser

Connect 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) ConnectE

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

ConnectE doc is similar to the method Connect

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) 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)

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) HandleAuthE

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

HandleAuthE 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

Incognito creates a new incognito browser

func (*Browser) IncognitoE

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

IncognitoE 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) Page

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

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

func (*Browser) PageE

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

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

func (*Browser) PageFromTargetID

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

PageFromTargetID creates a Page instance from a targetID

func (*Browser) PageFromTargetIDE

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

PageFromTargetIDE creates a Page instance from a targetID

func (*Browser) Pages

func (b *Browser) Pages() Pages

Pages returns all visible pages

func (*Browser) PagesE

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

PagesE doc is similar to the method Pages

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) 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

Attribute 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 Attribute. https://stackoverflow.com/questions/6003819/what-is-the-difference-between-properties-and-attributes-in-html

func (*Element) AttributeE

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

AttributeE is similar to the method Attribute

func (*Element) Blur

func (el *Element) Blur() *Element

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

func (*Element) BlurE

func (el *Element) BlurE() error

BlurE is similar to the method Blur

func (*Element) Box

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

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

func (*Element) BoxE

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

BoxE 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

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) CanvasToImageE added in v0.45.1

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

CanvasToImageE 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() *Element

Click the element

func (*Element) ClickE

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

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

func (*Element) Clickable added in v0.48.0

func (el *Element) Clickable() bool

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

func (*Element) ClickableE added in v0.48.0

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

ClickableE 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

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

func (*Element) ContainsElementE added in v0.48.0

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

ContainsElementE 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() *proto.DOMNode

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

func (*Element) DescribeE

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

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

func (*Element) Element

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

Element returns the first child that matches the css selector

func (*Element) ElementByJS

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

ElementByJS returns the element from the return value of the js

func (*Element) ElementByJSE

func (el *Element) ElementByJSE(js string, params Array) (*Element, error)

ElementByJSE doc is similar to the method ElementByJS

func (*Element) ElementE

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

ElementE doc is similar to the method Element

func (*Element) ElementMatches

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

ElementMatches 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) ElementMatchesE

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

ElementMatchesE doc is similar to the method ElementMatches

func (*Element) ElementX

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

ElementX returns the first child that matches the XPath selector

func (*Element) ElementXE

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

ElementXE doc is similar to the method ElementX

func (*Element) Elements

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

Elements returns all elements that match the css selector

func (*Element) ElementsByJS

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

ElementsByJS returns the elements from the return value of the js

func (*Element) ElementsByJSE

func (el *Element) ElementsByJSE(js string, params Array) (Elements, error)

ElementsByJSE doc is similar to the method ElementsByJS

func (*Element) ElementsE

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

ElementsE doc is similar to the method Elements

func (*Element) ElementsX

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

ElementsX returns all elements that match the XPath selector

func (*Element) ElementsXE

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

ElementsXE doc is similar to the method ElementsX

func (*Element) Eval

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

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

func (*Element) EvalE

func (el *Element) EvalE(byValue bool, js string, params Array) (*proto.RuntimeRemoteObject, error)

EvalE doc is similar to the method Eval

func (*Element) Focus

func (el *Element) Focus() *Element

Focus sets focus on the specified element

func (*Element) FocusE

func (el *Element) FocusE() error

FocusE doc is similar to the method Focus

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

HTML gets the outerHTML of the element

func (*Element) HTMLE

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

HTMLE doc is similar to the method HTML

func (*Element) Has

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

Has an element that matches the css selector

func (*Element) HasE

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

HasE doc is similar to the method Has

func (*Element) HasMatches

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

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

func (*Element) HasMatchesE

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

HasMatchesE doc is similar to the method HasMatches

func (*Element) HasX

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

HasX an element that matches the XPath selector

func (*Element) HasXE

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

HasXE doc is similar to the method HasX

func (*Element) Hover added in v0.49.1

func (el *Element) Hover() *Element

Hover the mouse over the center of the element.

func (*Element) HoverE added in v0.49.1

func (el *Element) HoverE() error

HoverE the mouse over the center of the element.

func (*Element) Input

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

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

func (*Element) InputE

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

InputE doc is similar to the method Input

func (*Element) Matches added in v0.45.0

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

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

func (*Element) MatchesE added in v0.45.0

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

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

func (*Element) Next

func (el *Element) Next() *Element

Next returns the next sibling element

func (*Element) NextE

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

NextE doc is similar to the method Next

func (*Element) NodeID added in v0.49.0

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

NodeID of the node

func (*Element) NodeIDE added in v0.49.0

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

NodeIDE of the node

func (*Element) Parent

func (el *Element) Parent() *Element

Parent returns the parent element

func (*Element) ParentE

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

ParentE doc is similar to the method Parent

func (*Element) Parents

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

Parents that match the selector

func (*Element) ParentsE

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

ParentsE that match the selector

func (*Element) Press

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

Press a key

func (*Element) PressE

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

PressE doc is similar to the method Press

func (*Element) Previous

func (el *Element) Previous() *Element

Previous returns the previous sibling element

func (*Element) PreviousE

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

PreviousE doc is similar to the method Previous

func (*Element) Property

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

Property 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) PropertyE

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

PropertyE is similar to the method Property

func (*Element) Release

func (el *Element) Release()

Release remote object on browser

func (*Element) ReleaseE

func (el *Element) ReleaseE() error

ReleaseE doc is similar to the method Release

func (*Element) Resource

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

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

func (*Element) ResourceE

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

ResourceE doc is similar to the method Resource

func (*Element) Screenshot

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

Screenshot of the area of the element

func (*Element) ScreenshotE

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

ScreenshotE of the area of the element

func (*Element) ScrollIntoView

func (el *Element) ScrollIntoView() *Element

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

func (*Element) ScrollIntoViewE

func (el *Element) ScrollIntoViewE() error

ScrollIntoViewE doc is similar to the method ScrollIntoViewIfNeeded

func (*Element) Select

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

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

func (*Element) SelectAllText

func (el *Element) SelectAllText() *Element

SelectAllText selects all text

func (*Element) SelectAllTextE

func (el *Element) SelectAllTextE() error

SelectAllTextE doc is similar to the method SelectAllText

func (*Element) SelectE

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

SelectE doc is similar to the method Select

func (*Element) SelectText

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

SelectText selects the text that matches the regular expression

func (*Element) SelectTextE

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

SelectTextE doc is similar to the method SelectText

func (*Element) SetFiles

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

SetFiles sets files for the given file input element

func (*Element) SetFilesE

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

SetFilesE doc is similar to the method SetFiles

func (*Element) ShadowRoot

func (el *Element) ShadowRoot() *Element

ShadowRoot returns the shadow root of this element

func (*Element) ShadowRootE

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

ShadowRootE returns the shadow root of this element

func (*Element) Text

func (el *Element) Text() string

Text gets the innerText of the element

func (*Element) TextE

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

TextE doc is similar to the method Text

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

Visible returns true if the element is visible on the page

func (*Element) VisibleE

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

VisibleE doc is similar to the method Visible

func (*Element) Wait

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

Wait until the js returns true

func (*Element) WaitE

func (el *Element) WaitE(js string, params Array) error

WaitE doc is similar to the method Wait

func (*Element) WaitInvisible

func (el *Element) WaitInvisible() *Element

WaitInvisible until the element is not visible or removed

func (*Element) WaitInvisibleE

func (el *Element) WaitInvisibleE() error

WaitInvisibleE doc is similar to the method WaitInvisible

func (*Element) WaitLoad added in v0.49.0

func (el *Element) WaitLoad() *Element

WaitLoad for element like <img />

func (*Element) WaitLoadE added in v0.49.0

func (el *Element) WaitLoadE() error

WaitLoadE for element like <img />

func (*Element) WaitStable

func (el *Element) WaitStable() *Element

WaitStable 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) WaitStableE

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

WaitStableE 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() *Element

WaitVisible until the element is visible

func (*Element) WaitVisibleE

func (el *Element) WaitVisibleE() error

WaitVisibleE doc is similar to the method WaitVisible

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 {
	Err     error
	Details interface{}
}

Error ...

func (*Error) Error

func (e *Error) Error() string

Error ...

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap ...

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()

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

func (*Hijack) LoadResponseE

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

LoadResponseE 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

Body of response

func (*HijackResponse) BodyE

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

BodyE of response

func (*HijackResponse) BodyStream added in v0.42.0

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

BodyStream returns the stream of the body

func (*HijackResponse) BodyStreamE added in v0.42.0

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

BodyStreamE 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

Header via key

func (*HijackResponse) HeaderE

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

HeaderE via key

func (*HijackResponse) Headers

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

Headers of request

func (*HijackResponse) HeadersE

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

HeadersE of request

func (*HijackResponse) JSONBody

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

JSONBody 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

StatusCode of response

func (*HijackResponse) StatusCodeE

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

StatusCodeE 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, handler func(*Hijack))

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) AddE

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

AddE 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) Remove

func (r *HijackRouter) Remove(pattern string)

Remove handler via the pattern

func (*HijackRouter) RemoveE

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

RemoveE 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()

Stop the router

func (*HijackRouter) StopE

func (r *HijackRouter) StopE() error

StopE 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) *Keyboard

Down holds key down

func (*Keyboard) DownE

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

DownE doc is similar to the method Down

func (*Keyboard) InsertText

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

InsertText like paste text into the page

func (*Keyboard) InsertTextE

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

InsertTextE doc is similar to the method InsertText

func (*Keyboard) Press

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

Press a key

func (*Keyboard) PressE

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

PressE doc is similar to the method Press

func (*Keyboard) Up

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

Up releases the key

func (*Keyboard) UpE

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

UpE doc is similar to the method Up

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) *Mouse

Click will press then release the button

func (*Mouse) ClickE

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

ClickE doc is similar to the method Click

func (*Mouse) Down

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

Down holds the button down

func (*Mouse) DownE

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

DownE doc is similar to the method Down

func (*Mouse) Move

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

Move to the absolute position

func (*Mouse) MoveE

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

MoveE to the absolute position with specified steps

func (*Mouse) Scroll

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

Scroll with the relative offset

func (*Mouse) ScrollE

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

ScrollE the relative offset with specified steps

func (*Mouse) Up

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

Up release the button

func (*Mouse) UpE

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

UpE doc is similar to the method Up

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 string) *Page

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

func (*Page) AddScriptTagE

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

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

func (*Page) AddStyleTag

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

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

func (*Page) AddStyleTagE

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

AddStyleTagE 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()

Close page

func (*Page) CloseE

func (p *Page) CloseE() error

CloseE 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

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) CookiesE

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

CookiesE 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 EachEventE(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

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

func (*Page) ElementByJS

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

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

func (*Page) ElementByJSE

func (p *Page) ElementByJSE(sleeper kit.Sleeper, thisID proto.RuntimeRemoteObjectID, js string, params Array) (*Element, error)

ElementByJSE returns the element from the return value of the js function. sleeper is used to sleep before retry the operation. 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", ElementByJSE will retry, you can use custom sleeper to make it only retry once.

func (*Page) ElementE

func (p *Page) ElementE(sleeper kit.Sleeper, objectID proto.RuntimeRemoteObjectID, selectors []string) (*Element, error)

ElementE finds element by css selector

func (*Page) ElementFromNode added in v0.47.0

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

ElementFromNode creates an Element from the node id

func (*Page) ElementFromNodeE added in v0.47.0

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

ElementFromNodeE 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(left, top int) *Element

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

func (*Page) ElementFromPointE added in v0.48.0

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

ElementFromPointE 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

ElementMatches 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.ElementMatches("div", "click me"). The regex is the js regex, not golang's.

func (*Page) ElementMatchesE

func (p *Page) ElementMatchesE(sleeper kit.Sleeper, objectID proto.RuntimeRemoteObjectID, pairs []string) (*Element, error)

ElementMatchesE doc is similar to the method ElementMatches

func (*Page) ElementX

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

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

func (*Page) ElementXE

func (p *Page) ElementXE(sleeper kit.Sleeper, objectID proto.RuntimeRemoteObjectID, xPaths []string) (*Element, error)

ElementXE finds elements by XPath

func (*Page) Elements

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

Elements returns all elements that match the css selector

func (*Page) ElementsByJS

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

ElementsByJS returns the elements from the return value of the js

func (*Page) ElementsByJSE

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

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

func (*Page) ElementsE

func (p *Page) ElementsE(objectID proto.RuntimeRemoteObjectID, selector string) (Elements, error)

ElementsE doc is similar to the method Elements

func (*Page) ElementsX

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

ElementsX returns all elements that match the XPath selector

func (*Page) ElementsXE

func (p *Page) ElementsXE(objectID proto.RuntimeRemoteObjectID, xpath string) (Elements, error)

ElementsXE doc is similar to the method ElementsX

func (*Page) Emulate added in v0.42.1

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

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

func (*Page) EmulateE added in v0.42.1

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

EmulateE 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, params ...interface{}) proto.JSON

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

func (*Page) EvalE

func (p *Page) EvalE(byValue bool, thisID proto.RuntimeRemoteObjectID, js string, jsArgs Array) (*proto.RuntimeRemoteObject, error)

EvalE 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) EvalOnNewDocument added in v0.44.0

func (p *Page) EvalOnNewDocument(js string)

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

func (*Page) EvalOnNewDocumentE added in v0.44.0

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

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

func (*Page) Expose added in v0.49.1

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

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) ExposeE added in v0.49.1

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

ExposeE 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) func() []byte

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

func (*Page) GetDownloadFileE

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

GetDownloadFileE 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

GetWindow get window bounds

func (*Page) GetWindowE

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

GetWindowE doc is similar to the method GetWindow

func (*Page) HandleDialog

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

HandleDialog 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) HandleDialogE

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

HandleDialogE doc is similar to the method HandleDialog

func (*Page) Has

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

Has an element that matches the css selector

func (*Page) HasE

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

HasE doc is similar to the method Has

func (*Page) HasMatches

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

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

func (*Page) HasMatchesE

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

HasMatchesE doc is similar to the method HasMatches

func (*Page) HasX

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

HasX an element that matches the XPath selector

func (*Page) HasXE

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

HasXE doc is similar to the method HasX

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

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

func (*Page) InfoE added in v0.42.1

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

InfoE 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) Navigate

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

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

func (*Page) NavigateE

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

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

func (*Page) ObjectToJSON

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

ObjectToJSON by remote object

func (*Page) ObjectToJSONE

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

ObjectToJSONE by object id

func (*Page) ObjectsToJSON

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

ObjectsToJSON by remote objects

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() []byte

PDF prints page as PDF

func (*Page) PDFE

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

PDFE prints page as PDF

func (*Page) Pause

func (p *Page) Pause() *Page

Pause stops on the next JavaScript statement

func (*Page) PauseE

func (p *Page) PauseE() error

PauseE doc is similar to the method Pause

func (*Page) Release

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

Release remote object

func (*Page) ReleaseE

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

ReleaseE doc is similar to the method Release

func (*Page) Root

func (p *Page) Root() *Page

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

func (*Page) Screenshot

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

Screenshot 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) ScreenshotFullPage

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

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

func (*Page) Search added in v0.47.0

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

Search 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) SearchE added in v0.47.0

func (p *Page) SearchE(sleeper kit.Sleeper, queries []string, from, to int) (Elements, error)

SearchE 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) *Page

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

func (*Page) SetCookiesE

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

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

func (*Page) SetExtraHeaders

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

SetExtraHeaders 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) SetExtraHeadersE

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

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

func (*Page) SetUserAgent

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

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) SetUserAgentE

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

SetUserAgentE 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) StopLoading

func (p *Page) StopLoading() *Page

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

func (*Page) StopLoadingE

func (p *Page) StopLoadingE() error

StopLoadingE 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(width, height int64, deviceScaleFactor float64, mobile bool) *Page

Viewport overrides the values of device screen dimensions.

func (*Page) ViewportE

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

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

func (*Page) Wait

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

Wait js function until it returns true

func (*Page) WaitE

func (p *Page) WaitE(sleeper kit.Sleeper, thisID proto.RuntimeRemoteObjectID, js string, params Array) error

WaitE 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() *Page

WaitIdle wait until the next window.requestIdleCallback is called.

func (*Page) WaitIdleE

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

WaitIdleE doc is similar to the method WaitIdle

func (*Page) WaitLoad

func (p *Page) WaitLoad() *Page

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

func (*Page) WaitLoadE

func (p *Page) WaitLoadE() error

WaitLoadE doc is similar to the method WaitLoad

func (*Page) WaitOpen

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

WaitOpen waits for a new page opened by the current one

func (*Page) WaitOpenE

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

WaitOpenE doc is similar to the method WaitPage

func (*Page) WaitRequestIdle

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

WaitRequestIdle 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) WaitRequestIdleE

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

WaitRequestIdleE 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.

func (*Page) Window

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

Window set the window location and size

func (*Page) WindowFullscreen

func (p *Page) WindowFullscreen() *Page

WindowFullscreen the window

func (*Page) WindowMaximize

func (p *Page) WindowMaximize() *Page

WindowMaximize the window

func (*Page) WindowMinimize

func (p *Page) WindowMinimize() *Page

WindowMinimize the window

func (*Page) WindowNormal

func (p *Page) WindowNormal() *Page

WindowNormal the window size

type Pages

type Pages []*Page

Pages provides some helpers to deal with page list

func (Pages) Find

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

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

func (Pages) FindByURL

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

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

func (Pages) FindByURLE

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

FindByURLE 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