diff --git a/example_test.go b/example_test.go index e041a1c..cfdd54b 100644 --- a/example_test.go +++ b/example_test.go @@ -1,12 +1,17 @@ package selenium_test import ( + "encoding/json" "fmt" + "github.com/chromedp/cdproto" + "github.com/chromedp/cdproto/network" + "github.com/mitchellh/mapstructure" + "github.com/tebeka/selenium" + "github.com/tebeka/selenium/chrome" + "github.com/tebeka/selenium/log" "os" "strings" "time" - - "github.com/tebeka/selenium" ) // This example shows how to navigate to a http://play.golang.org page, input a @@ -171,3 +176,73 @@ func Example() { } } + +func ExampleChromeCDP() { + service, err := selenium.NewChromeDriverService("/usr/local/bin/chromedriver", 6789) + if err != nil { + panic(err) + } + defer service.Stop() + + caps := selenium.Capabilities{"browserName": "chrome"} + caps.AddLogging(log.Capabilities{ + log.Performance: log.All, + }) + caps.AddChrome(chrome.Capabilities{ + Args: []string{ + "--user-data-dir=/tmp/chrome", + "--headless", + }, + }) + wd, err := selenium.NewRemote(caps, fmt.Sprintf("http://localhost:%d/wd/hub", 6789)) + if err != nil { + panic(err) + } + defer wd.Quit() + + if err := wd.Get("xxxxx"); err != nil { + panic(err) + } + + // /resource/RelatedPinFeedResource/get + + log_messages, err := wd.Log(log.Performance) + if err != nil { + panic(err) + } + for _, log_message := range log_messages { + message := make(map[string]interface{}) + json.Unmarshal([]byte(log_message.Message), &message) + message = message["message"].(map[string]interface{}) + method := message["method"] + if method != "Network.responseReceived" { + continue + } + + params := message["params"].(map[string]interface{}) + response := params["response"].(map[string]interface{}) + if strings.Contains(response["url"].(string), "xxxxx") == false { + continue + } + + // use cdp + request_id := network.RequestID(params["requestId"].(string)) + response_body, err := wd.ExecuteChromeDPCommand(cdproto.CommandNetworkGetResponseBody, network.GetResponseBody(request_id)) + if err != nil { + panic(err) + } + + response_body_returns := network.GetResponseBodyReturns{} + mapstructure.Decode(response_body, &response_body_returns) + fmt.Printf("%v", response_body_returns.Body) + + // or use + response_body, err = wd.ExecuteChromeDPCommand("Network.getResponseBody", map[string]interface{}{ + "requestId": params["requestId"], + }) + if err != nil { + panic(err) + } + fmt.Printf("%v", response_body) + } +} diff --git a/go.mod b/go.mod index cbb519e..4ab4da8 100644 --- a/go.mod +++ b/go.mod @@ -7,10 +7,12 @@ require ( github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 github.com/blang/semver v3.5.1+incompatible + github.com/chromedp/cdproto v0.0.0-20220217222649-d8c14a5c6edf // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/protobuf v1.3.4 github.com/google/go-cmp v0.3.0 github.com/google/go-github/v27 v27.0.4 github.com/mediabuyerbot/go-crx3 v1.3.1 + github.com/mitchellh/mapstructure v1.4.3 // indirect google.golang.org/api v0.7.0 -) \ No newline at end of file +) diff --git a/go.sum b/go.sum index 28a9333..296c2dd 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,10 @@ github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdn github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/chromedp/cdproto v0.0.0-20200209033844-7e00b02ea7d2/go.mod h1:PfAWWKJqjlGFYJEidUM6aVIWPr0EpobeyVWEEmplX7g= +github.com/chromedp/cdproto v0.0.0-20220217222649-d8c14a5c6edf h1:1omDWNUsWxn2HpiMiMuyRmzjl9uG7RP3IE6GTlpgJWU= +github.com/chromedp/cdproto v0.0.0-20220217222649-d8c14a5c6edf/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U= +github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= +github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -76,6 +80,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -88,11 +94,15 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mediabuyerbot/go-crx3 v1.3.1 h1:JG3Hlaf7FsMhTJHBt+iEO5bK1GTh/Ms/cBT2aR2kBUE= github.com/mediabuyerbot/go-crx3 v1.3.1/go.mod h1:ecvIxF/Jv0jTy1JSx7YTuMlYpV49ayyW/pPxMl8o3P8= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= diff --git a/remote.go b/remote.go index 653b5f4..4cb7bf1 100644 --- a/remote.go +++ b/remote.go @@ -1270,6 +1270,29 @@ func (wd *remoteWD) ExecuteScriptAsyncRaw(script string, args []interface{}) ([] return wd.execScriptRaw(script, args, "/async") } +func (wd *remoteWD) ExecuteChromeDPCommand(cmd string, params interface{}) (interface{}, error) { + data, err := json.Marshal(map[string]interface{}{ + "cmd": cmd, + "params": params, + }) + + if err != nil { + return nil, err + } + + response, err := wd.execute("POST", wd.requestURL("/session/%s/goog/cdp/execute", wd.id), data) + if err != nil { + return nil, err + } + + reply := new(struct{ Value interface{} }) + if err = json.Unmarshal(response, reply); err != nil { + return nil, err + } + + return reply.Value, nil +} + func (wd *remoteWD) Screenshot() ([]byte, error) { data, err := wd.stringCommand("/session/%s/screenshot") if err != nil { diff --git a/selenium.go b/selenium.go index ecd8c91..902d9fd 100644 --- a/selenium.go +++ b/selenium.go @@ -422,6 +422,8 @@ type WebDriver interface { // perform JSON decoding. ExecuteScriptAsyncRaw(script string, args []interface{}) ([]byte, error) + ExecuteChromeDPCommand(cmd string, params interface{}) (interface{}, error) + // WaitWithTimeoutAndInterval waits for the condition to evaluate to true. WaitWithTimeoutAndInterval(condition Condition, timeout, interval time.Duration) error