witness

package module
v0.0.0-...-bc17065 Latest Latest
Warning

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

Go to latest
Published: Dec 28, 2020 License: Apache-2.0 Imports: 16 Imported by: 0

README

witness (PoC)

witness is golang client driving Chrome browser using the Chrome DevTools Protocol. Witness has Selenium like interface. It is experimental project, backward compatibility is not guaranteed!

Installation

go get -u github.com/GrayYoga/witness

How to use

Here is an example of using:

package main

import (
	"time"

	"github.com/GrayYoga/witness"
	"github.com/GrayYoga/witness/pkg/chrome"
)

func main() {
	chrome, _ := chrome.New("--headless")
	defer chrome.Close()
	session, err := chrome.CDP.DefaultSession()
	if err != nil {
		panic(err)
	}

	chrome.CDP.Logging.Level = witness.LevelProtocolMessage
	// Implicitly affected only C() function
	chrome.CDP.Timeouts.Implicitly = time.Second * 5

	session.Page.Navigate("https://my.ecwid.com")

	session.Page.C("[name='email']", true).Type("test@example.com")
	session.Page.C("[name='password']", true).Type("xxxxxx")
	session.Page.C("button.btn-primary", true).Click()
}

Implemented methods:

type Session struct {
	Network   Network
	Input     Input
	Runtime   Runtime
	Page      Page
	Message   Message
	Tabs      Tab
	Emulation Emulation
}

type Network interface {
	SetCookies(...*devtool.Cookie) error
	ClearBrowserCookies() error
	GetCookies(...string) ([]*devtool.Cookie, error)
	Intercept([]*devtool.RequestPattern, func(*devtool.RequestPaused, Interceptor)) func()
	SetOffline(bool) error
	SetThrottling(int, int, int) error
	SetBlockedURLs([]string) error
}

type Tab interface {
	NewTab(string) (string, error)
	SwitchToTab(string) (*Session, error)
	GetTabs() ([]string, error)
	OnNewTabOpen() chan string
}

type Input interface {
	MouseMove(float64, float64) error
	SendKeys(...rune) error
	InsertText(string) error
}

type Runtime interface {
	Evaluate(string, bool, bool) (interface{}, error)
}

type Message interface {
	BlockingSend(method string, send interface{}) ([]byte, error)
	Listen(...string) (chan *Event, func())
}

type Emulation interface {
	SetCPUThrottlingRate(rate int) error
	SetUserAgent(userAgent string) error
	Emulate(*mobile.Device) error
}

type Page interface {
	Findable

	Navigate(string) error
	Reload() error
	GetNavigationEntry() (*devtool.NavigationEntry, error)
	Close() error
	IsClosed() bool
	MainFrame() error
	SwitchToFrame(string) error
	Back() error
	Forward() error

	ID() string

	AddScriptToEvaluateOnNewDocument(string) (string, error)
	RemoveScriptToEvaluateOnNewDocument(string) error
	SetDownloadBehavior(devtool.DownloadBehavior, string) error
	CaptureScreenshot(string, int8, bool, func() error) ([]byte, error)
	Activate() error

	Ticker(call TickerFunc) (interface{}, error)
}

type Findable interface {
	C(string, bool) Element // must get element by css-selector with implicity wait or panic
	Query(string) (Element, error)
	QueryAll(string) []Element
}

// Element element interface
type Element interface {
	Findable

	Click() error
	Hover() error
	Type(string, ...rune) error
	Upload(...string) error
	Clear() error
	Select(...string) error
	Checkbox(bool) error
	SetAttr(string, string) error
	Call(string, ...interface{}) (interface{}, error)
	Focus() error

	IsVisible() (bool, error)
	GetText() (string, error)
	GetAttr(attr string) (string, error)
	GetRectangle() (*devtool.Rect, error)
	GetComputedStyle(string) (string, error)
	GetSelected(bool) ([]string, error)
	IsChecked() (bool, error)
	GetEventListeners() ([]string, error)
	GetFrameID() (string, error)

	ObserveMutation(attributes, childList, subtree bool) (chan string, chan error)
	Release() error
}

See https://github.com/GrayYoga/witness/tree/master/examples for more examples

Documentation

Index

Constants

View Source
const (
	ProtocolParseError     = -32700
	ProtocolInvalidRequest = -32600
	ProtocolMethodNotFound = -32601
	ProtocolInvalidParams  = -32602
	ProtocolInternalError  = -32603
	ProtocolServerError    = -32000
)

v8 inspector devtool errors

View Source
const (
	LevelFatal           level = 0x01
	LevelProtocolErrors  level = 0x02 | LevelFatal
	LevelProtocolMessage level = 0x04 | LevelProtocolErrors
	LevelProtocolEvents  level = 0x08 | LevelProtocolErrors
	LevelProtocolVerbose level = LevelProtocolErrors | LevelProtocolMessage | LevelProtocolEvents
	LevelInfo            level = 0x10 | LevelProtocolErrors
)

log levels for client logging

Variables

View Source
var (
	ErrStaleElementReference  = errors.New("referenced element is no longer attached to the DOM")
	ErrNoSuchContext          = errors.New("cannot find context with specified id")
	ErrNoSuchElement          = errors.New("no such element")
	ErrNoSuchFrame            = errors.New("no such frame")
	ErrFrameDetached          = errors.New("frame you working on was detached")
	ErrNoPageTarget           = errors.New("no one page target")
	ErrDevtoolTimeout         = errors.New("devtool response reached timeout")
	ErrNavigateTimeout        = errors.New("navigation reached timeout")
	ErrSessionClosed          = errors.New("session closed")
	ErrElementInvisible       = errors.New("element invisible")
	ErrElementIsOutOfViewport = errors.New("element is out of viewport")
	ErrElementNotFocusable    = errors.New("element is not focusable")
	ErrElementMissClick       = errors.New("miss click - element is overlapping or changing its coordinates")
	ErrInvalidString          = errors.New("object type is not string")
	ErrInvalidElementFrame    = errors.New("specified element is not a IFRAME")
	ErrInvalidElementSelect   = errors.New("specified element is not a SELECT")
	ErrInvalidElementOption   = errors.New("specified element has no options")
)

cdp errors

Functions

This section is empty.

Types

type CDP

type CDP struct {
	Stats    *stats
	Timeouts *timeouts
	Logging  *wlog
	// contains filtered or unexported fields
}

CDP chrome devtool protocol client

func New

func New(cntx context.Context, webSocketURL string) (*CDP, error)

New create new client to interact with browser by CDP

func (*CDP) Close

func (c *CDP) Close()

Close close browser and websocket connection

func (*CDP) DefaultSession

func (c *CDP) DefaultSession() (*Session, error)

DefaultSession attach to default welcome page that opened after chrome start

type CDPSession

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

CDPSession CDP session

func (*CDPSession) Activate

func (session *CDPSession) Activate() error

Activate activate current Target

func (*CDPSession) AddScriptToEvaluateOnNewDocument

func (session *CDPSession) AddScriptToEvaluateOnNewDocument(source string) (string, error)

AddScriptToEvaluateOnNewDocument https://chromedevtools.github.io/devtools-protocol/tot/Page#method-addScriptToEvaluateOnNewDocument

func (*CDPSession) Back

func (session *CDPSession) Back() error

Back navigate back

func (*CDPSession) BlockingSend

func (session *CDPSession) BlockingSend(method string, send interface{}) ([]byte, error)

BlockingSend send message over CDP protocol

func (*CDPSession) C

func (session *CDPSession) C(selector string, visible bool) Element

C searching selector (visible) with implicity wait timeout

func (*CDPSession) CaptureScreenshot

func (session *CDPSession) CaptureScreenshot(format string, quality int8, fullPage bool, cb func() error) ([]byte, error)

CaptureScreenshot get screen of current page

func (*CDPSession) ClearBrowserCookies

func (session *CDPSession) ClearBrowserCookies() error

ClearBrowserCookies ...

func (*CDPSession) Close

func (session *CDPSession) Close() error

Close close this sessions

func (*CDPSession) Continue

func (session *CDPSession) Continue(requestID string, url *string, method *string, postData *string, headers []*devtool.HeaderEntry) error

Continue https://chromedevtools.github.io/devtools-protocol/tot/Fetch#method-continueRequest

func (*CDPSession) Emulate

func (session *CDPSession) Emulate(device *mobile.Device) error

Emulate emulate predefined device

func (*CDPSession) Evaluate

func (session *CDPSession) Evaluate(code string, async bool, returnByValue bool) (interface{}, error)

Evaluate evaluate javascript code at context of web page

func (*CDPSession) Forward

func (session *CDPSession) Forward() error

Forward navigate forward

func (*CDPSession) Fulfill

func (session *CDPSession) Fulfill(
	requestID string,
	responseCode int,
	responseHeaders []*devtool.HeaderEntry,
	body *string,
	responsePhrase *string) error

Fulfill https://chromedevtools.github.io/devtools-protocol/tot/Fetch#method-fulfillRequest

func (*CDPSession) GetCookies

func (session *CDPSession) GetCookies(urls ...string) ([]*devtool.Cookie, error)

GetCookies returns all browser cookies for the current URL

func (*CDPSession) GetLayoutMetrics

func (session *CDPSession) GetLayoutMetrics() (*devtool.LayoutMetrics, error)

GetLayoutMetrics ...

func (*CDPSession) GetNavigationEntry

func (session *CDPSession) GetNavigationEntry() (*devtool.NavigationEntry, error)

GetNavigationEntry get current tab info

func (*CDPSession) GetRequestPostData

func (session *CDPSession) GetRequestPostData(requestID string) (string, error)

GetRequestPostData https://chromedevtools.github.io/devtools-protocol/tot/Network/#method-getRequestPostData

func (*CDPSession) GetResponseBody

func (session *CDPSession) GetResponseBody(requestID string) (string, error)

GetResponseBody https://chromedevtools.github.io/devtools-protocol/tot/Network/#method-getResponseBody

func (*CDPSession) GetTabs

func (session *CDPSession) GetTabs() ([]string, error)

GetTabs list of opened tabs in browser (targetID)

func (*CDPSession) ID

func (session *CDPSession) ID() string

ID session's ID

func (*CDPSession) InsertText

func (session *CDPSession) InsertText(text string) error

InsertText method emulates inserting text that doesn't come from a key press, for example an emoji keyboard or an IME

func (*CDPSession) Intercept

func (session *CDPSession) Intercept(patterns []*devtool.RequestPattern, fn func(*devtool.RequestPaused, Interceptor)) func()

Intercept ...

func (*CDPSession) IsClosed

func (session *CDPSession) IsClosed() bool

IsClosed check is session (tab) closed

func (*CDPSession) Listen

func (session *CDPSession) Listen(methods ...string) (chan *Event, func())

Listen subscribe to listen cdp events with methods name return channel with incoming events and func to unsubscribe channel will be closed after unsubscribe func call

func (*CDPSession) MainFrame

func (session *CDPSession) MainFrame() error

MainFrame switch context to main frame of page

func (*CDPSession) MouseMove

func (session *CDPSession) MouseMove(x, y float64) error

MouseMove ...

func (*CDPSession) Navigate

func (session *CDPSession) Navigate(urlStr string) error

Navigate navigate to url

func (*CDPSession) NewTab

func (session *CDPSession) NewTab(url string) (string, error)

NewTab ...

func (*CDPSession) OnNewTabOpen

func (session *CDPSession) OnNewTabOpen() chan string

OnNewTabOpen subscribe to Target.targetCreated event and return channel with targetID

func (*CDPSession) Query

func (session *CDPSession) Query(selector string) (Element, error)

Query query element on page by css selector

func (*CDPSession) QueryAll

func (session *CDPSession) QueryAll(selector string) []Element

QueryAll queryAll elements on page by css selector

func (*CDPSession) Reload

func (session *CDPSession) Reload() error

Reload refresh current page ignores cache

func (*CDPSession) RemoveScriptToEvaluateOnNewDocument

func (session *CDPSession) RemoveScriptToEvaluateOnNewDocument(identifier string) error

RemoveScriptToEvaluateOnNewDocument https://chromedevtools.github.io/devtools-protocol/tot/Page#method-removeScriptToEvaluateOnNewDocument

func (*CDPSession) SendKeys

func (session *CDPSession) SendKeys(key ...rune) error

SendKeys send keyboard keys to focused element

func (*CDPSession) SetBlockedURLs

func (session *CDPSession) SetBlockedURLs(urls []string) error

SetBlockedURLs blocking some resources

func (*CDPSession) SetCPUThrottlingRate

func (session *CDPSession) SetCPUThrottlingRate(rate int) error

SetCPUThrottlingRate https://chromedevtools.github.io/devtools-protocol/tot/Emulation#method-setCPUThrottlingRate

func (*CDPSession) SetCookies

func (session *CDPSession) SetCookies(cookies ...*devtool.Cookie) error

SetCookies ...

func (*CDPSession) SetDownloadBehavior

func (session *CDPSession) SetDownloadBehavior(behavior devtool.DownloadBehavior, downloadPath string) error

SetDownloadBehavior https://chromedevtools.github.io/devtools-protocol/tot/Page#method-setDownloadBehavior

func (*CDPSession) SetExtraHTTPHeaders

func (session *CDPSession) SetExtraHTTPHeaders(headers map[string]string) error

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

func (*CDPSession) SetOffline

func (session *CDPSession) SetOffline(e bool) error

SetOffline set offline/online mode SetOffline(false) - reset all network conditions to default

func (*CDPSession) SetThrottling

func (session *CDPSession) SetThrottling(latencyMs, downloadThroughputBps, uploadThroughputBps int) error

SetThrottling set latency in milliseconds, download & upload throttling in bytes per second

func (*CDPSession) SetUserAgent

func (session *CDPSession) SetUserAgent(userAgent string) error

SetUserAgent set user agent

func (*CDPSession) SwitchToFrame

func (session *CDPSession) SwitchToFrame(frameID string) error

SwitchToFrame switch context to frame

func (*CDPSession) SwitchToTab

func (session *CDPSession) SwitchToTab(id string) (*Session, error)

SwitchToTab switch to another tab (new independent session will be created)

func (*CDPSession) TerminateExecution

func (session *CDPSession) TerminateExecution() error

TerminateExecution Terminate current or next JavaScript execution. Will cancel the termination when the outer-most script execution ends

func (*CDPSession) Ticker

func (session *CDPSession) Ticker(call TickerFunc) (interface{}, error)

Ticker ...

type Element

type Element interface {
	Findable

	Click() error
	Hover() error
	Type(string, ...rune) error
	Upload(...string) error
	Clear() error
	Select(...string) error
	Checkbox(bool) error
	SetAttr(string, string) error
	Call(string, ...interface{}) (interface{}, error)
	Focus() error

	IsVisible() (bool, error)
	GetText() (string, error)
	GetAttr(attr string) (string, error)
	GetRectangle() (*devtool.Rect, error)
	GetComputedStyle(string) (string, error)
	GetSelected(bool) ([]string, error)
	IsChecked() (bool, error)
	GetEventListeners() ([]string, error)
	GetFrameID() (string, error)

	ObserveMutation(attributes, childList, subtree bool) (chan string, chan error)
	Release() error
}

Element element interface

type Emulation

type Emulation interface {
	SetCPUThrottlingRate(rate int) error
	SetUserAgent(userAgent string) error
	Emulate(*mobile.Device) error
}

Emulation Emulation domain

type Event

type Event struct {
	Method string          `json:"method"`
	Params json.RawMessage `json:"params"`
}

Event ...

type Findable

type Findable interface {
	C(string, bool) Element // Select by CSS selector
	Query(string) (Element, error)
	QueryAll(string) []Element
}

Findable interface to find element

type Input

type Input interface {
	MouseMove(float64, float64) error
	SendKeys(...rune) error
	InsertText(string) error
}

Input input domain

type Interceptor

type Interceptor interface {
	Fail(requestID string, reason devtool.ErrorReason) error
	Fulfill(requestID string, responseCode int, responseHeaders []*devtool.HeaderEntry, body *string, responsePhrase *string) error
	Continue(requestID string, url *string, method *string, postData *string, headers []*devtool.HeaderEntry) error
}

Interceptor continue paused request

type Map

type Map map[string]interface{}

Map ...

func (Map) Bool

func (m Map) Bool(key string) bool

Bool ...

func (Map) Float

func (m Map) Float(key string) float64

Float ...

func (Map) Int

func (m Map) Int(key string) int64

Int ...

func (Map) String

func (m Map) String(key string) string

type Message

type Message interface {
	BlockingSend(method string, send interface{}) ([]byte, error)
	Listen(...string) (chan *Event, func())
}

Message internal CDP methods

type Network

type Network interface {
	SetCookies(...*devtool.Cookie) error
	ClearBrowserCookies() error
	GetCookies(...string) ([]*devtool.Cookie, error)
	Intercept([]*devtool.RequestPattern, func(*devtool.RequestPaused, Interceptor)) func()
	SetOffline(e bool) error
	SetThrottling(int, int, int) error
	SetBlockedURLs([]string) error
	GetRequestPostData(string) (string, error)
	GetResponseBody(string) (string, error)
}

Network network domain

type Page

type Page interface {
	Findable

	Navigate(string) error
	Reload() error
	GetNavigationEntry() (*devtool.NavigationEntry, error)
	Close() error
	IsClosed() bool
	MainFrame() error
	SwitchToFrame(string) error
	Back() error
	Forward() error

	ID() string

	AddScriptToEvaluateOnNewDocument(string) (string, error)
	RemoveScriptToEvaluateOnNewDocument(string) error
	SetDownloadBehavior(devtool.DownloadBehavior, string) error
	CaptureScreenshot(string, int8, bool, func() error) ([]byte, error)
	Activate() error

	Ticker(call TickerFunc) (interface{}, error)

	GetLayoutMetrics() (*devtool.LayoutMetrics, error)
}

Page page domain

type Runtime

type Runtime interface {
	Evaluate(string, bool, bool) (interface{}, error)
	TerminateExecution() error
}

Runtime runtime domain

type Session

type Session struct {
	Network   Network
	Input     Input
	Runtime   Runtime
	Page      Page
	Message   Message
	Tabs      Tab
	Emulation Emulation
}

Session entry point session

type Tab

type Tab interface {
	NewTab(string) (string, error)
	SwitchToTab(string) (*Session, error)
	GetTabs() ([]string, error)
	OnNewTabOpen() chan string
}

Tab pages manage

type TickerFunc

type TickerFunc func() (interface{}, error)

TickerFunc ...

Directories

Path Synopsis
examples
internal
pkg
har

Jump to

Keyboard shortcuts

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