rod

package module
v0.85.8 Latest Latest
Warning

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

Go to latest
Published: Dec 18, 2020 License: MIT Imports: 33 Imported by: 585

README

Overview

Go Reference Discord Chat

Documentation | API reference

Rod is a high-level driver directly based on DevTools Protocol. It's designed for web automation and scraping. Rod is designed for both high-level and low-level use, senior programmers can use the low-level packages and functions to easily customize or build up their own version of Rod, the high-level functions are just examples to build a default version of Rod.

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
  • Lightweight, no third-party dependencies, CI tested on Linux, Mac, and Windows
  • High-level helpers like WaitStable, WaitRequestIdle, HijackRequests, WaitDownload, etc
  • Two-step WaitEvent design, never miss an event (how it works)
  • Correctly handles nested iframes or shadow DOMs
  • 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. Use the type definitions of the JSON-RPC to perform high-level actions. The lib handles it is proto.

Object model:

object model

FAQ

Q: How to contribute or become a maintainer

Please check this doc.

Q: How to use Rod with docker so that I don't have to install a browser

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: 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 the name of a control device for puppetry, such as this image. The meaning is we are the puppeteer, the browser is the puppet, we use the rod to control the puppet.

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 Github's release comparison to see the automated changelog, for example, compare v0.75.2 with v0.76.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

    Theoretically, Rod should perform faster and consume less memory than Chromedp.

    Chromedp uses a fix-sized buffer for events, it can cause dead-lock on high concurrency. Because Chromedp uses a single event-loop, the slow event handlers will block each other. Rod doesn't have these issues because it's based on goob.

    Chromedp will JSON decode every message from the browser, rod is decode-on-demand, so Rod performs better, especially for heavy network events.

    Chromedp uses third part WebSocket lib which has 1MB overhead for each cdp client, if you want to control thousands of remote browsers it can become a problem. Because of this limitation, if you evaluate a js script larger than 1MB, Chromedp will crash, here's an example of how easy you can crash Chromedp: gist.

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

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

    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 make the static types useless when tracking issues. In contrast, Rod uses as few interfaces as possible.

    Rod has less dependencies, a simpler code structure and better test automation, 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.

    Another problem of Chromedp is their architecture is based on DOM node id, 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. Even after it's closed, you still can't evaluate js express on the element inside an iframe.

  • puppeteer

    Puppeteer will JSON decode every message from the browser, Rod is decode-on-demand, so theoretically Rod will perform better, especially for heavy network events.

    With puppeteer, you have to handle promise/async/await a lot, it makes elegant fluent interface design very hard. 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. If you forget to write a await, it's usually painful to debug leaking Promise. The overhead grows when your project grows.

    Rod is type-safe by default, and has better internal comments about how Rod itself works. It has type bindings for all endpoints in 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.

    Rod supports cancellation and timeout better, this can be critical if you want to handle thousands of pages. For example, to simulate click we have to send serval cdp requests, with Promise you can't achieve something like "only send half of the cdp requests", but with the context we can.

  • playwright

    Rod and Playwright were first published almost at the same time. It's a great step forward for the Puppeteer team. Most comparisons between Rod and Puppeteer remain true to Playwright.

    One of Rod's architectural goal is to make it easier for everyone to contribute and make it a pure community project, that's one big reason why I chose Golang and the MIT license. Typescript is a nice choice but if you check Playwright's design choices, any and union types are everywhere, if you try to jump to the source code of page.click, d.ts files will let you understand the reality of typescript. Golang is definitely not good enough, but it usually introduces less tech debt than node.js typescript, if you want me to choose which one to use for QA or Infra who's not familiar with coding to automate end-to-end test or site-monitoring, I would pick Golang.

    Their effort for cross-browser support is fabulous. But nowadays, HTML5 is well adopted by main brands, it's hard to say the complexity it brings can weight the benefits. Will the cross-browser patches become a burden in the future? Security issues for patched browsers is another concern. It also makes it tricky to test old versions of Firefox or Safari. Hope it's not over-engineering.

  • 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 pages 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

This example opens https://github.com/, searches for "git", and then gets the header element which gives the description for Git.

package main

import (
	"fmt"

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

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

	// 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.
	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("Found", len(page.MustElements("input")), "input elements")

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

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

	// When eval on an element, "this" in the js is the current DOM element.
	fmt.Println(page.MustElement("title").MustEval(`this.innerText`).String())

}
Output:

Git is the most widely used version control system.
Found 5 input elements
1 + 2 = 3
Search · git · GitHub
Example (Context_and_timeout)

Rod use https://golang.org/pkg/context to handle cancelations for IO blocking operations, most times it's timeout. Context will be recursively passed to all sub-methods. For example, methods like Page.Context(ctx) will return a clone of the page with the ctx, all the methods of the returned page will use the ctx if they have IO blocking operations. Page.Timeout or Page.WithCancel is just a shortcut for Page.Context. Of course, Browser or Element works the same way.

package main

import (
	"math/rand"
	"time"

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

func main() {
	page := rod.New().MustConnect().MustPage("https://github.com")

	page.
		// Set a 5-second timeout for all chained methods
		Timeout(5 * time.Second).

		// The total time for MustWaitLoad and MustElement must be less than 5 seconds
		MustWaitLoad().
		MustElement("title").

		// Methods after CancelTimeout won't be affected by the 5-second timeout
		CancelTimeout().

		// Set a 10-second timeout for all chained methods
		Timeout(10 * time.Second).

		// Panics if it takes more than 10 seconds
		MustText()

	// The two code blocks below are basically the same:
	{
		page.Timeout(5 * time.Second).MustElement("a").CancelTimeout()
	}
	{
		// Use this way you can customize your own way to cancel long-running task
		page, cancel := page.WithCancel()
		go func() {
			time.Sleep(time.Duration(rand.Int())) // cancel after randomly time
			cancel()
		}()
		page.MustElement("a")
	}
}
Output:

Example (Customize_browser_launch)

Shows how we can further customize the browser with the launcher library. Usually you use launcher lib to set the browser's command line flags (switches). Doc for flags: https://peter.sh/experiments/chromium-command-line-switches

package main

import (
	"fmt"

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

func main() {
	url := launcher.New().
		Proxy("127.0.0.1:8080").     // set flag "--proxy-server=127.0.0.1:8080"
		Delete("use-mock-keychain"). // delete flag "--use-mock-keychain"
		MustLaunch()

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

	// So that we don't have to self issue certs for MITM
	browser.MustIgnoreCertErrors(true)

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

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

Example (Customize_retry_strategy)

Shows how 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"
	"github.com/go-rod/rod/lib/utils"
)

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

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

	// sleep for 0.5 seconds before every retry
	sleeper := func() utils.Sleeper {
		return 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)

When rod doesn't have a feature that you need. You can easily call the cdp to achieve it. List of cdp API: https://chromedevtools.github.io/devtools-protocol

package main

import (
	"context"

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

func main() {
	page := rod.New().MustConnect().MustPage("")

	// Rod doesn't have a method to enable AD blocking,
	// but you can call cdp interface directly to achieve it.
	// Doc: https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-setAdBlockingEnabled

	// The two code blocks below are equal to enable AD blocking

	{
		_ = proto.PageSetAdBlockingEnabled{
			Enabled: true,
		}.Call(page)
	}

	{
		// Interact with the cdp JSON API directly
		_, _ = page.Call(context.TODO(), "", "Page.setAdBlockingEnabled", map[string]bool{
			"enabled": true,
		})
	}
}
Output:

Example (Disable_headless_to_debug)

Shows how to disable headless mode and debug. Rod provides a lot of debug options, you can set them with setter methods or use environment variables. Doc for environment variables: https://pkg.go.dev/github.com/go-rod/rod/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"
	"github.com/go-rod/rod/lib/utils"
)

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() // remove user-data-dir

	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().
		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.
	// You can also enable it with env rod=monitor
	launcher.NewBrowser().Open(browser.ServeMonitor(""))

	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

	utils.Pause() // pause goroutine
}
Output:

Example (Download_file)
package main

import (
	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/utils"
)

func main() {
	browser := rod.New().MustConnect()
	page := browser.MustPage("https://file-examples.com/index.php/sample-documents-download/sample-pdf-download/")

	wait := browser.MustWaitDownload()

	page.MustElementR("a", "DOWNLOAD SAMPLE PDF FILE").MustClick()

	_ = utils.OutputFile("t.pdf", wait())
}
Output:

Example (Error_handling)

We use "Must" prefixed functions to write example code. But in production you may want to use the no-prefix version of them. About why we use "Must" as the prefix, it's similar to https://golang.org/pkg/regexp/#MustCompile

package main

import (
	"context"
	"errors"
	"fmt"

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

func main() {
	page := rod.New().MustConnect().MustPage("https://example.com")

	// We use Go's standard way to check error types, no magic.
	check := func(err error) {
		var evalErr *rod.ErrEval
		if errors.Is(err, context.DeadlineExceeded) { // timeout error
			fmt.Println("timeout err")
		} else if errors.As(err, &evalErr) { // eval error
			fmt.Println(evalErr.LineNumber)
		} else if err != nil {
			fmt.Println("can't handle", err)
		}
	}

	// The two code blocks below are doing the same thing in two styles:

	// The block below is better for debugging or quick scripting. We use panic to short-circuit logics.
	// So that we can take advantage of fluent interface (https://en.wikipedia.org/wiki/Fluent_interface)
	// and fail-fast (https://en.wikipedia.org/wiki/Fail-fast).
	// This style will reduce code, but it may also catch extra errors (less consistent and precise).
	{
		err := rod.Try(func() {
			fmt.Println(page.MustElement("a").MustHTML()) // use "Must" prefixed functions
		})
		check(err)
	}

	// The block below is better for production code. It's the standard way to handle errors.
	// Usually, this style is more consistent and precise.
	{
		el, err := page.Element("a")
		if err != nil {
			check(err)
			return
		}
		html, err := el.HTML()
		if err != nil {
			check(err)
			return
		}
		fmt.Println(html)
	}
}
Output:

Example (Eval_reuse_remote_object)

Shows how to share a remote object reference between two Eval

package main

import (
	"fmt"

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

func main() {
	page := rod.New().MustConnect().MustPage("")

	fn := page.MustEvaluate(rod.Eval(`Math.random`).ByObject())

	res := page.MustEval(`f => f()`, fn)

	// print a random number
	fmt.Println(res.Num())
}
Output:

Example (Handle_events)

Shows how to listen for events.

package main

import (
	"context"
	"fmt"

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

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

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	page := browser.Context(ctx).MustPage("")

	done := make(chan int)

	// Listen for all events of console output. You can even listen to multiple types of events at that same time,
	// check the doc of EachEvent for details.
	go page.EachEvent(func(e *proto.RuntimeConsoleAPICalled) {
		fmt.Println(page.MustObjectsToJSON(e.Args))
		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 to unsubscribe events.
		wait := page.EachEvent(func(e *proto.PageLoadEventFired) (stop bool) {
			return true
		})
		page.MustNavigate("https://example.com")
		wait()
	}

	// Or the for-loop style to handle events to do the same thing above.
	if false {
		page.MustNavigate("https://example.com")

		for msg := range page.Event() {
			e := proto.PageLoadEventFired{}
			if msg.Load(&e) {
				break
			}
		}
	}

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

	<-done

}
Output:

[hello world]
Example (Hijack_requests)

Shows how to intercept requests and modify both the request and the response. The entire process of hijacking one request:

browser --req-> rod ---> server ---> rod --res-> browser

The --req-> and --res-> are the parts that can be modified.

package main

import (
	"fmt"

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

func main() {
	browser := rod.New().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.Req().Header.Set("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
		// ctx.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.Body() + "\n document.title = 'hi' ")
	})

	go router.Run()

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

	fmt.Println("done")

}
Output:

done
Example (Load_extension)
package main

import (
	"fmt"
	"path/filepath"

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

func main() {
	extPath, _ := filepath.Abs("fixtures/chrome-extension")

	u := launcher.New().
		Set("load-extension", extPath). // must use abs path for an extension
		Headless(false).                // headless mode doesn't support extension yet
		MustLaunch()

	page := rod.New().ControlURL(u).MustConnect().MustPage("http://example.com")

	page.MustWait(`document.title === 'test-extension'`)

	fmt.Println("ok")

	// Skip
	
Output:

Example (Page_pdf)
package main

import (
	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/proto"
	"github.com/go-rod/rod/lib/utils"
)

func main() {
	page := rod.New().MustConnect().MustPage("")

	wait := page.MustWaitNavigation()
	page.MustNavigate("https://github.com")
	wait() // until the navigation to settle down

	// simple version
	page.MustPDF("my.pdf")

	// customization version
	pdf, _ := page.PDF(&proto.PagePrintToPDF{
		PaperWidth:              8.5,
		PaperHeight:             11,
		PageRanges:              "1-3",
		IgnoreInvalidPageRanges: false,
		DisplayHeaderFooter:     true,
	})
	_ = utils.OutputFile("my.pdf", pdf)
}
Output:

Example (Page_screenshot)
package main

import (
	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/proto"
	"github.com/go-rod/rod/lib/utils"
)

func main() {
	page := rod.New().MustConnect().MustPage("")

	wait := page.MustWaitNavigation()
	page.MustNavigate("https://github.com")
	wait() // until the navigation to settle down

	// simple version
	page.MustScreenshot("my.png")

	// customization version
	img, _ := page.Screenshot(true, &proto.PageCaptureScreenshot{
		Format:  proto.PageCaptureScreenshotFormatJpeg,
		Quality: 90,
		Clip: &proto.PageViewport{
			X:      0,
			Y:      0,
			Width:  300,
			Height: 200,
			Scale:  1,
		},
		FromSurface: true,
	})
	_ = utils.OutputFile("my.jpg", img)
}
Output:

Example (Race_selectors)

Show how to handle multiple results of an action. Such as when you login a page, the result can be success or wrong password.

package main

import (
	"fmt"

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

func main() {
	const username = ""
	const password = ""

	browser := rod.New().MustConnect()

	page := browser.MustPage("https://leetcode.com/accounts/login/")

	page.MustElement("#id_login").MustInput(username)
	page.MustElement("#id_password").MustInput(password).MustPress(input.Enter)

	// It will keep retrying until one selector has found a match
	elm := page.Race().Element(".nav-user-icon-base").MustHandle(func(e *rod.Element) {
		// print the username after successful login
		fmt.Println(*e.MustAttribute("title"))
	}).Element("[data-cy=sign-in-error]").MustDo()

	if elm.MustMatches("[data-cy=sign-in-error]") {
		// when wrong username or password
		panic(elm.MustText())
	}
}
Output:

Example (States)

Shows how to update the state of the current page. In this example we enable the network domain.

package main

import (
	"fmt"

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

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

	page := browser.MustPage("")

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

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

	// Check if the network domain is successfully enabled.
	fmt.Println(page.LoadState(&proto.NetworkEnable{}))

}
Output:

false
true
Example (Wait_for_animation)

Rod uses mouse cursor to simulate clicks, so if a button is moving because of animation, the click may not work as expected. We usually use WaitStable to make sure the target isn't changing anymore.

package main

import (
	"fmt"

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

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

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

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

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

	// Here, WaitStable will wait until the button's position and size become stable.
	saveBtn.MustWaitStable().MustClick().MustWaitInvisible()

	fmt.Println("done")

}
Output:

done
Example (Wait_for_request)

When you want to wait for an ajax request to complete, this example will be useful.

package main

import (
	"fmt"

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

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

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

	// Start to analyze request events
	wait := page.MustWaitRequestIdle()

	// This will trigger the search ajax request
	page.MustElement("#search_form_input_homepage").MustClick().MustInput("test")

	// Wait until there's no active requests
	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 DefaultLogger = log.New(os.Stdout, "[rod] ", log.LstdFlags)

DefaultLogger for rod

View Source
var DefaultSleeper = func() utils.Sleeper {
	return utils.BackoffSleeper(100*time.Millisecond, time.Second, nil)
}

DefaultSleeper generates 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

Why the default is not RequestAnimationFrame or DOM change events is because of if a retry never ends it can easily flood the program. But you can always easily config it into what you want.

Functions

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

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

Call raw cdp interface directly

func (*Browser) CancelTimeout

func (b *Browser) CancelTimeout() *Browser

CancelTimeout cancels the current timeout context and returns a clone with the parent context

func (*Browser) Client

func (b *Browser) Client(c CDPClient) *Browser

Client set the cdp client

func (*Browser) Close

func (b *Browser) Close() error

Close the browser

func (*Browser) Connect

func (b *Browser) Connect() error

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

func (*Browser) Context

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

Context returns a clone with the specified ctx for chained sub-operations

func (*Browser) ControlURL

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

ControlURL set the url to remote control browser.

func (*Browser) DefaultDevice added in v0.71.0

func (b *Browser) DefaultDevice(d devices.Device) *Browser

DefaultDevice sets the default device for new page in the future. Default is devices.LaptopWithMDPIScreen . Set it to devices.Clear to disable it.

func (*Browser) DisableDomain

func (b *Browser) DisableDomain(sessionID proto.TargetSessionID, req proto.Request) (restore func())

DisableDomain and returns a restore function to restore previous state

func (*Browser) EachEvent

func (b *Browser) EachEvent(callbacks ...interface{}) (wait func())

EachEvent of the specified event types, if any callback returns true the wait function will resolve, The type of each callback is (? means optional):

func(proto.Event, proto.TargetSessionID?) bool?

You can listen to multiple event types at the same time like:

browser.EachEvent(func(a *proto.A) {}, func(b *proto.B) {})

func (*Browser) EnableDomain

func (b *Browser) EnableDomain(sessionID proto.TargetSessionID, req proto.Request) (restore func())

EnableDomain and returns a restore function to restore previous state

func (*Browser) Event

func (b *Browser) Event() <-chan *Message

Event of the browser

func (*Browser) GetContext

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

GetContext of current instance

func (*Browser) GetCookies added in v0.71.0

func (b *Browser) GetCookies() ([]*proto.NetworkCookie, error)

GetCookies from the browser

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) Headless added in v0.63.0

func (b *Browser) Headless() bool

Headless mode or not

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) IgnoreCertErrors added in v0.61.3

func (b *Browser) IgnoreCertErrors(enable bool) error

IgnoreCertErrors switch. If enabled, all certificate errors will be ignored.

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.Request) (has bool)

LoadState into the method, seesionID can be empty.

func (*Browser) Logger added in v0.70.0

func (b *Browser) Logger(l utils.Logger) *Browser

Logger overrides the default log functions for tracing

func (*Browser) Monitor added in v0.70.0

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

Monitor address to listen if not empty. Shortcut for Browser.ServeMonitor

func (*Browser) MustClose added in v0.50.0

func (b *Browser) MustClose()

MustClose is similar to Close

func (*Browser) MustConnect added in v0.50.0

func (b *Browser) MustConnect() *Browser

MustConnect is similar to Connect

func (*Browser) MustGetCookies added in v0.71.0

func (b *Browser) MustGetCookies() []*proto.NetworkCookie

MustGetCookies is similar GetCookies

func (*Browser) MustHandleAuth added in v0.50.0

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

MustHandleAuth is similar to HandleAuth

func (*Browser) MustIgnoreCertErrors added in v0.61.3

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

MustIgnoreCertErrors is similar to IgnoreCertErrors

func (*Browser) MustIncognito added in v0.50.0

func (b *Browser) MustIncognito() *Browser

MustIncognito is similar to Incognito

func (*Browser) MustPage added in v0.50.0

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

MustPage is similar to Page

func (*Browser) MustPageFromTargetID added in v0.50.0

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

MustPageFromTargetID is similar to PageFromTargetID

func (*Browser) MustPages added in v0.50.0

func (b *Browser) MustPages() Pages

MustPages is similar to Pages

func (*Browser) MustSetCookies added in v0.71.0

func (b *Browser) MustSetCookies(cookies []*proto.NetworkCookie) *Browser

MustSetCookies is similar SetCookies

func (*Browser) MustWaitDownload added in v0.83.0

func (b *Browser) MustWaitDownload() func() []byte

MustWaitDownload is similar to WaitDownload. It will read the file into bytes then remove the file.

func (*Browser) NoDefaultDevice added in v0.81.1

func (b *Browser) NoDefaultDevice() *Browser

NoDefaultDevice is the same as DefaultDevice(devices.Clear)

func (*Browser) Page

func (b *Browser) Page(opts proto.TargetCreateTarget) (p *Page, err error)

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

func (*Browser) PageFromSession added in v0.74.0

func (b *Browser) PageFromSession(sessionID proto.TargetSessionID) *Page

PageFromSession is used for low-level debugging

func (*Browser) PageFromTarget added in v0.50.0

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

PageFromTarget gets or creates a Page instance.

func (*Browser) Pages

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

Pages retrieves all visible pages

func (*Browser) RemoveState added in v0.74.0

func (b *Browser) RemoveState(key interface{})

RemoveState a state

func (*Browser) ServeMonitor

func (b *Browser) ServeMonitor(host string) string

ServeMonitor starts the monitor server. The reason why not to use "chrome://inspect/#devices" is one target cannot be driven by multiple controllers.

func (*Browser) SetCookies added in v0.71.0

func (b *Browser) SetCookies(cookies []*proto.NetworkCookieParam) error

SetCookies to the browser

func (*Browser) Sleeper added in v0.50.0

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

Sleeper returns a clone with for chained sub-operations

func (*Browser) SlowMotion added in v0.77.0

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 returns a clone with the specified timeout context.Context 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) WaitDownload added in v0.83.0

func (b *Browser) WaitDownload(dir string) func() (info *proto.PageDownloadWillBegin)

WaitDownload returns a helper to get the next download file. The file path will be:

filepath.Join(dir, info.GUID)

func (*Browser) WaitEvent

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

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

func (*Browser) WithCancel added in v0.69.0

func (b *Browser) WithCancel() (*Browser, func())

WithCancel returns a clone with a context cancel function

type CDPClient added in v0.70.0

type CDPClient interface {
	Connect(ctx context.Context) error
	Event() <-chan *cdp.Event
	Call(ctx context.Context, sessionID, method string, params interface{}) ([]byte, error)
}

CDPClient is usually used to make rod side-effect free. Such as proxy all IO of rod.

type Element

type Element struct {
	Object *proto.RuntimeRemoteObject
	// contains filtered or unexported fields
}

Element represents the DOM element

func (*Element) Attribute

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

Attribute of the DOM object. Attribute vs Property: https://stackoverflow.com/questions/6003819/what-is-the-difference-between-properties-and-attributes-in-html

func (*Element) BackgroundImage added in v0.76.6

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

BackgroundImage returns the css background-image of the element

func (*Element) Blur

func (el *Element) Blur() error

Blur is similar to the method Blur

func (*Element) Call added in v0.70.0

func (el *Element) Call(ctx context.Context, sessionID, methodName string, params interface{}) (res []byte, err error)

Call implements the proto.Client

func (*Element) CancelTimeout

func (el *Element) CancelTimeout() *Element

CancelTimeout cancels the current timeout context and returns a clone with the parent 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) 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) *Element

Context returns a clone with the specified ctx for chained sub-operations

func (*Element) Describe

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

Describe the current element

func (*Element) Element

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

Element returns the first child that matches the css selector

func (*Element) ElementByJS

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

ElementByJS returns the element from the return value of the js

func (*Element) ElementR added in v0.57.0

func (el *Element) ElementR(selector, jsRegex string) (*Element, error)

ElementR returns the first child element that matches the css selector and its text matches the jsRegex.

func (*Element) ElementX

func (el *Element) ElementX(xPath string) (*Element, error)

ElementX returns the first child that matches the XPath selector

func (*Element) Elements

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

Elements returns all elements that match the css selector

func (*Element) ElementsByJS

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

ElementsByJS returns the elements from the return value of the js

func (*Element) ElementsX

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

ElementsX returns all elements that match the XPath selector

func (*Element) Equal added in v0.85.7

func (el *Element) Equal(elm *Element) (bool, error)

Equal checks if the two elements are equal.

func (*Element) Eval

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

Eval js on the page. For more info check the Element.Evaluate

func (*Element) Evaluate added in v0.67.0

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

Evaluate is just a shortcut of Page.Evaluate with This set to current element.

func (*Element) Focus

func (el *Element) Focus() error

Focus sets focus on the specified element

func (*Element) Frame

func (el *Element) Frame() (*Page, error)

Frame creates a page instance that represents the iframe

func (*Element) GetContext

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

GetContext of current instance

func (*Element) GetSessionID added in v0.72.0

func (el *Element) GetSessionID() proto.TargetSessionID

GetSessionID interface

func (*Element) HTML

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

HTML of the element

func (*Element) Has

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

Has an element that matches the css selector

func (*Element) HasR added in v0.61.0

func (el *Element) HasR(selector, jsRegex string) (bool, *Element, error)

HasR returns true if a child element that matches the css selector and its text matches the jsRegex.

func (*Element) HasX

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

HasX an element that matches the XPath selector

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 focuses on the element and input text to it. To empty the input you can use something like el.SelectAllText().MustInput("")

func (*Element) InputTime added in v0.79.2

func (el *Element) InputTime(t time.Time) error

InputTime focuses on the element and input time to it.

func (*Element) Interactable added in v0.66.0

func (el *Element) Interactable() (pt *proto.Point, err error)

Interactable checks if the element is interactable with cursor. The cursor can be mouse, finger, stylus, etc. If not interactable err will be ErrNotInteractable, such as when covered by a modal,

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 is similar to Attribute

func (*Element) MustBackgroundImage added in v0.76.6

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

MustBackgroundImage is similar to BackgroundImage

func (*Element) MustBlur added in v0.50.0

func (el *Element) MustBlur() *Element

MustBlur is similar to Blur

func (*Element) MustCanvasToImage added in v0.50.0

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

MustCanvasToImage is similar to CanvasToImage

func (*Element) MustClick added in v0.50.0

func (el *Element) MustClick() *Element

MustClick is similar to Click

func (*Element) MustContainsElement added in v0.50.0

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

MustContainsElement is similar to ContainsElement

func (*Element) MustDescribe added in v0.50.0

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

MustDescribe is similar to Describe

func (*Element) MustElement added in v0.50.0

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

MustElement is similar to Element

func (*Element) MustElementByJS added in v0.50.0

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

MustElementByJS is similar to ElementByJS

func (*Element) MustElementR added in v0.57.0

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

MustElementR is similar to ElementR

func (*Element) MustElementX added in v0.50.0

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

MustElementX is similar to ElementX

func (*Element) MustElements added in v0.50.0

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

MustElements is similar to Elements

func (*Element) MustElementsByJS added in v0.50.0

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

MustElementsByJS is similar to ElementsByJS

func (*Element) MustElementsX added in v0.50.0

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

MustElementsX is similar to ElementsX

func (*Element) MustEqual added in v0.85.7

func (el *Element) MustEqual(elm *Element) bool

MustEqual is similar to Equal

func (*Element) MustEval added in v0.50.0

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

MustEval is similar to Eval

func (*Element) MustFocus added in v0.50.0

func (el *Element) MustFocus() *Element

MustFocus is similar to Focus

func (*Element) MustFrame added in v0.55.1

func (el *Element) MustFrame() *Page

MustFrame is similar to Frame

func (*Element) MustHTML added in v0.50.0

func (el *Element) MustHTML() string

MustHTML is similar to HTML

func (*Element) MustHas added in v0.50.0

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

MustHas is similar to Has

func (*Element) MustHasR added in v0.61.0

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

MustHasR is similar to HasR

func (*Element) MustHasX added in v0.50.0

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

MustHasX is similar to HasX

func (*Element) MustHover added in v0.50.0

func (el *Element) MustHover() *Element

MustHover is similar to Hover

func (*Element) MustInput added in v0.50.0

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

MustInput is similar to Input

func (*Element) MustInputTime added in v0.79.2

func (el *Element) MustInputTime(t time.Time) *Element

MustInputTime is similar to Input

func (*Element) MustInteractable added in v0.66.0

func (el *Element) MustInteractable() bool

MustInteractable is similar to Interactable

func (*Element) MustMatches added in v0.50.0

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

MustMatches is similar to Matches

func (*Element) MustNext added in v0.50.0

func (el *Element) MustNext() *Element

MustNext is similar to Next

func (*Element) MustNodeID added in v0.50.0

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

MustNodeID is similar to NodeID

func (*Element) MustParent added in v0.50.0

func (el *Element) MustParent() *Element

MustParent is similar to Parent

func (*Element) MustParents added in v0.50.0

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

MustParents is similar to Parents

func (*Element) MustPress added in v0.50.0

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

MustPress is similar to Press

func (*Element) MustPrevious added in v0.50.0

func (el *Element) MustPrevious() *Element

MustPrevious is similar to Previous

func (*Element) MustProperty added in v0.50.0

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

MustProperty is similar to Property

func (*Element) MustRelease added in v0.50.0

func (el *Element) MustRelease()

MustRelease is similar to Release

func (*Element) MustRemove added in v0.66.0

func (el *Element) MustRemove()

MustRemove the element from the page

func (*Element) MustResource added in v0.50.0

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

MustResource is similar to Resource

func (*Element) MustScreenshot added in v0.50.0

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

MustScreenshot is similar to Screenshot

func (*Element) MustScrollIntoView added in v0.50.0

func (el *Element) MustScrollIntoView() *Element

MustScrollIntoView is similar to ScrollIntoView

func (*Element) MustSelect added in v0.50.0

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

MustSelect is similar to Select

func (*Element) MustSelectAllText added in v0.50.0

func (el *Element) MustSelectAllText() *Element

MustSelectAllText is similar to SelectAllText

func (*Element) MustSelectText added in v0.50.0

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

MustSelectText is similar to SelectText

func (*Element) MustSetFiles added in v0.50.0

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

MustSetFiles is similar to SetFiles

func (*Element) MustShadowRoot added in v0.50.0

func (el *Element) MustShadowRoot() *Element

MustShadowRoot is similar to ShadowRoot

func (*Element) MustShape added in v0.66.0

func (el *Element) MustShape() *proto.DOMGetContentQuadsResult

MustShape is similar to Shape

func (*Element) MustTap added in v0.61.4

func (el *Element) MustTap() *Element

MustTap is similar to Tap

func (*Element) MustText added in v0.50.0

func (el *Element) MustText() string

MustText is similar to Text

func (*Element) MustVisible added in v0.50.0

func (el *Element) MustVisible() bool

MustVisible is similar to Visible

func (*Element) MustWait added in v0.50.0

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

MustWait is similar to Wait

func (*Element) MustWaitEnabled added in v0.84.1

func (el *Element) MustWaitEnabled()

MustWaitEnabled is similar to WaitEnabled

func (*Element) MustWaitInvisible added in v0.50.0

func (el *Element) MustWaitInvisible() *Element

MustWaitInvisible is similar to WaitInvisible

func (*Element) MustWaitLoad added in v0.50.0

func (el *Element) MustWaitLoad() *Element

MustWaitLoad is similar to WaitLoad

func (*Element) MustWaitStable added in v0.50.0

func (el *Element) MustWaitStable() *Element

MustWaitStable is similar to WaitStable

func (*Element) MustWaitVisible added in v0.50.0

func (el *Element) MustWaitVisible() *Element

MustWaitVisible is similar to WaitVisible

func (*Element) MustWaitWritable added in v0.84.1

func (el *Element) MustWaitWritable()

MustWaitWritable is similar to WaitWritable

func (*Element) Next

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

Next returns the next sibling element in the DOM tree

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 returns the parent element in the DOM tree

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 a key

func (*Element) Previous

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

Previous returns the previous sibling element in the DOM tree

func (*Element) Property

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

Property of the DOM object. Property vs Attribute: https://stackoverflow.com/questions/6003819/what-is-the-difference-between-properties-and-attributes-in-html

func (*Element) Release

func (el *Element) Release() error

Release is a shortcut for Page.Release(el.Object)

func (*Element) Remove added in v0.66.0

func (el *Element) Remove() error

Remove the element from the page

func (*Element) Resource

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

Resource returns the "src" content of current element. Such as the jpg of <img src="a.jpg">

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 scrolls the current element into the visible area of the browser window if it's not already within the visible area.

func (*Element) Select

func (el *Element) Select(selectors []string, selected bool, t SelectorType) error

Select the children option elements that match the selectors.

func (*Element) SelectAllText

func (el *Element) SelectAllText() error

SelectAllText selects all text

func (*Element) SelectText

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

SelectText selects the text that matches the regular expression

func (*Element) SetFiles

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

SetFiles of the current file input element

func (*Element) ShadowRoot

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

ShadowRoot returns the shadow root of this element

func (*Element) Shape added in v0.66.0

func (el *Element) Shape() (*proto.DOMGetContentQuadsResult, error)

Shape of the DOM element content. The shape is a group of 4-sides polygons (4-gons). A 4-gon is not necessary a rectangle. 4-gons can be apart from each other. For example, we use 2 4-gons to describe the shape below:

┌────────┐   ┌────────┐
│    ┌───┘ = └────────┘ + ┌────┐
└────┘                    └────┘

func (*Element) Sleeper added in v0.50.0

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

Sleeper returns a clone with for chained sub-operations

func (*Element) Tap added in v0.61.4

func (el *Element) Tap() error

Tap the button just like a human.

func (*Element) Text

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

Text that the element displays

func (*Element) Timeout

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

Timeout returns a clone with the specified timeout context.Context 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 returns true if the element is visible on the page

func (*Element) Wait

func (el *Element) Wait(opts *EvalOptions) error

Wait until the js returns true

func (*Element) WaitEnabled added in v0.84.1

func (el *Element) WaitEnabled() error

WaitEnabled until the element is not disabled. Doc for readonly: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly

func (*Element) WaitInvisible

func (el *Element) WaitInvisible() error

WaitInvisible until the element invisible

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(d time.Duration) error

WaitStable waits until no shape or position change for d duration. Be careful, d is not the max wait timeout, it's the least stable time. If you want to set a timeout you can use the "Element.Timeout" function.

func (*Element) WaitStableRAF added in v0.84.1

func (el *Element) WaitStableRAF() error

WaitStableRAF waits until no shape or position change for 2 consecutive animation frames. If you want to wait animation that is triggered by JS not CSS, you'd better use Element.WaitStable. About animation frame: https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

func (*Element) WaitVisible

func (el *Element) WaitVisible() error

WaitVisible until the element is visible

func (*Element) WaitWritable added in v0.84.1

func (el *Element) WaitWritable() error

WaitWritable until the element is not readonly. Doc for disabled: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/disabled

func (*Element) WithCancel added in v0.69.0

func (el *Element) WithCancel() (*Element, func())

WithCancel returns a clone with a context cancel function

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 ErrCovered added in v0.73.0

type ErrCovered struct {
	*Element
}

ErrCovered error.

func (*ErrCovered) Error added in v0.73.0

func (e *ErrCovered) Error() string

Error ...

func (*ErrCovered) Is added in v0.73.0

func (e *ErrCovered) Is(err error) bool

Is interface

func (*ErrCovered) Unwrap added in v0.73.0

func (e *ErrCovered) Unwrap() error

Unwrap ...

type ErrElementNotFound

type ErrElementNotFound struct {
}

ErrElementNotFound error

func (*ErrElementNotFound) Error added in v0.73.0

func (e *ErrElementNotFound) Error() string

type ErrEval

type ErrEval struct {
	*proto.RuntimeExceptionDetails
}

ErrEval error

func (*ErrEval) Error added in v0.73.0

func (e *ErrEval) Error() string

func (*ErrEval) Is added in v0.73.0

func (e *ErrEval) Is(err error) bool

Is interface

type ErrExpectElement

type ErrExpectElement struct {
	*proto.RuntimeRemoteObject
}

ErrExpectElement error

func (*ErrExpectElement) Error added in v0.73.0

func (e *ErrExpectElement) Error() string

func (*ErrExpectElement) Is added in v0.73.0

func (e *ErrExpectElement) Is(err error) bool

Is interface

type ErrExpectElements

type ErrExpectElements struct {
	*proto.RuntimeRemoteObject
}

ErrExpectElements error

func (*ErrExpectElements) Error added in v0.73.0

func (e *ErrExpectElements) Error() string

func (*ErrExpectElements) Is added in v0.73.0

func (e *ErrExpectElements) Is(err error) bool

Is interface

type ErrInvisibleShape added in v0.73.0

type ErrInvisibleShape struct {
}

ErrInvisibleShape error.

func (*ErrInvisibleShape) Error added in v0.73.0

func (e *ErrInvisibleShape) Error() string

Error ...

func (*ErrInvisibleShape) Unwrap added in v0.73.0

func (e *ErrInvisibleShape) Unwrap() error

Unwrap ...

type ErrNavigation

type ErrNavigation struct {
	Reason string
}

ErrNavigation error

func (*ErrNavigation) Error added in v0.73.0

func (e *ErrNavigation) Error() string

func (*ErrNavigation) Is added in v0.73.0

func (e *ErrNavigation) Is(err error) bool

Is interface

type ErrNotInteractable added in v0.66.0

type ErrNotInteractable struct{}

ErrNotInteractable error. Check the doc of Element.Interactable for details.

func (*ErrNotInteractable) Error added in v0.73.0

func (e *ErrNotInteractable) Error() string

type ErrObjectNotFound added in v0.74.2

type ErrObjectNotFound struct {
	*proto.RuntimeRemoteObject
}

ErrObjectNotFound error

func (*ErrObjectNotFound) Error added in v0.74.2

func (e *ErrObjectNotFound) Error() string

func (*ErrObjectNotFound) Is added in v0.74.2

func (e *ErrObjectNotFound) Is(err error) bool

Is interface

type ErrPageCloseCanceled added in v0.63.0

type ErrPageCloseCanceled struct {
}

ErrPageCloseCanceled error

func (*ErrPageCloseCanceled) Error added in v0.73.0

func (e *ErrPageCloseCanceled) Error() string

type ErrTry added in v0.73.0

type ErrTry struct {
	Value interface{}
}

ErrTry error

func (*ErrTry) Error added in v0.73.0

func (e *ErrTry) Error() string

func (*ErrTry) Is added in v0.73.0

func (e *ErrTry) Is(err error) bool

Is interface

type EvalOptions added in v0.50.0

type EvalOptions struct {
	// If enabled the eval result will be a plain JSON value.
	// If disabled the eval result will be a reference of a remote js object.
	ByValue bool

	AwaitPromise bool

	// ThisObj represents the "this" object in the JS
	ThisObj *proto.RuntimeRemoteObject

	// JS code to eval
	JS string

	// JSArgs represents the arguments in the JS if the JS is a function definition.
	// If an argument is *proto.RuntimeRemoteObject type, the corresponding remote object will be used.
	// Or it will be passed as a plain JSON value.
	JSArgs []interface{}

	// Whether execution should be treated as initiated by user in the UI.
	UserGesture bool
	// contains filtered or unexported fields
}

EvalOptions for Page.Evaluate

func Eval added in v0.67.0

func Eval(js string, args ...interface{}) *EvalOptions

Eval creates a EvalOptions with ByValue set to true.

func EvalHelper added in v0.80.1

func EvalHelper(fn *js.Function, args ...interface{}) *EvalOptions

EvalHelper creates a special EvalOptions that will cache the fn on the page js context. Useful when you want to extend the helpers of Rod, such as create your own selector helpers.

func (*EvalOptions) ByObject added in v0.50.0

func (e *EvalOptions) ByObject() *EvalOptions

ByObject disables ByValue.

func (*EvalOptions) ByPromise added in v0.74.0

func (e *EvalOptions) ByPromise() *EvalOptions

ByPromise enables AwaitPromise.

func (*EvalOptions) ByUser added in v0.64.0

func (e *EvalOptions) ByUser() *EvalOptions

ByUser enables UserGesture.

func (*EvalOptions) This added in v0.50.0

This set the obj as ThisObj

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. The RequestID will be set by the router, you don't have to set it.

func (*Hijack) LoadResponse

func (h *Hijack) LoadResponse(client *http.Client, 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 is similar to LoadResponse

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() gson.JSON

JSONBody of the request

func (*HijackRequest) Method

func (ctx *HijackRequest) Method() string

Method of the request

func (*HijackRequest) Req added in v0.52.0

func (ctx *HijackRequest) Req() *http.Request

Req returns the underlaying http.Request instance that will be used to send 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) SetContext added in v0.57.1

func (ctx *HijackRequest) SetContext(c context.Context) *HijackRequest

SetContext of the underlaying http.Request instance

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

Body of the payload

func (*HijackResponse) Fail added in v0.48.1

Fail request

func (*HijackResponse) Headers

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

Headers of the payload

func (*HijackResponse) Payload added in v0.52.0

func (ctx *HijackResponse) Payload() *proto.FetchFulfillRequest

Payload to respond the request from the browser.

func (*HijackResponse) SetBody

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

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

func (*HijackResponse) SetHeader

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

SetHeader of the payload via key-value pairs

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

MustAdd is similar to Add

func (*HijackRouter) MustRemove added in v0.50.0

func (r *HijackRouter) MustRemove(pattern string) *HijackRouter

MustRemove is similar to Remove

func (*HijackRouter) MustStop added in v0.50.0

func (r *HijackRouter) MustStop()

MustStop is similar to Stop

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 {
	sync.Mutex
	// 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 holds the key down

func (*Keyboard) InsertText

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

InsertText is like pasting text into the page

func (*Keyboard) MustDown added in v0.50.0

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

MustDown is similar to Down

func (*Keyboard) MustInsertText added in v0.50.0

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

MustInsertText is similar to InsertText

func (*Keyboard) MustPress added in v0.50.0

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

MustPress is similar to Press

func (*Keyboard) MustUp added in v0.50.0

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

MustUp is similar to Up

func (*Keyboard) Press

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

Press a key. It's a combination of Keyboard.Down and Keyboard.Up

func (*Keyboard) Up

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

Up releases the key

type Message added in v0.74.0

type Message struct {
	SessionID proto.TargetSessionID
	Method    string
	// contains filtered or unexported fields
}

Message represents a cdp.Event

func (*Message) Load added in v0.74.0

func (msg *Message) Load(e proto.Event) bool

Load data into e, returns true if e matches the event type.

type Mouse

type Mouse struct {
	sync.Mutex
	// 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 the button. It's the combination of Mouse.Down and Mouse.Up

func (*Mouse) Down

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

Down holds the button down

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 is similar to Click

func (*Mouse) MustDown added in v0.50.0

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

MustDown is similar to Down

func (*Mouse) MustMove added in v0.50.0

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

MustMove is similar to Move

func (*Mouse) MustScroll added in v0.50.0

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

MustScroll is similar to Scroll

func (*Mouse) MustUp added in v0.50.0

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

MustUp is similar to Up

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

Up releases the button

type Page

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

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

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

Example (Pool)

It's a common practice to concurrently use a pool of resources in Go, it's not special for rod.

package main

import (
	"fmt"
	"sync"

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

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

	// We create a pool that will hold at most 3 pages
	pool := rod.NewPagePool(3)

	// Create a page if needed. If you want pages to share cookies with each remove the MustIncognito()
	create := func() *rod.Page { return browser.MustIncognito().MustPage("") }

	yourJob := func() {
		page := pool.Get(create)
		defer pool.Put(page)

		page.MustNavigate("http://example.com").MustWaitLoad()
		fmt.Println(page.MustInfo().Title)
	}

	// Run jobs concurrently
	wg := sync.WaitGroup{}
	for range "...." {
		wg.Add(1)
		go func() {
			defer wg.Done()
			yourJob()
		}()
	}
	wg.Wait()

	// cleanup pool
	pool.Cleanup(func(p *rod.Page) { p.MustClose() })

}
Output:

Example Domain
Example Domain
Example Domain
Example Domain

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) Call added in v0.70.0

func (p *Page) Call(ctx context.Context, sessionID, methodName string, params interface{}) (res []byte, err error)

Call implements the proto.Client

func (*Page) CancelTimeout

func (p *Page) CancelTimeout() *Page

CancelTimeout cancels the current timeout context and returns a clone with the parent context

func (*Page) Close

func (p *Page) Close() error

Close tries to close page, running its beforeunload hooks, if any.

func (*Page) Context

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

Context returns a clone with the specified ctx for chained sub-operations

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.Request) (restore func())

DisableDomain and returns a restore function to restore previous state

func (*Page) EachEvent

func (p *Page) EachEvent(callbacks ...interface{}) (wait func())

EachEvent is similar to Browser.EachEvent, but only catches events for current page.

func (*Page) Element

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

Element retries until an element in the page that matches the CSS selector, then returns the matched element.

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. By default, it will retry until the js function doesn't return null. To customize the retry logic, check the examples of Page.Sleeper.

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(obj *proto.RuntimeRemoteObject) *Element

ElementFromObject creates an Element from the remote object id.

func (*Page) ElementFromPoint added in v0.48.0

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

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

func (*Page) ElementR added in v0.57.0

func (p *Page) ElementR(selector, jsRegex string) (*Element, error)

ElementR retries until an element in the page that matches the css selector and it's text matches the jsRegex, then returns the matched element.

func (*Page) ElementX

func (p *Page) ElementX(xPath string) (*Element, error)

ElementX retries until an element in the page that matches one of the XPath selectors, then returns the matched element.

func (*Page) Elements

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

Elements returns all elements that match the css selector

func (*Page) ElementsByJS

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

ElementsByJS returns the elements from the return value of the js

func (*Page) ElementsX

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

ElementsX returns all elements that match the XPath selector

func (*Page) Emulate added in v0.42.1

func (p *Page) Emulate(device devices.Device) error

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

func (*Page) EnableDomain

func (p *Page) EnableDomain(method proto.Request) (restore func())

EnableDomain and returns a restore function to restore previous state

func (*Page) Eval

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

Eval is just a shortcut for Page.Evaluate with AwaitPromise set true.

func (*Page) EvalOnNewDocument added in v0.44.0

func (p *Page) EvalOnNewDocument(js string) (remove func() error, err error)

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

func (*Page) Evaluate added in v0.67.0

func (p *Page) Evaluate(opts *EvalOptions) (res *proto.RuntimeRemoteObject, err error)

Evaluate js on the page.

func (*Page) Event added in v0.70.2

func (p *Page) Event() <-chan *Message

Event of the page

func (*Page) Expose added in v0.49.1

func (p *Page) Expose(name string, fn func(gson.JSON) (interface{}, error)) (stop func() error, err error)

Expose fn to the page's window object with the name. The exposure survives reloads. Call stop to unbind the fn.

func (*Page) ExposeHelpers added in v0.85.1

func (p *Page) ExposeHelpers(list ...*js.Function)

ExposeHelpers helper functions to page's js context so that we can use the Devtools' console to debug them.

func (*Page) GetContext

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

GetContext of current instance

func (*Page) GetResource added in v0.76.6

func (p *Page) GetResource(url string) ([]byte, error)

GetResource content by the url. Such as image, css, html, etc. Use the proto.PageGetResourceTree to list all the resources.

func (*Page) GetSessionID added in v0.72.0

func (p *Page) GetSessionID() proto.TargetSessionID

GetSessionID interface

func (*Page) GetWindow

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

GetWindow position and size info

func (*Page) HandleDialog

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

HandleDialog accepts or dismisses next JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload). Because modal dialog will block js, usually you have to run the wait function in another goroutine before the action that will trigger the dialog. For example:

wait := page.MustHandleDialog(true, "")
go wait()
page.MustElement("button").MustClick()

func (*Page) Has

func (p *Page) Has(selector string) (bool, *Element, error)

Has an element that matches the css selector

func (*Page) HasR added in v0.61.0

func (p *Page) HasR(selector, jsRegex string) (bool, *Element, error)

HasR an element that matches the css selector and its display text matches the jsRegex.

func (*Page) HasX

func (p *Page) HasX(selector string) (bool, *Element, error)

HasX an element that matches the XPath selector

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.Request) (has bool)

LoadState into the method.

func (*Page) MustAddScriptTag added in v0.50.0

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

MustAddScriptTag is similar to AddScriptTag

func (*Page) MustAddStyleTag added in v0.50.0

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

MustAddStyleTag is similar to AddStyleTag

func (*Page) MustClose added in v0.50.0

func (p *Page) MustClose()

MustClose is similar to Close

func (*Page) MustCookies added in v0.50.0

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

MustCookies is similar to Cookies

func (*Page) MustElement added in v0.50.0

func (p *Page) MustElement(selector string) *Element

MustElement is similar to Element

func (*Page) MustElementByJS added in v0.50.0

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

MustElementByJS is similar to ElementByJS

func (*Page) MustElementFromNode added in v0.50.0

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

MustElementFromNode is similar to ElementFromNode

func (*Page) MustElementFromPoint added in v0.50.0

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

MustElementFromPoint is similar to ElementFromPoint

func (*Page) MustElementR added in v0.57.0

func (p *Page) MustElementR(selector, jsRegex string) *Element

MustElementR is similar to ElementR

func (*Page) MustElementX added in v0.50.0

func (p *Page) MustElementX(xPath string) *Element

MustElementX is similar to ElementX

func (*Page) MustElements added in v0.50.0

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

MustElements is similar to Elements

func (*Page) MustElementsByJS added in v0.50.0

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

MustElementsByJS is similar to ElementsByJS

func (*Page) MustElementsX added in v0.50.0

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

MustElementsX is similar to ElementsX

func (*Page) MustEmulate added in v0.50.0

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

MustEmulate is similar to Emulate

func (*Page) MustEval added in v0.50.0

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

MustEval is similar to Eval

func (*Page) MustEvalOnNewDocument added in v0.50.0

func (p *Page) MustEvalOnNewDocument(js string)

MustEvalOnNewDocument is similar to EvalOnNewDocument

func (*Page) MustEvaluate added in v0.67.0

func (p *Page) MustEvaluate(opts *EvalOptions) *proto.RuntimeRemoteObject

MustEvaluate is similar to Evaluate

func (*Page) MustExpose added in v0.50.0

func (p *Page) MustExpose(name string, fn func(gson.JSON) (interface{}, error)) (stop func())

MustExpose is similar to Expose

func (*Page) MustGetWindow added in v0.50.0

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

MustGetWindow is similar to GetWindow

func (*Page) MustHandleDialog added in v0.50.0

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

MustHandleDialog is similar to HandleDialog

func (*Page) MustHas added in v0.50.0

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

MustHas is similar to Has

func (*Page) MustHasR added in v0.61.0

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

MustHasR is similar to HasR

func (*Page) MustHasX added in v0.50.0

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

MustHasX is similar to HasX

func (*Page) MustInfo added in v0.50.0

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

MustInfo is similar to Info

func (*Page) MustNavigate added in v0.50.0

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

MustNavigate is similar to Navigate

func (*Page) MustNavigateBack added in v0.61.4

func (p *Page) MustNavigateBack() *Page

MustNavigateBack is similar to NavigateBack

func (*Page) MustNavigateForward added in v0.61.4

func (p *Page) MustNavigateForward() *Page

MustNavigateForward is similar to NavigateForward

func (*Page) MustObjectToJSON added in v0.50.0

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

MustObjectToJSON is similar to ObjectToJSON

func (*Page) MustObjectsToJSON added in v0.50.0

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

MustObjectsToJSON is similar to ObjectsToJSON

func (*Page) MustPDF added in v0.50.0

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

MustPDF is similar to PDF. If the toFile is "", it will save output to "tmp/pdf" folder, time as the file name.

func (*Page) MustRelease added in v0.50.0

func (p *Page) MustRelease(obj *proto.RuntimeRemoteObject) *Page

MustRelease is similar to Release

func (*Page) MustReload added in v0.61.4

func (p *Page) MustReload() *Page

MustReload is similar to Reload

func (*Page) MustScreenshot added in v0.50.0

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

MustScreenshot is similar to Screenshot. 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 is similar to ScreenshotFullPage. If the toFile is "", it will save output to "tmp/screenshots" folder, time as the file name.

func (*Page) MustSearch added in v0.50.0

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

MustSearch is similar to Search

func (*Page) MustSetCookies added in v0.50.0

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

MustSetCookies is similar to SetCookies

func (*Page) MustSetExtraHeaders added in v0.50.0

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

MustSetExtraHeaders is similar to SetExtraHeaders

func (*Page) MustSetUserAgent added in v0.50.0

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

MustSetUserAgent is similar to SetUserAgent

func (*Page) MustSetViewport added in v0.64.0

func (p *Page) MustSetViewport(width, height int, deviceScaleFactor float64, mobile bool) *Page

MustSetViewport is similar to SetViewport

func (*Page) MustSetWindow added in v0.64.0

func (p *Page) MustSetWindow(left, top, width, height int) *Page

MustSetWindow is similar to SetWindow

func (*Page) MustStopLoading added in v0.50.0

func (p *Page) MustStopLoading() *Page

MustStopLoading is similar to StopLoading

func (*Page) MustWait added in v0.50.0

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

MustWait is similar to Wait

func (*Page) MustWaitIdle added in v0.50.0

func (p *Page) MustWaitIdle() *Page

MustWaitIdle is similar to WaitIdle

func (*Page) MustWaitLoad added in v0.50.0

func (p *Page) MustWaitLoad() *Page

MustWaitLoad is similar to WaitLoad

func (*Page) MustWaitNavigation added in v0.63.2

func (p *Page) MustWaitNavigation() func()

MustWaitNavigation is similar to WaitNavigation

func (*Page) MustWaitOpen added in v0.50.0

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

MustWaitOpen is similar to WaitOpen

func (*Page) MustWaitPauseOpen added in v0.50.0

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

MustWaitPauseOpen is similar to WaitPauseOpen

func (*Page) MustWaitRequestIdle added in v0.50.0

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

MustWaitRequestIdle is similar to WaitRequestIdle

func (*Page) MustWindowFullscreen added in v0.50.0

func (p *Page) MustWindowFullscreen() *Page

MustWindowFullscreen is similar to WindowFullscreen

func (*Page) MustWindowMaximize added in v0.50.0

func (p *Page) MustWindowMaximize() *Page

MustWindowMaximize is similar to WindowMaximize

func (*Page) MustWindowMinimize added in v0.50.0

func (p *Page) MustWindowMinimize() *Page

MustWindowMinimize is similar to WindowMinimize

func (*Page) MustWindowNormal added in v0.50.0

func (p *Page) MustWindowNormal() *Page

MustWindowNormal is similar to WindowNormal

func (*Page) Navigate

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

Navigate to the url. If the url is empty, "about:blank" will be used. It will return immediately after the server responds the http header.

func (*Page) NavigateBack added in v0.61.4

func (p *Page) NavigateBack() error

NavigateBack history.

func (*Page) NavigateForward added in v0.61.4

func (p *Page) NavigateForward() error

NavigateForward history.

func (*Page) ObjectToJSON

func (p *Page) ObjectToJSON(obj *proto.RuntimeRemoteObject) (gson.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) (*StreamReader, error)

PDF prints page as PDF

func (*Page) Race added in v0.57.0

func (p *Page) Race() *RaceContext

Race creates a context to race selectors

func (*Page) Release

func (p *Page) Release(obj *proto.RuntimeRemoteObject) error

Release the remote object. Usually, you don't need to call it. When a page is closed or reloaded, all remote objects will be released automatically. It's useful if the page never closes or reloads.

func (*Page) Reload added in v0.61.4

func (p *Page) Reload() error

Reload page.

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.

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 (browser brand, accept-language, etc) of the page. If req is nil, a default user agent will be used, a typical mac chrome.

func (*Page) SetViewport added in v0.62.0

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

SetViewport overrides the values of device screen dimensions

func (*Page) SetWindow added in v0.62.0

func (p *Page) SetWindow(bounds *proto.BrowserBounds) error

SetWindow location and size

func (*Page) Sleeper

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

Sleeper returns a clone with 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 returns a clone with the specified timeout context.Context chained sub-operations

func (*Page) Wait

func (p *Page) Wait(this *proto.RuntimeRemoteObject, js string, params []interface{}) error

Wait js function until it returns true

func (*Page) WaitEvent

func (p *Page) WaitEvent(e proto.Event) (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 waits until the next window.requestIdleCallback is called.

func (*Page) WaitLoad

func (p *Page) WaitLoad() error

WaitLoad waits for the `window.onload` event, it returns immediately if the event is already fired.

func (*Page) WaitNavigation added in v0.63.2

func (p *Page) WaitNavigation(name proto.PageLifecycleEventName) func()

WaitNavigation wait for a page lifecycle event when navigating. Usually you will wait for proto.PageLifecycleEventNameNetworkAlmostIdle

func (*Page) WaitOpen

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

WaitOpen waits for the next new page opened by the current one

func (*Page) WaitPauseOpen added in v0.49.3

func (p *Page) WaitPauseOpen() (func() (*Page, func() error, error), 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) WaitRepaint added in v0.84.1

func (p *Page) WaitRepaint() error

WaitRepaint waits until the next repaint. Doc: https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

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. Be careful, d is not the max wait timeout, it's the least idle time. If you want to set a timeout you can use the "Page.Timeout" function. Use the includes and excludes regexp list to filter the requests by their url.

func (*Page) WithCancel added in v0.69.0

func (p *Page) WithCancel() (*Page, func())

WithCancel returns a clone with a context cancel function

type PagePool added in v0.73.2

type PagePool chan *Page

PagePool to thread-safely limit the number of pages at the same time. It's a common practice to use a channel to limit concurrency, it's not special for rod. This helper is more like an example to use Go Channel.

func NewPagePool added in v0.73.2

func NewPagePool(limit int) PagePool

NewPagePool instance

func (PagePool) Cleanup added in v0.73.2

func (pp PagePool) Cleanup(iteratee func(*Page))

Cleanup helper

func (PagePool) Get added in v0.73.2

func (pp PagePool) Get(create func() *Page) *Page

Get a page from the pool. Use the PagePool.Put to make it reusable later.

func (PagePool) Put added in v0.73.2

func (pp PagePool) Put(p *Page)

Put a page back to the pool

type Pages

type Pages []*Page

Pages provides some helpers to deal with page list

func (Pages) Empty added in v0.53.0

func (ps Pages) Empty() bool

Empty returns true if the list is empty

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(jsRegex string) (*Page, error)

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

func (Pages) First added in v0.53.0

func (ps Pages) First() *Page

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

func (Pages) Last added in v0.53.0

func (ps Pages) Last() *Page

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

func (Pages) MustFind added in v0.50.3

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

MustFind is similar to Find

func (Pages) MustFindByURL added in v0.50.0

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

MustFindByURL is similar to FindByURL

type RaceContext added in v0.57.0

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

RaceContext stores the branches to race

func (*RaceContext) Do added in v0.57.0

func (rc *RaceContext) Do() (*Element, error)

Do the race

func (*RaceContext) Element added in v0.57.0

func (rc *RaceContext) Element(selector string) *RaceContext

Element the doc is similar to MustElement

func (*RaceContext) ElementByJS added in v0.57.0

func (rc *RaceContext) ElementByJS(opts *EvalOptions) *RaceContext

ElementByJS the doc is similar to MustElementByJS

func (*RaceContext) ElementR added in v0.57.0

func (rc *RaceContext) ElementR(selector, regex string) *RaceContext

ElementR the doc is similar to ElementR

func (*RaceContext) ElementX added in v0.57.0

func (rc *RaceContext) ElementX(selector string) *RaceContext

ElementX the doc is similar to ElementX

func (*RaceContext) Handle added in v0.81.0

func (rc *RaceContext) Handle(callback func(*Element) error) *RaceContext

Handle adds a callback function to the most recent chained selector. The callback function is run, if the corresponding selector is present first, in the Race condition.

func (*RaceContext) MustDo added in v0.57.0

func (rc *RaceContext) MustDo() *Element

MustDo is similar to Do

func (*RaceContext) MustElementByJS added in v0.57.0

func (rc *RaceContext) MustElementByJS(js string, params []interface{}) *RaceContext

MustElementByJS is similar to ElementByJS

func (*RaceContext) MustHandle added in v0.81.0

func (rc *RaceContext) MustHandle(callback func(*Element)) *RaceContext

MustHandle is similar to Handle

type SelectorType added in v0.68.0

type SelectorType string

SelectorType enum

const (
	// SelectorTypeRegex type
	SelectorTypeRegex SelectorType = "regex"
	// SelectorTypeCSSSector type
	SelectorTypeCSSSector SelectorType = "css-selector"
	// SelectorTypeText type
	SelectorTypeText SelectorType = "text"
)

type StreamReader added in v0.63.0

type StreamReader struct {
	Offset int
	// contains filtered or unexported fields
}

StreamReader for browser data stream

func NewStreamReader added in v0.63.0

func NewStreamReader(c proto.Client, h proto.IOStreamHandle) *StreamReader

NewStreamReader instance

func (*StreamReader) Read added in v0.63.0

func (sr *StreamReader) Read(p []byte) (n int, err error)

type Touch added in v0.61.1

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

Touch presents a touch device, such as a hand with fingers, each finger is a proto.InputTouchPoint. Touch events is stateless, we use the struct here only as a namespace to make the API style unified.

func (*Touch) Cancel added in v0.61.1

func (t *Touch) Cancel() error

Cancel touch action

func (*Touch) End added in v0.61.1

func (t *Touch) End() error

End touch action

func (*Touch) Move added in v0.61.1

func (t *Touch) Move(points ...*proto.InputTouchPoint) error

Move touch points. Use the InputTouchPoint.ID (Touch.identifier) to track points. Doc: https://developer.mozilla.org/en-US/docs/Web/API/Touch_events

func (*Touch) MustCancel added in v0.61.1

func (t *Touch) MustCancel() *Touch

MustCancel is similar to Cancel

func (*Touch) MustEnd added in v0.61.1

func (t *Touch) MustEnd() *Touch

MustEnd is similar to End

func (*Touch) MustMove added in v0.61.1

func (t *Touch) MustMove(points ...*proto.InputTouchPoint) *Touch

MustMove is similar to Move

func (*Touch) MustStart added in v0.61.1

func (t *Touch) MustStart(points ...*proto.InputTouchPoint) *Touch

MustStart is similar to Start

func (*Touch) MustTap added in v0.61.1

func (t *Touch) MustTap(x, y float64) *Touch

MustTap is similar to Tap

func (*Touch) Start added in v0.61.1

func (t *Touch) Start(points ...*proto.InputTouchPoint) error

Start a touch action

func (*Touch) Tap added in v0.61.1

func (t *Touch) Tap(x, y float64) error

Tap dispatches a touchstart and touchend event.

type TraceMsg added in v0.59.0

type TraceMsg struct {
	// Type of the message
	Type TraceType

	// Details is a json object
	Details interface{}
}

TraceMsg for logger

func (*TraceMsg) String added in v0.59.0

func (msg *TraceMsg) String() string

type TraceType added in v0.59.0

type TraceType string

TraceType for logger

const (
	// TraceTypeWaitRequestsIdle type
	TraceTypeWaitRequestsIdle TraceType = "wait requests idle"

	// TraceTypeWaitRequests type
	TraceTypeWaitRequests TraceType = "wait requests"

	// TraceTypeEval type
	TraceTypeEval TraceType = "eval"

	// TraceTypeAction type
	TraceTypeAction TraceType = "act"

	// TraceTypeInput type
	TraceTypeInput TraceType = "input"
)

Jump to

Keyboard shortcuts

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