├── .codecov.yml ├── .editorconfig ├── .github └── workflows │ └── test.yaml ├── LICENSE ├── README.md ├── cdp.go ├── cdp_client.go ├── cdp_client_io_stream_reader.go ├── cdp_test.go ├── cmd └── cdpgen │ ├── .gitignore │ ├── README.md │ ├── lint │ └── name.go │ ├── main.go │ ├── proto │ └── proto.go │ ├── protodef │ ├── browser_protocol.json │ ├── edge.json │ ├── js_protocol.json │ └── node.json │ └── update.sh ├── devtool ├── devtool.go ├── devtool_test.go ├── doc.go ├── headless.go ├── headless_test.go └── testdata │ ├── close.out │ ├── error.golden │ ├── list.json │ ├── new.json │ ├── test.golden │ └── version.json ├── doc.go ├── error.go ├── error_test.go ├── example └── screencast │ └── main.go ├── example_advanced_test.go ├── example_dial_test.go ├── example_incognito_test.go ├── example_logging_test.go ├── example_test.go ├── go.mod ├── go.sum ├── internal ├── errors │ ├── errors.go │ ├── errors_test.go │ └── stdlib.go └── testutil │ └── testutil.go ├── protocol ├── accessibility │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── animation │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── applicationcache │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── audits │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── autofill │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── backgroundservice │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── bluetoothemulation │ ├── command.go │ ├── domain.go │ └── types.go ├── browser │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── cachestorage │ ├── command.go │ ├── domain.go │ └── types.go ├── cast │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── console │ ├── domain.go │ ├── event.go │ └── types.go ├── css │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── database │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── debugger │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── deviceaccess │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── deviceorientation │ ├── command.go │ └── domain.go ├── doc.go ├── dom │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── domdebugger │ ├── command.go │ ├── domain.go │ └── types.go ├── domsnapshot │ ├── command.go │ ├── domain.go │ └── types.go ├── domstorage │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── emulation │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── eventbreakpoints │ ├── command.go │ └── domain.go ├── extensions │ ├── command.go │ ├── domain.go │ └── types.go ├── fedcm │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── fetch │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── filesystem │ ├── command.go │ ├── domain.go │ └── types.go ├── headlessexperimental │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── heapprofiler │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── indexeddb │ ├── command.go │ ├── domain.go │ └── types.go ├── input │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── inspector │ ├── domain.go │ └── event.go ├── internal │ ├── browser.go │ ├── error.go │ ├── error_test.go │ ├── network.go │ └── page.go ├── io │ ├── command.go │ ├── domain.go │ ├── stream_reader.go │ ├── stream_reder_test.go │ └── types.go ├── layertree │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── log │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── media │ ├── domain.go │ ├── event.go │ └── types.go ├── memory │ ├── command.go │ ├── domain.go │ └── types.go ├── network │ ├── command.go │ ├── domain.go │ ├── event.go │ ├── types.go │ └── util.go ├── overlay │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── page │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── performance │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── performancetimeline │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── preload │ ├── domain.go │ ├── event.go │ └── types.go ├── profiler │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── pwa │ ├── command.go │ ├── domain.go │ └── types.go ├── runtime │ ├── command.go │ ├── domain.go │ ├── event.go │ ├── testdata │ │ ├── log.golden │ │ ├── log.html │ │ ├── log.input │ │ └── log_input_gen.go │ ├── types.go │ ├── util.go │ └── util_test.go ├── schema │ ├── command.go │ ├── domain.go │ └── types.go ├── security │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── serviceworker │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── storage │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── systeminfo │ ├── command.go │ ├── domain.go │ └── types.go ├── target │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── tethering │ ├── command.go │ ├── domain.go │ └── event.go ├── tracing │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── webaudio │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go └── webauthn │ ├── command.go │ ├── domain.go │ ├── event.go │ └── types.go ├── rpcc ├── call.go ├── conn.go ├── conn_test.go ├── doc.go ├── socket.go ├── socket_test.go ├── stream.go ├── stream_sync.go ├── stream_sync_test.go └── stream_test.go ├── session ├── conn.go ├── doc.go ├── manager.go ├── manager_test.go ├── session.go └── session_test.go └── sync.go /.codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | # Ignore coverage for generated code. 3 | - "protocol/**/command([0-9]*)?.go" 4 | - "protocol/**/domain([0-9]*)?.go" 5 | - "protocol/**/types([0-9]*)?.go" 6 | - "protocol/**/event([0-9]*)?.go" 7 | - "protocol/page18.go" 8 | - "protocol/internal/page19.go" 9 | 10 | coverage: 11 | range: 70..100 12 | round: nearest 13 | precision: 1 14 | 15 | status: 16 | project: 17 | default: 18 | enabled: yes 19 | threshold: 2% 20 | patch: no 21 | changes: no 22 | 23 | comment: 24 | layout: "header, diff" 25 | behavior: once 26 | require_changes: yes 27 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | indent_style = tab 9 | 10 | [*.md] 11 | indent_style = space 12 | indent_size = 4 13 | 14 | [*.{json,yaml,yml}] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: [push, pull_request] 3 | jobs: 4 | test: 5 | runs-on: ubuntu-latest 6 | strategy: 7 | matrix: 8 | go: ["1.19", "1.23"] 9 | name: Test on Go ${{ matrix.go }} 10 | steps: 11 | - uses: actions/checkout@v3 12 | - name: Setup Go 13 | uses: actions/setup-go@v3 14 | with: 15 | go-version: ${{ matrix.go }} 16 | - run: go version 17 | - name: Setup Chrome 18 | uses: browser-actions/setup-chrome@latest 19 | - run: chrome --version 20 | - name: Run tests 21 | run: | 22 | chrome --headless --disable-gpu --remote-debugging-port=9222 --disable-setuid-sandbox --no-sandbox about:blank & 23 | chrome_pid=$! 24 | go list -f '{{if len .TestGoFiles}}-coverprofile={{.Name}}_coverage.out {{.ImportPath}}{{end}}' ./... | xargs -L1 go test -race -covermode=atomic 25 | go test ./session -browser -race -covermode=atomic -coverprofile=session_coverage.out 26 | go test . -browser 27 | kill -9 $chrome_pid 28 | - name: Upload coverage to Codecov 29 | uses: codecov/codecov-action@v4 30 | with: 31 | token: ${{ secrets.CODECOV_TOKEN }} 32 | fail_ci_if_error: true 33 | verbose: true 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Mathias Fredriksson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cdp_client_io_stream_reader.go: -------------------------------------------------------------------------------- 1 | package cdp 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/mafredri/cdp/protocol/io" 7 | ) 8 | 9 | // NewIOStreamReader returns a reader for io.Stream that implements io.Reader 10 | // from the standard library. 11 | func (c *Client) NewIOStreamReader(ctx context.Context, handle io.StreamHandle) *io.StreamReader { 12 | return io.NewStreamReader(ctx, c.IO, handle) 13 | } 14 | -------------------------------------------------------------------------------- /cdp_test.go: -------------------------------------------------------------------------------- 1 | package cdp_test 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "flag" 7 | "fmt" 8 | "net/http" 9 | "net/http/httptest" 10 | "os" 11 | "strings" 12 | "testing" 13 | "time" 14 | 15 | "github.com/gorilla/websocket" 16 | "github.com/mafredri/cdp" 17 | "github.com/mafredri/cdp/devtool" 18 | "github.com/mafredri/cdp/protocol/page" 19 | "github.com/mafredri/cdp/protocol/runtime" 20 | "github.com/mafredri/cdp/rpcc" 21 | ) 22 | 23 | var TestSockSrv string 24 | 25 | type testSocketServer struct { 26 | ws websocket.Upgrader 27 | } 28 | 29 | func (tc *testSocketServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { 30 | conn, err := tc.ws.Upgrade(w, r, nil) 31 | if err != nil { 32 | panic(err) 33 | } 34 | defer conn.Close() 35 | 36 | switch r.RequestURI { 37 | case "/example_logging": 38 | for { 39 | _, _, err := conn.ReadMessage() 40 | if err != nil { 41 | return 42 | } 43 | err = conn.WriteMessage(websocket.TextMessage, []byte(`{"id":1,"result":{}}`)) 44 | if err != nil { 45 | return 46 | } 47 | } 48 | } 49 | } 50 | 51 | func TestBrowser_RemoteDebuggingProtocol(t *testing.T) { 52 | if !*testBrowser { 53 | t.SkipNow() 54 | } 55 | 56 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 57 | defer cancel() 58 | 59 | devt := devtool.New(fmt.Sprintf("http://localhost:%d", *remoteDebuggingPort)) 60 | pt, err := devt.Create(ctx) 61 | if err != nil { 62 | t.Fatal(err) 63 | } 64 | defer devt.Close(ctx, pt) 65 | 66 | conn, err := rpcc.DialContext(ctx, pt.WebSocketDebuggerURL) 67 | if err != nil { 68 | t.Fatal(err) 69 | } 70 | defer conn.Close() 71 | 72 | c := cdp.NewClient(conn) 73 | 74 | if err = c.Page.Enable(ctx); err != nil { 75 | panic(err) 76 | } 77 | if err = c.Runtime.Enable(ctx); err != nil { 78 | panic(err) 79 | } 80 | 81 | domContentEventFired, err := c.Page.DOMContentEventFired(ctx) 82 | if err != nil { 83 | panic(err) 84 | } 85 | defer domContentEventFired.Close() 86 | 87 | // TODO(mafredri): Create a testdata HTML instead of relying on google.com. 88 | _, err = c.Page.Navigate(ctx, page.NewNavigateArgs("https://www.google.com")) 89 | if err != nil { 90 | t.Fatal(err) 91 | } 92 | 93 | _, err = domContentEventFired.Recv() 94 | if err != nil { 95 | t.Fatal(err) 96 | } 97 | 98 | eval, err := c.Runtime.Evaluate(ctx, runtime.NewEvaluateArgs("document.title")) 99 | if err != nil { 100 | t.Fatal(err) 101 | } 102 | 103 | want := "Google" 104 | var got string 105 | if err = json.Unmarshal(eval.Result.Value, &got); err != nil { 106 | t.Error(err) 107 | } 108 | 109 | if got != want { 110 | t.Errorf("Evaluate(document.title): got %q, want %q", got, want) 111 | } 112 | } 113 | 114 | var ( 115 | testBrowser = flag.Bool("browser", false, "Run browser tests") 116 | remoteDebuggingPort = flag.Int("rdp", 9222, "Remote debugging port (for browser tests)") 117 | ) 118 | 119 | func TestMain(m *testing.M) { 120 | flag.Parse() 121 | 122 | srv := httptest.NewServer(&testSocketServer{}) 123 | TestSockSrv = strings.TrimPrefix(srv.URL, "http://") 124 | code := m.Run() 125 | srv.Close() 126 | os.Exit(code) 127 | } 128 | -------------------------------------------------------------------------------- /cmd/cdpgen/.gitignore: -------------------------------------------------------------------------------- 1 | cdpgen 2 | -------------------------------------------------------------------------------- /cmd/cdpgen/README.md: -------------------------------------------------------------------------------- 1 | # cdpgen 2 | 3 | The cdpgen tool is used to generate the Golang API for the Chrome DevTools Protocol from the protocol definitions (JSON). 4 | 5 | Beware, this tool is not a feat of engineering, it's only purpose is to generate the Golang API. It has gone thourgh many revisions while prototyping the API and might contain both messy and dead code. 6 | 7 | ## Installing 8 | 9 | ```console 10 | go get -u github.com/mafredri/cdp/cmd/cdpgen 11 | ``` 12 | 13 | ## Usage 14 | 15 | The current protocol definitions are committed in this repository under the `protodef` directory. 16 | 17 | ### Generating the cdp package 18 | 19 | ```console 20 | $ cdpgen -dest-pkg github.com/mafredri/cdp \ 21 | -browser-proto $GOPATH/src/github.com/mafredri/cdp/cmd/cdpgen/protodef/browser_protocol.json \ 22 | -js-proto $GOPATH/src/github.com/mafredri/cdp/cmd/cdpgen/protodef/js_protocol.json 23 | ``` 24 | 25 | ### Updating protocol definitions 26 | 27 | ```console 28 | $ ./update.sh 29 | ``` 30 | 31 | ## Future improvements 32 | 33 | - Better formatting for comments, consider sentence construction, proper casing and line length. 34 | -------------------------------------------------------------------------------- /cmd/cdpgen/lint/name.go: -------------------------------------------------------------------------------- 1 | package lint 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | 7 | lint "github.com/mafredri/go-lint" 8 | ) 9 | 10 | var ( 11 | reIDs = regexp.MustCompile("^(.*)Ids($|[A-Z].*$)") 12 | reUUIDs = regexp.MustCompile("^(.*)Uuids($|[A-Z].*$)") 13 | reURLs = regexp.MustCompile("^(.*)Urls($|[A-Z].*$)") 14 | reIDRef = regexp.MustCompile("^(.*)Idref($|[A-Z].*$)") 15 | ) 16 | 17 | func init() { 18 | lint.SetInitialism("DOM", true) 19 | lint.SetInitialism("GPU", true) 20 | lint.SetInitialism("SSL", true) 21 | lint.SetInitialism("MAC", true) 22 | lint.SetInitialism("U2F", true) 23 | lint.SetInitialism("CTAP", true) 24 | lint.SetInitialism("USB", true) 25 | lint.SetInitialism("NFC", true) 26 | lint.SetInitialism("BLE", true) 27 | lint.SetInitialism("RP", true) // RPID => Relaying Party (ID). 28 | lint.SetInitialism("JPEG", true) 29 | lint.SetInitialism("WEBP", true) 30 | lint.SetInitialism("AVIF", true) 31 | lint.SetInitialism("RGB", true) 32 | lint.SetInitialism("HSL", true) 33 | lint.SetInitialism("CORS", true) 34 | lint.SetInitialism("WASM", true) 35 | lint.SetInitialism("JS", true) 36 | lint.SetInitialism("JXL", true) 37 | lint.SetInitialism("BR", true) // Brotli compression. 38 | lint.SetInitialism("HWB", true) // Color format. 39 | lint.SetInitialism("IME", true) 40 | lint.SetInitialism("CM", true) // FedCm => FedCM. 41 | lint.SetInitialism("OS", true) // Operating system. 42 | lint.SetInitialism("COEP", true) // Cross-Origin-Embedder-Policy. 43 | lint.SetInitialism("COOP", true) // Cross-Origin-Opener-Policy. 44 | lint.SetInitialism("CORP", true) // Cross-Origin-Resource-Policy. 45 | lint.SetInitialism("CVC", true) // Card verification code. 46 | lint.SetInitialism("IDP", true) // Identity Provider. 47 | lint.SetInitialism("CSP", true) // Content Security Policy. 48 | lint.SetInitialism("DIP", true) // Document isolation policy. 49 | lint.SetInitialism("RSSI", true) 50 | lint.SetInitialism("CH", true) 51 | lint.SetInitialism("DPR", true) 52 | lint.SetInitialism("UA", true) 53 | lint.SetInitialism("ECT", true) 54 | lint.SetInitialism("RTT", true) 55 | lint.SetInitialism("HID", true) 56 | lint.SetInitialism("OTP", true) 57 | lint.SetInitialism("XHR", true) 58 | } 59 | 60 | // Name returns a different name if it should be different. 61 | func Name(name string) (should string) { 62 | should = lint.Name(name) 63 | 64 | for _, replace := range []struct { 65 | re *regexp.Regexp 66 | to string 67 | }{ 68 | {re: reIDs, to: "IDs"}, 69 | {re: reUUIDs, to: "UUIDs"}, 70 | {re: reURLs, to: "URLs"}, 71 | {re: reIDRef, to: "IDRef"}, 72 | } { 73 | should = replace.re.ReplaceAllString(should, fmt.Sprintf("${1}%s${2}", replace.to)) 74 | } 75 | 76 | return should 77 | } 78 | -------------------------------------------------------------------------------- /cmd/cdpgen/update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | (cd "$(dirname "$0")"; 4 | [[ -d protodef ]] || mkdir protodef 5 | (cd protodef; 6 | curl -sSL "https://github.com/ChromeDevTools/devtools-protocol/raw/master/json/browser_protocol.json" >js_protocol.json 7 | curl -sSL "https://github.com/ChromeDevTools/devtools-protocol/raw/master/json/js_protocol.json" >browser_protocol.json 8 | ) 9 | ) 10 | -------------------------------------------------------------------------------- /devtool/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package devtool provides methods for interacting with a DevTools 3 | endpoint. 4 | 5 | To activate the DevTools endpoint, a browser (or other debug target) 6 | should be started with debugging enabled: 7 | 8 | chromium --remote-debugging-port=9222 9 | .//EdgeDiagnosticsAdapter.exe --port 9223 10 | node --inspect=9224 11 | 12 | Create a new DevTools instance that interacts with the given URL: 13 | 14 | devt := devtool.New("http://127.0.0.1:9222") 15 | 16 | Get the active page or create a new one: 17 | 18 | devt := devtool.New("http://127.0.0.1:9222") 19 | page, err := devt.Get(context.Background(), devtool.Page) 20 | if err != nil { 21 | page, err = devt.Create(context.Background()) 22 | if err != nil { 23 | // Handle error. 24 | } 25 | } 26 | // ... 27 | 28 | Set request timeouts via contexts: 29 | 30 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 31 | defer cancel() 32 | 33 | devt := devtool.New("http://127.0.0.1:9222") 34 | list, err := devt.List(ctx) 35 | if err != nil { 36 | // Handle error. 37 | } 38 | // ... 39 | */ 40 | package devtool 41 | -------------------------------------------------------------------------------- /devtool/headless.go: -------------------------------------------------------------------------------- 1 | package devtool 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "regexp" 7 | 8 | "github.com/mafredri/cdp" 9 | "github.com/mafredri/cdp/protocol/target" 10 | "github.com/mafredri/cdp/rpcc" 11 | ) 12 | 13 | var httpRe = regexp.MustCompile("^https?://") 14 | 15 | // fallbackHeadlessCreateURL tries to create a new target for Headless Chrome 16 | // that does not support the json new endpoint. A rpcc connection is established 17 | // to the "/devtools/browser" endpoint and "Target.createTarget" is issued. 18 | func fallbackHeadlessCreateURL(ctx context.Context, d *DevTools, openURL string) (*Target, error) { 19 | // Context must be set, rpcc DialContext panics on nil context. 20 | if ctx == nil { 21 | ctx = context.Background() 22 | } 23 | 24 | // Headless Chrome requires a non-empty URL for CreateTarget. 25 | if openURL == "" { 26 | openURL = "about:blank" 27 | } 28 | 29 | wsURL := "ws://" + httpRe.ReplaceAllString(d.url, "") + "/devtools/browser" 30 | conn, err := rpcc.DialContext(ctx, wsURL) 31 | if err != nil { 32 | return nil, err 33 | } 34 | defer conn.Close() 35 | 36 | c := cdp.NewClient(conn) 37 | t, err := c.Target.CreateTarget(ctx, target.NewCreateTargetArgs(openURL)) 38 | if err != nil { 39 | return nil, err 40 | } 41 | 42 | // List must be called after CreateTarget (headless bug): 43 | // https://bugs.chromium.org/p/chromium/issues/detail?id=704503 44 | list, err := d.List(ctx) 45 | if err != nil { 46 | return nil, err 47 | } 48 | 49 | for _, tt := range list { 50 | if tt.ID == string(t.TargetID) { 51 | return tt, nil 52 | } 53 | } 54 | 55 | return nil, errors.New("devtool: headlessCreateURL: could not create target") 56 | } 57 | -------------------------------------------------------------------------------- /devtool/testdata/close.out: -------------------------------------------------------------------------------- 1 | Target is closing -------------------------------------------------------------------------------- /devtool/testdata/error.golden: -------------------------------------------------------------------------------- 1 | Create: devtool: CreateURL: Not found 2 | Get: devtool: List: Not found 3 | Get ServiceWorker: devtool: Get: could not find target of type: service_worker 4 | Close: devtool: Close: Could not close target id: ddd908ca-4d8c-4783-a089-c9456c463eef 5 | Activate: devtool: Activate: Could not close target id: ddd908ca-4d8c-4783-a089-c9456c463eef 6 | Version: devtool: Version: Not found 7 | -------------------------------------------------------------------------------- /devtool/testdata/list.json: -------------------------------------------------------------------------------- 1 | [ { 2 | "description": "", 3 | "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/4bae5c92-f550-4538-aafb-4263b4e6c9b2", 4 | "id": "4bae5c92-f550-4538-aafb-4263b4e6c9b2", 5 | "title": "about:blank", 6 | "type": "page", 7 | "url": "about:blank", 8 | "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/4bae5c92-f550-4538-aafb-4263b4e6c9b2" 9 | }, { 10 | "description": "", 11 | "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/a36bf2bf-f50d-4e26-95ea-e71b679ddf5c", 12 | "id": "a36bf2bf-f50d-4e26-95ea-e71b679ddf5c", 13 | "title": "about:blank", 14 | "type": "page", 15 | "url": "about:blank", 16 | "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/a36bf2bf-f50d-4e26-95ea-e71b679ddf5c" 17 | } ] 18 | -------------------------------------------------------------------------------- /devtool/testdata/new.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "", 3 | "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/ded68f91-23c0-4d15-b644-c10c3d06ec32", 4 | "id": "ded68f91-23c0-4d15-b644-c10c3d06ec32", 5 | "title": "", 6 | "type": "page", 7 | "url": "about:blank", 8 | "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/ded68f91-23c0-4d15-b644-c10c3d06ec32" 9 | } 10 | -------------------------------------------------------------------------------- /devtool/testdata/test.golden: -------------------------------------------------------------------------------- 1 | PUT /json/new?https%3A%2F%2Fwww.google.com 2 | CreateURL: &{ /devtools/inspector.html?ws=localhost:9222/devtools/page/ded68f91-23c0-4d15-b644-c10c3d06ec32 ded68f91-23c0-4d15-b644-c10c3d06ec32 page about:blank ws://localhost:9222/devtools/page/ded68f91-23c0-4d15-b644-c10c3d06ec32} 3 | PUT /json/new 4 | Create: &{ /devtools/inspector.html?ws=localhost:9222/devtools/page/ded68f91-23c0-4d15-b644-c10c3d06ec32 ded68f91-23c0-4d15-b644-c10c3d06ec32 page about:blank ws://localhost:9222/devtools/page/ded68f91-23c0-4d15-b644-c10c3d06ec32} 5 | PUT /json/list 6 | Get: &{ /devtools/inspector.html?ws=localhost:9222/devtools/page/4bae5c92-f550-4538-aafb-4263b4e6c9b2 4bae5c92-f550-4538-aafb-4263b4e6c9b2 about:blank page about:blank ws://localhost:9222/devtools/page/4bae5c92-f550-4538-aafb-4263b4e6c9b2} 7 | PUT /json/close/ddd908ca-4d8c-4783-a089-c9456c463eef 8 | Close: 9 | PUT /json/activate/ddd908ca-4d8c-4783-a089-c9456c463eef 10 | Activate: 11 | PUT /json/version 12 | Version: &{Chrome/59.0.3040.0 1.2 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3040.0 Safari/537.36 5.9.35 537.36 (@c020f6a22577978ce1fe89fc1a397f2a651c48a8) ws://localhost:9222/devtools/browser/74ffefaa-3f6b-4d25-8fb3-98b85d7bf1cd} 13 | -------------------------------------------------------------------------------- /devtool/testdata/version.json: -------------------------------------------------------------------------------- 1 | { 2 | "Browser": "Chrome/59.0.3040.0", 3 | "Protocol-Version": "1.2", 4 | "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3040.0 Safari/537.36", 5 | "V8-Version": "5.9.35", 6 | "WebKit-Version": "537.36 (@c020f6a22577978ce1fe89fc1a397f2a651c48a8)", 7 | "webSocketDebuggerUrl": "ws://localhost:9222/devtools/browser/74ffefaa-3f6b-4d25-8fb3-98b85d7bf1cd" 8 | } 9 | -------------------------------------------------------------------------------- /error.go: -------------------------------------------------------------------------------- 1 | package cdp 2 | 3 | import ( 4 | "github.com/mafredri/cdp/internal/errors" 5 | ) 6 | 7 | // ErrorCause returns the underlying cause for this error, if possible. 8 | // If err does not implement causer.Cause(), then err is returned. 9 | // 10 | // Deprecated: Use errors.Unwrap, errors.Is or errors.As instead. 11 | func ErrorCause(err error) error { return errors.Cause(err) } 12 | -------------------------------------------------------------------------------- /error_test.go: -------------------------------------------------------------------------------- 1 | package cdp 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | ) 7 | 8 | type opError struct { 9 | err error 10 | } 11 | 12 | func (o *opError) Cause() error { 13 | return o.err 14 | } 15 | 16 | func (o opError) Error() string { 17 | return o.err.Error() 18 | } 19 | 20 | func TestErrorCause(t *testing.T) { 21 | err1 := errors.New("trigger") 22 | 23 | tests := []struct { 24 | name string 25 | err error 26 | want error 27 | }{ 28 | {"Returns underlying error", &opError{err: err1}, err1}, 29 | {"Returns original error", err1, err1}, 30 | {"Returns nil", nil, nil}, 31 | } 32 | 33 | for _, tt := range tests { 34 | t.Run(tt.name, func(t *testing.T) { 35 | got := ErrorCause(tt.err) 36 | if got != tt.want { 37 | t.Errorf("got %v, want %v", got, tt.want) 38 | } 39 | }) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /example/screencast/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io/ioutil" 7 | "log" 8 | "time" 9 | 10 | "github.com/mafredri/cdp" 11 | "github.com/mafredri/cdp/devtool" 12 | "github.com/mafredri/cdp/protocol/page" 13 | "github.com/mafredri/cdp/rpcc" 14 | ) 15 | 16 | func main() { 17 | if err := run(); err != nil { 18 | panic(err) 19 | } 20 | } 21 | 22 | func run() error { 23 | ctx, cancel := context.WithCancel(context.TODO()) 24 | defer cancel() 25 | 26 | devt := devtool.New("http://localhost:9222") 27 | 28 | pageTarget, err := devt.Get(ctx, devtool.Page) 29 | if err != nil { 30 | return err 31 | } 32 | 33 | conn, err := rpcc.DialContext(ctx, pageTarget.WebSocketDebuggerURL) 34 | if err != nil { 35 | return err 36 | } 37 | defer conn.Close() 38 | 39 | c := cdp.NewClient(conn) 40 | 41 | err = c.Page.Enable(ctx) 42 | if err != nil { 43 | return err 44 | } 45 | 46 | // Navigate to GitHub, block until ready. 47 | loadEventFired, err := c.Page.LoadEventFired(ctx) 48 | if err != nil { 49 | return err 50 | } 51 | 52 | _, err = c.Page.Navigate(ctx, page.NewNavigateArgs("https://github.com")) 53 | if err != nil { 54 | return err 55 | } 56 | 57 | _, err = loadEventFired.Recv() 58 | if err != nil { 59 | return err 60 | } 61 | loadEventFired.Close() 62 | 63 | // Start listening to ScreencastFrame events. 64 | screencastFrame, err := c.Page.ScreencastFrame(ctx) 65 | if err != nil { 66 | return err 67 | } 68 | 69 | go func() { 70 | defer screencastFrame.Close() 71 | 72 | for { 73 | ev, err := screencastFrame.Recv() 74 | if err != nil { 75 | log.Printf("Failed to receive ScreencastFrame: %v", err) 76 | return 77 | } 78 | log.Printf("Got frame with sessionID: %d: %+v", ev.SessionID, ev.Metadata) 79 | 80 | err = c.Page.ScreencastFrameAck(ctx, page.NewScreencastFrameAckArgs(ev.SessionID)) 81 | if err != nil { 82 | log.Printf("Failed to ack ScreencastFrame: %v", err) 83 | return 84 | } 85 | 86 | // Write to screencast_frame-[timestamp].png. 87 | name := fmt.Sprintf("screencast_frame-%d.png", ev.Metadata.Timestamp.Time().Unix()) 88 | 89 | // Write the frame to file (without blocking). 90 | go func() { 91 | err = ioutil.WriteFile(name, ev.Data, 0o644) 92 | if err != nil { 93 | log.Printf("Failed to write ScreencastFrame to %q: %v", name, err) 94 | } 95 | }() 96 | } 97 | }() 98 | 99 | screencastArgs := page.NewStartScreencastArgs(). 100 | SetEveryNthFrame(1). 101 | SetFormat("png") 102 | err = c.Page.StartScreencast(ctx, screencastArgs) 103 | if err != nil { 104 | return err 105 | } 106 | 107 | // Random delay for our screencast. 108 | time.Sleep(30 * time.Second) 109 | 110 | err = c.Page.StopScreencast(ctx) 111 | if err != nil { 112 | return err 113 | } 114 | 115 | return nil 116 | } 117 | -------------------------------------------------------------------------------- /example_dial_test.go: -------------------------------------------------------------------------------- 1 | package cdp_test 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io" 7 | "log" 8 | 9 | "github.com/coder/websocket" 10 | 11 | "github.com/mafredri/cdp" 12 | "github.com/mafredri/cdp/devtool" 13 | "github.com/mafredri/cdp/protocol/runtime" 14 | "github.com/mafredri/cdp/rpcc" 15 | ) 16 | 17 | func Example_dial_using_alternative_websocket_implementation() { 18 | ctx, cancel := context.WithCancel(context.Background()) 19 | defer cancel() 20 | 21 | devt := devtool.New("http://localhost:9222") 22 | page, err := devt.CreateURL(ctx, "about:blank") 23 | if err != nil { 24 | log.Println(err) 25 | } 26 | 27 | // Dial using an alternative websocket implementation. 28 | // 29 | // Note that this disables functionality like: 30 | // 31 | // - Safety measure against writing fragmented websocket messages 32 | // - Setting compression level after dial 33 | dialer := rpcc.WithDialer(func(dialCtx context.Context, addr string) (io.ReadWriteCloser, error) { 34 | log.Println(addr) 35 | conn, _, err := websocket.Dial(dialCtx, addr, &websocket.DialOptions{ 36 | CompressionMode: websocket.CompressionContextTakeover, 37 | }) 38 | if err != nil { 39 | return nil, err 40 | } 41 | // Note that we cannot use dialCtx here since websocket.NetConn 42 | // binds to the lifetime of ctx. 43 | return websocket.NetConn(ctx, conn, websocket.MessageText), nil 44 | }) 45 | conn, err := rpcc.Dial(page.WebSocketDebuggerURL, dialer) 46 | if err != nil { 47 | log.Println(err) 48 | } 49 | defer conn.Close() 50 | 51 | // Use the connection that uses nhooyr.io/websocket underneath. 52 | c := cdp.NewClient(conn) 53 | 54 | if err = c.Runtime.Enable(ctx); err != nil { 55 | log.Println(err) 56 | } 57 | eval, err := c.Runtime.Evaluate(ctx, runtime.NewEvaluateArgs(`document.location.href`).SetReturnByValue(true)) 58 | if err == nil && eval.ExceptionDetails != nil { 59 | err = eval.ExceptionDetails 60 | } 61 | if err != nil { 62 | log.Println(err) 63 | } 64 | fmt.Println(eval.Result.String()) 65 | 66 | err = devt.Close(ctx, page) 67 | if err != nil { 68 | log.Println(err) 69 | } 70 | // Output: 71 | // "about:blank" 72 | } 73 | -------------------------------------------------------------------------------- /example_logging_test.go: -------------------------------------------------------------------------------- 1 | package cdp_test 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "encoding/json" 7 | "fmt" 8 | "io" 9 | 10 | "github.com/mafredri/cdp" 11 | "github.com/mafredri/cdp/rpcc" 12 | ) 13 | 14 | // LogCodec captures the output from writing RPC requests and reading 15 | // responses on the connection. It implements rpcc.Codec via 16 | // WriteRequest and ReadResponse. 17 | type LogCodec struct{ conn io.ReadWriter } 18 | 19 | // WriteRequest marshals v into a buffer, writes its contents onto the 20 | // connection and logs it. 21 | func (c *LogCodec) WriteRequest(req *rpcc.Request) error { 22 | var buf bytes.Buffer 23 | if err := json.NewEncoder(&buf).Encode(req); err != nil { 24 | return err 25 | } 26 | fmt.Printf("SEND: %s", buf.Bytes()) 27 | _, err := c.conn.Write(buf.Bytes()) 28 | if err != nil { 29 | return err 30 | } 31 | return nil 32 | } 33 | 34 | // ReadResponse unmarshals from the connection into v whilst echoing 35 | // what is read into a buffer for logging. 36 | func (c *LogCodec) ReadResponse(resp *rpcc.Response) error { 37 | var buf bytes.Buffer 38 | if err := json.NewDecoder(io.TeeReader(c.conn, &buf)).Decode(resp); err != nil { 39 | return err 40 | } 41 | fmt.Printf("RECV: %s\n", buf.String()) 42 | return nil 43 | } 44 | 45 | func Example_logging() { 46 | ctx, cancel := context.WithCancel(context.Background()) 47 | defer cancel() 48 | 49 | newLogCodec := func(conn io.ReadWriter) rpcc.Codec { 50 | return &LogCodec{conn: conn} 51 | } 52 | conn, err := rpcc.Dial("ws://"+TestSockSrv+"/example_logging", rpcc.WithCodec(newLogCodec)) 53 | if err != nil { 54 | fmt.Println(err) 55 | } 56 | defer conn.Close() 57 | 58 | c := cdp.NewClient(conn) 59 | 60 | if err = c.Network.Enable(ctx, nil); err != nil { 61 | fmt.Println(err) 62 | } 63 | // Output: 64 | // SEND: {"id":1,"method":"Network.enable"} 65 | // RECV: {"id":1,"result":{}} 66 | } 67 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/mafredri/cdp 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/client9/misspell v0.3.4 7 | github.com/coder/websocket v1.8.12 8 | github.com/google/go-cmp v0.6.0 9 | github.com/gorilla/websocket v1.5.3 10 | github.com/mafredri/go-lint v0.0.0-20180911205320-920981dfc79e 11 | golang.org/x/sync v0.8.0 12 | golang.org/x/text v0.17.0 13 | ) 14 | -------------------------------------------------------------------------------- /internal/errors/errors.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | // Interfaces for common error unwrapping. 9 | type causer interface{ Cause() error } 10 | type wrapper interface{ Unwrap() error } 11 | 12 | // Cause returns the underlying cause for this error, if possible. 13 | // If err does not implement causer.Cause(), then err is returned. 14 | // 15 | // Deprecated: Use errors.Unwrap, errors.Is or errors.As instead. 16 | func Cause(err error) error { 17 | for err != nil { 18 | if c, ok := err.(wrapper); ok { 19 | err = c.Unwrap() 20 | } else if c, ok := err.(causer); ok { 21 | err = c.Cause() 22 | } else { 23 | return err 24 | } 25 | } 26 | return err 27 | } 28 | 29 | // Wrapf wraps an error with a message. Wrapf returns nil if error is nil. 30 | func Wrapf(err error, format string, a ...interface{}) error { 31 | if err == nil { 32 | return nil 33 | } 34 | return &wrapped{ 35 | err: err, 36 | msg: fmt.Sprintf(format, a...), 37 | } 38 | } 39 | 40 | type wrapped struct { 41 | err error 42 | msg string 43 | } 44 | 45 | var ( 46 | _ error = (*wrapped)(nil) 47 | _ causer = (*wrapped)(nil) 48 | _ wrapper = (*wrapped)(nil) 49 | ) 50 | 51 | func (e *wrapped) Error() string { return fmt.Sprintf("%s: %s", e.msg, e.err.Error()) } 52 | func (e *wrapped) Cause() error { return e.err } 53 | func (e *wrapped) Unwrap() error { return e.err } 54 | 55 | // Merge errors into one, nil errors are discarded 56 | // and returns nil if all errors are nil. 57 | func Merge(err ...error) error { 58 | var errs []error 59 | for _, e := range err { 60 | if e != nil { 61 | errs = append(errs, e) 62 | } 63 | } 64 | if len(errs) == 0 { 65 | return nil 66 | } 67 | return &merged{s: errs} 68 | } 69 | 70 | type merged struct { 71 | s []error 72 | } 73 | 74 | var ( 75 | _ error = (*merged)(nil) 76 | _ causer = (*merged)(nil) 77 | _ wrapper = (*merged)(nil) 78 | ) 79 | 80 | func (e *merged) Error() string { 81 | var s strings.Builder 82 | for i, err := range e.s { 83 | if i > 0 { 84 | s.WriteString(": ") 85 | } 86 | s.WriteString(err.Error()) 87 | } 88 | return s.String() 89 | } 90 | 91 | // Unwrap returns only the first error, there is 92 | // no way to create a queue of errors. 93 | func (e *merged) Unwrap() error { return e.s[0] } 94 | 95 | // Cause returns only the first error as there is 96 | // no way to create a queue of errors. 97 | func (e *merged) Cause() error { return e.s[0] } 98 | 99 | // Is does errors.Is on all merged errors. 100 | func (e *merged) Is(target error) bool { 101 | if target == nil { 102 | return nil == e.s 103 | } 104 | for _, err := range e.s { 105 | if Is(err, target) { 106 | return true 107 | } 108 | } 109 | return false 110 | } 111 | 112 | // As does errors.As on all merged errors. 113 | func (e *merged) As(target interface{}) bool { 114 | for _, err := range e.s { 115 | if As(err, target) { 116 | return true 117 | } 118 | } 119 | return false 120 | } 121 | -------------------------------------------------------------------------------- /internal/errors/errors_test.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func TestErrorf(t *testing.T) { 10 | got := Errorf("%s%s", "a", "b") 11 | if !strings.Contains(got.Error(), "ab") { 12 | t.Errorf("error does not contain %q, got %v", "ab", got) 13 | } 14 | } 15 | 16 | func TestWrap(t *testing.T) { 17 | err := errors.New("first") 18 | 19 | msg := "second" 20 | got := Wrapf(err, msg) 21 | if !strings.Contains(got.Error(), err.Error()) { 22 | t.Errorf("wrapped error did not contain the first error, got: %v", got) 23 | } 24 | if !strings.Contains(got.Error(), msg) { 25 | t.Errorf("wrapped error did not contain message, got: %v", got) 26 | } 27 | if cause := Cause(got); cause != err { 28 | t.Errorf("wrong cause: expected %v, got %v", err, cause) 29 | } 30 | } 31 | 32 | func TestWrapNilError(t *testing.T) { 33 | var err error 34 | got := Wrapf(err, "test") 35 | if got != nil { 36 | t.Errorf("expected nil, got %v", got) 37 | } 38 | } 39 | 40 | func TestMergeError(t *testing.T) { 41 | err1 := errors.New("first") 42 | err2 := errors.New("second") 43 | 44 | got := Merge(err1, err2) 45 | if !strings.Contains(got.Error(), err1.Error()) { 46 | t.Errorf("merged error did not contain first error, want: %v, got: %v", err1.Error(), got.Error()) 47 | } 48 | if !strings.Contains(got.Error(), err2.Error()) { 49 | t.Errorf("merged error did not contain second error, want: %v, got: %v", err2.Error(), got.Error()) 50 | } 51 | } 52 | 53 | func TestMergeErrorIs(t *testing.T) { 54 | err1 := errors.New("first") 55 | err2 := errors.New("second") 56 | err3 := errors.New("third") 57 | 58 | got := Merge(err1, err2) 59 | 60 | if !errors.Is(got, err1) { 61 | t.Errorf("merged error is not err1, want true, got false") 62 | } 63 | if !errors.Is(got, err2) { 64 | t.Errorf("merged error is not err2, want true, got false") 65 | } 66 | if errors.Is(got, err3) { 67 | t.Errorf("merged error is err3, want false, got true") 68 | } 69 | } 70 | 71 | type testErrorAs struct{ msg string } 72 | 73 | func (e testErrorAs) Error() string { return e.msg } 74 | 75 | func TestMergeErrorAs(t *testing.T) { 76 | err1 := &wrapped{msg: "err1"} 77 | err2 := testErrorAs{msg: "err2"} 78 | 79 | err := Merge(err1, err2) 80 | got1 := &wrapped{} 81 | if !errors.As(err, &got1) { 82 | t.Errorf("merged error as wrapped failed, want true, got false") 83 | } else if got1.msg != "err1" { 84 | t.Errorf("merged error as wrapped did not assign the error, want msg=err1, got msg=%s", got1.msg) 85 | } 86 | got2 := testErrorAs{} 87 | if !errors.As(err, &got2) { 88 | t.Errorf("merged error as testErrorAs failed, want true, got false") 89 | } else if got2.Error() != "err2" { 90 | t.Errorf("merged error as testErrorAs did not assign the error, want msg=err2, got msg=%s", got2.Error()) 91 | } 92 | } 93 | 94 | func TestMergeNoError(t *testing.T) { 95 | got := Merge(nil, nil) 96 | if got != nil { 97 | t.Errorf("expected no error, got %v", got) 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /internal/errors/stdlib.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package errors 6 | 7 | import ( 8 | stderrors "errors" 9 | "fmt" 10 | ) 11 | 12 | // New returns an error that formats as the given text. 13 | // Each call to New returns a distinct error value even if the text is identical. 14 | func New(text string) error { return stderrors.New(text) } 15 | 16 | // Unwrap returns the result of calling the Unwrap method on err, if err's 17 | // type contains an Unwrap method returning error. 18 | // Otherwise, Unwrap returns nil. 19 | func Unwrap(err error) error { return stderrors.Unwrap(err) } 20 | 21 | // Is reports whether any error in err's chain matches target. 22 | // 23 | // The chain consists of err itself followed by the sequence of errors obtained by 24 | // repeatedly calling Unwrap. 25 | // 26 | // An error is considered to match a target if it is equal to that target or if 27 | // it implements a method Is(error) bool such that Is(target) returns true. 28 | // 29 | // An error type might provide an Is method so it can be treated as equivalent 30 | // to an existing error. For example, if MyError defines 31 | // 32 | // func (m MyError) Is(target error) bool { return target == os.ErrExist } 33 | // 34 | // then Is(MyError{}, os.ErrExist) returns true. See syscall.Errno.Is for 35 | // an example in the standard library. 36 | func Is(err, target error) bool { return stderrors.Is(err, target) } 37 | 38 | // As finds the first error in err's chain that matches target, and if so, sets 39 | // target to that error value and returns true. Otherwise, it returns false. 40 | // 41 | // The chain consists of err itself followed by the sequence of errors obtained by 42 | // repeatedly calling Unwrap. 43 | // 44 | // An error matches target if the error's concrete value is assignable to the value 45 | // pointed to by target, or if the error has a method As(interface{}) bool such that 46 | // As(target) returns true. In the latter case, the As method is responsible for 47 | // setting target. 48 | // 49 | // An error type might provide an As method so it can be treated as if it were a 50 | // different error type. 51 | // 52 | // As panics if target is not a non-nil pointer to either a type that implements 53 | // error, or to any interface type. 54 | func As(err error, target interface{}) bool { return stderrors.As(err, target) } 55 | 56 | // Errorf formats according to a format specifier and returns the string as a 57 | // value that satisfies error. 58 | // 59 | // If the format specifier includes a %w verb with an error operand, 60 | // the returned error will implement an Unwrap method returning the operand. It is 61 | // invalid to include more than one %w verb or to supply it with an operand 62 | // that does not implement the error interface. The %w verb is otherwise 63 | // a synonym for %v. 64 | func Errorf(format string, a ...interface{}) error { return fmt.Errorf(format, a...) } 65 | -------------------------------------------------------------------------------- /internal/testutil/testutil.go: -------------------------------------------------------------------------------- 1 | package testutil 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | "time" 7 | 8 | "github.com/mafredri/cdp" 9 | "github.com/mafredri/cdp/devtool" 10 | "github.com/mafredri/cdp/protocol/target" 11 | "github.com/mafredri/cdp/rpcc" 12 | ) 13 | 14 | // Client represents a test client. 15 | type Client struct { 16 | t *testing.T 17 | Conn *rpcc.Conn 18 | Client *cdp.Client 19 | } 20 | 21 | // NewPage creates a new page target. 22 | func (c *Client) NewPage(ctx context.Context) *Target { 23 | return NewTarget(ctx, c.t, c.Client) 24 | } 25 | 26 | // NewClient returns a new test client. 27 | func NewClient(ctx context.Context, t *testing.T) *Client { 28 | t.Helper() 29 | 30 | devt := devtool.New("http://localhost:9222") 31 | v, err := devt.Version(ctx) 32 | if err != nil { 33 | t.Fatal(err) 34 | } 35 | conn, err := rpcc.DialContext(ctx, v.WebSocketDebuggerURL) 36 | if err != nil { 37 | t.Fatal(err) 38 | } 39 | 40 | return &Client{ 41 | t: t, 42 | Conn: conn, 43 | Client: cdp.NewClient(conn), 44 | } 45 | } 46 | 47 | // Target represents a (page) target. 48 | type Target struct { 49 | t *testing.T 50 | c *cdp.Client 51 | id target.ID 52 | } 53 | 54 | // ID returns the target ID. 55 | func (t *Target) ID() target.ID { 56 | return t.id 57 | } 58 | 59 | // Close closes the target. 60 | func (t *Target) Close() { 61 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 62 | defer cancel() 63 | 64 | reply, err := t.c.Target.CloseTarget(ctx, 65 | target.NewCloseTargetArgs(t.ID())) 66 | if err != nil { 67 | t.t.Error(err) 68 | } 69 | if !reply.Success { 70 | t.t.Error("close target failed") 71 | } 72 | } 73 | 74 | // NewTarget creates a new target. 75 | func NewTarget(ctx context.Context, t *testing.T, c *cdp.Client) *Target { 76 | reply, err := c.Target.CreateTarget(ctx, 77 | target.NewCreateTargetArgs("about:blank")) 78 | if err != nil { 79 | t.Fatal(err) 80 | } 81 | 82 | return &Target{t: t, c: c, id: reply.TargetID} 83 | } 84 | -------------------------------------------------------------------------------- /protocol/accessibility/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package accessibility 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // LoadCompleteClient is a client for LoadComplete events. The loadComplete 10 | // event mirrors the load complete event sent by the browser to assistive 11 | // technology when the web page has finished loading. 12 | type LoadCompleteClient interface { 13 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 14 | // triggered, context canceled or connection closed. 15 | Recv() (*LoadCompleteReply, error) 16 | rpcc.Stream 17 | } 18 | 19 | // LoadCompleteReply is the reply for LoadComplete events. 20 | type LoadCompleteReply struct { 21 | Root AXNode `json:"root"` // New document root node. 22 | } 23 | 24 | // NodesUpdatedClient is a client for NodesUpdated events. The nodesUpdated 25 | // event is sent every time a previously requested node has changed the in 26 | // tree. 27 | type NodesUpdatedClient interface { 28 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 29 | // triggered, context canceled or connection closed. 30 | Recv() (*NodesUpdatedReply, error) 31 | rpcc.Stream 32 | } 33 | 34 | // NodesUpdatedReply is the reply for NodesUpdated events. 35 | type NodesUpdatedReply struct { 36 | Nodes []AXNode `json:"nodes"` // Updated node data. 37 | } 38 | -------------------------------------------------------------------------------- /protocol/animation/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package animation 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // CanceledClient is a client for AnimationCanceled events. Event for when an 10 | // animation has been canceled. 11 | type CanceledClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*CanceledReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // CanceledReply is the reply for AnimationCanceled events. 19 | type CanceledReply struct { 20 | ID string `json:"id"` // Id of the animation that was canceled. 21 | } 22 | 23 | // CreatedClient is a client for AnimationCreated events. Event for each 24 | // animation that has been created. 25 | type CreatedClient interface { 26 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 27 | // triggered, context canceled or connection closed. 28 | Recv() (*CreatedReply, error) 29 | rpcc.Stream 30 | } 31 | 32 | // CreatedReply is the reply for AnimationCreated events. 33 | type CreatedReply struct { 34 | ID string `json:"id"` // Id of the animation that was created. 35 | } 36 | 37 | // StartedClient is a client for AnimationStarted events. Event for animation 38 | // that has been started. 39 | type StartedClient interface { 40 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 41 | // triggered, context canceled or connection closed. 42 | Recv() (*StartedReply, error) 43 | rpcc.Stream 44 | } 45 | 46 | // StartedReply is the reply for AnimationStarted events. 47 | type StartedReply struct { 48 | Animation Animation `json:"animation"` // Animation that was started. 49 | } 50 | 51 | // UpdatedClient is a client for AnimationUpdated events. Event for animation 52 | // that has been updated. 53 | type UpdatedClient interface { 54 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 55 | // triggered, context canceled or connection closed. 56 | Recv() (*UpdatedReply, error) 57 | rpcc.Stream 58 | } 59 | 60 | // UpdatedReply is the reply for AnimationUpdated events. 61 | type UpdatedReply struct { 62 | Animation Animation `json:"animation"` // Animation that was updated. 63 | } 64 | -------------------------------------------------------------------------------- /protocol/applicationcache/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package applicationcache 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/page" 7 | ) 8 | 9 | // GetApplicationCacheForFrameArgs represents the arguments for GetApplicationCacheForFrame in the ApplicationCache domain. 10 | type GetApplicationCacheForFrameArgs struct { 11 | FrameID page.FrameID `json:"frameId"` // Identifier of the frame containing document whose application cache is retrieved. 12 | } 13 | 14 | // NewGetApplicationCacheForFrameArgs initializes GetApplicationCacheForFrameArgs with the required arguments. 15 | func NewGetApplicationCacheForFrameArgs(frameID page.FrameID) *GetApplicationCacheForFrameArgs { 16 | args := new(GetApplicationCacheForFrameArgs) 17 | args.FrameID = frameID 18 | return args 19 | } 20 | 21 | // GetApplicationCacheForFrameReply represents the return values for GetApplicationCacheForFrame in the ApplicationCache domain. 22 | type GetApplicationCacheForFrameReply struct { 23 | ApplicationCache ApplicationCache `json:"applicationCache"` // Relevant application cache data for the document in given frame. 24 | } 25 | 26 | // GetFramesWithManifestsReply represents the return values for GetFramesWithManifests in the ApplicationCache domain. 27 | type GetFramesWithManifestsReply struct { 28 | FrameIDs []FrameWithManifest `json:"frameIds"` // Array of frame identifiers with manifest urls for each frame containing a document associated with some application cache. 29 | } 30 | 31 | // GetManifestForFrameArgs represents the arguments for GetManifestForFrame in the ApplicationCache domain. 32 | type GetManifestForFrameArgs struct { 33 | FrameID page.FrameID `json:"frameId"` // Identifier of the frame containing document whose manifest is retrieved. 34 | } 35 | 36 | // NewGetManifestForFrameArgs initializes GetManifestForFrameArgs with the required arguments. 37 | func NewGetManifestForFrameArgs(frameID page.FrameID) *GetManifestForFrameArgs { 38 | args := new(GetManifestForFrameArgs) 39 | args.FrameID = frameID 40 | return args 41 | } 42 | 43 | // GetManifestForFrameReply represents the return values for GetManifestForFrame in the ApplicationCache domain. 44 | type GetManifestForFrameReply struct { 45 | ManifestURL string `json:"manifestURL"` // Manifest URL for document in the given frame. 46 | } 47 | -------------------------------------------------------------------------------- /protocol/applicationcache/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package applicationcache 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/page" 7 | "github.com/mafredri/cdp/rpcc" 8 | ) 9 | 10 | // StatusUpdatedClient is a client for ApplicationCacheStatusUpdated events. 11 | type StatusUpdatedClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*StatusUpdatedReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // StatusUpdatedReply is the reply for ApplicationCacheStatusUpdated events. 19 | type StatusUpdatedReply struct { 20 | FrameID page.FrameID `json:"frameId"` // Identifier of the frame containing document whose application cache updated status. 21 | ManifestURL string `json:"manifestURL"` // Manifest URL. 22 | Status int `json:"status"` // Updated application cache status. 23 | } 24 | 25 | // NetworkStateUpdatedClient is a client for NetworkStateUpdated events. 26 | type NetworkStateUpdatedClient interface { 27 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 28 | // triggered, context canceled or connection closed. 29 | Recv() (*NetworkStateUpdatedReply, error) 30 | rpcc.Stream 31 | } 32 | 33 | // NetworkStateUpdatedReply is the reply for NetworkStateUpdated events. 34 | type NetworkStateUpdatedReply struct { 35 | IsNowOnline bool `json:"isNowOnline"` // No description. 36 | } 37 | -------------------------------------------------------------------------------- /protocol/applicationcache/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package applicationcache 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/page" 7 | ) 8 | 9 | // Resource Detailed application cache resource information. 10 | type Resource struct { 11 | URL string `json:"url"` // Resource url. 12 | Size int `json:"size"` // Resource size. 13 | Type string `json:"type"` // Resource type. 14 | } 15 | 16 | // ApplicationCache Detailed application cache information. 17 | type ApplicationCache struct { 18 | ManifestURL string `json:"manifestURL"` // Manifest URL. 19 | Size float64 `json:"size"` // Application cache size. 20 | CreationTime float64 `json:"creationTime"` // Application cache creation time. 21 | UpdateTime float64 `json:"updateTime"` // Application cache update time. 22 | Resources []Resource `json:"resources"` // Application cache resources. 23 | } 24 | 25 | // FrameWithManifest Frame identifier - manifest URL pair. 26 | type FrameWithManifest struct { 27 | FrameID page.FrameID `json:"frameId"` // Frame identifier. 28 | ManifestURL string `json:"manifestURL"` // Manifest URL. 29 | Status int `json:"status"` // Application cache status. 30 | } 31 | -------------------------------------------------------------------------------- /protocol/audits/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package audits 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/network" 7 | ) 8 | 9 | // GetEncodedResponseArgs represents the arguments for GetEncodedResponse in the Audits domain. 10 | type GetEncodedResponseArgs struct { 11 | RequestID network.RequestID `json:"requestId"` // Identifier of the network request to get content for. 12 | // Encoding The encoding to use. 13 | // 14 | // Values: "webp", "jpeg", "png". 15 | Encoding string `json:"encoding"` 16 | Quality *float64 `json:"quality,omitempty"` // The quality of the encoding (0-1). (defaults to 1) 17 | SizeOnly *bool `json:"sizeOnly,omitempty"` // Whether to only return the size information (defaults to false). 18 | } 19 | 20 | // NewGetEncodedResponseArgs initializes GetEncodedResponseArgs with the required arguments. 21 | func NewGetEncodedResponseArgs(requestID network.RequestID, encoding string) *GetEncodedResponseArgs { 22 | args := new(GetEncodedResponseArgs) 23 | args.RequestID = requestID 24 | args.Encoding = encoding 25 | return args 26 | } 27 | 28 | // SetQuality sets the Quality optional argument. The quality of the 29 | // encoding (0-1). (defaults to 1) 30 | func (a *GetEncodedResponseArgs) SetQuality(quality float64) *GetEncodedResponseArgs { 31 | a.Quality = &quality 32 | return a 33 | } 34 | 35 | // SetSizeOnly sets the SizeOnly optional argument. Whether to only 36 | // return the size information (defaults to false). 37 | func (a *GetEncodedResponseArgs) SetSizeOnly(sizeOnly bool) *GetEncodedResponseArgs { 38 | a.SizeOnly = &sizeOnly 39 | return a 40 | } 41 | 42 | // GetEncodedResponseReply represents the return values for GetEncodedResponse in the Audits domain. 43 | type GetEncodedResponseReply struct { 44 | Body []byte `json:"body,omitempty"` // The encoded body as a base64 string. Omitted if sizeOnly is true. (Encoded as a base64 string when passed over JSON) 45 | OriginalSize int `json:"originalSize"` // Size before re-encoding. 46 | EncodedSize int `json:"encodedSize"` // Size after re-encoding. 47 | } 48 | 49 | // CheckContrastArgs represents the arguments for CheckContrast in the Audits domain. 50 | type CheckContrastArgs struct { 51 | ReportAAA *bool `json:"reportAAA,omitempty"` // Whether to report WCAG AAA level issues. Default is false. 52 | } 53 | 54 | // NewCheckContrastArgs initializes CheckContrastArgs with the required arguments. 55 | func NewCheckContrastArgs() *CheckContrastArgs { 56 | args := new(CheckContrastArgs) 57 | 58 | return args 59 | } 60 | 61 | // SetReportAAA sets the ReportAAA optional argument. Whether to 62 | // report WCAG AAA level issues. Default is false. 63 | func (a *CheckContrastArgs) SetReportAAA(reportAAA bool) *CheckContrastArgs { 64 | a.ReportAAA = &reportAAA 65 | return a 66 | } 67 | 68 | // CheckFormsIssuesReply represents the return values for CheckFormsIssues in the Audits domain. 69 | type CheckFormsIssuesReply struct { 70 | FormIssues []GenericIssueDetails `json:"formIssues"` // No description. 71 | } 72 | -------------------------------------------------------------------------------- /protocol/audits/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package audits 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // IssueAddedClient is a client for IssueAdded events. 10 | type IssueAddedClient interface { 11 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 12 | // triggered, context canceled or connection closed. 13 | Recv() (*IssueAddedReply, error) 14 | rpcc.Stream 15 | } 16 | 17 | // IssueAddedReply is the reply for IssueAdded events. 18 | type IssueAddedReply struct { 19 | Issue InspectorIssue `json:"issue"` // No description. 20 | } 21 | -------------------------------------------------------------------------------- /protocol/autofill/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package autofill 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/dom" 7 | "github.com/mafredri/cdp/protocol/page" 8 | ) 9 | 10 | // TriggerArgs represents the arguments for Trigger in the Autofill domain. 11 | type TriggerArgs struct { 12 | FieldID dom.BackendNodeID `json:"fieldId"` // Identifies a field that serves as an anchor for autofill. 13 | FrameID *page.FrameID `json:"frameId,omitempty"` // Identifies the frame that field belongs to. 14 | Card CreditCard `json:"card"` // Credit card information to fill out the form. Credit card data is not saved. 15 | } 16 | 17 | // NewTriggerArgs initializes TriggerArgs with the required arguments. 18 | func NewTriggerArgs(fieldID dom.BackendNodeID, card CreditCard) *TriggerArgs { 19 | args := new(TriggerArgs) 20 | args.FieldID = fieldID 21 | args.Card = card 22 | return args 23 | } 24 | 25 | // SetFrameID sets the FrameID optional argument. Identifies the frame 26 | // that field belongs to. 27 | func (a *TriggerArgs) SetFrameID(frameID page.FrameID) *TriggerArgs { 28 | a.FrameID = &frameID 29 | return a 30 | } 31 | 32 | // SetAddressesArgs represents the arguments for SetAddresses in the Autofill domain. 33 | type SetAddressesArgs struct { 34 | Addresses []Address `json:"addresses"` // No description. 35 | } 36 | 37 | // NewSetAddressesArgs initializes SetAddressesArgs with the required arguments. 38 | func NewSetAddressesArgs(addresses []Address) *SetAddressesArgs { 39 | args := new(SetAddressesArgs) 40 | args.Addresses = addresses 41 | return args 42 | } 43 | -------------------------------------------------------------------------------- /protocol/autofill/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package autofill implements the Autofill domain. Defines commands and 4 | // events for Autofill. 5 | package autofill 6 | 7 | import ( 8 | "context" 9 | 10 | "github.com/mafredri/cdp/protocol/internal" 11 | "github.com/mafredri/cdp/rpcc" 12 | ) 13 | 14 | // domainClient is a client for the Autofill domain. Defines commands and 15 | // events for Autofill. 16 | type domainClient struct{ conn *rpcc.Conn } 17 | 18 | // NewClient returns a client for the Autofill domain with the connection set to conn. 19 | func NewClient(conn *rpcc.Conn) *domainClient { 20 | return &domainClient{conn: conn} 21 | } 22 | 23 | // Trigger invokes the Autofill method. Trigger autofill on a form identified 24 | // by the fieldId. If the field and related form cannot be autofilled, returns 25 | // an error. 26 | func (d *domainClient) Trigger(ctx context.Context, args *TriggerArgs) (err error) { 27 | if args != nil { 28 | err = rpcc.Invoke(ctx, "Autofill.trigger", args, nil, d.conn) 29 | } else { 30 | err = rpcc.Invoke(ctx, "Autofill.trigger", nil, nil, d.conn) 31 | } 32 | if err != nil { 33 | err = &internal.OpError{Domain: "Autofill", Op: "Trigger", Err: err} 34 | } 35 | return 36 | } 37 | 38 | // SetAddresses invokes the Autofill method. Set addresses so that developers 39 | // can verify their forms implementation. 40 | func (d *domainClient) SetAddresses(ctx context.Context, args *SetAddressesArgs) (err error) { 41 | if args != nil { 42 | err = rpcc.Invoke(ctx, "Autofill.setAddresses", args, nil, d.conn) 43 | } else { 44 | err = rpcc.Invoke(ctx, "Autofill.setAddresses", nil, nil, d.conn) 45 | } 46 | if err != nil { 47 | err = &internal.OpError{Domain: "Autofill", Op: "SetAddresses", Err: err} 48 | } 49 | return 50 | } 51 | 52 | // Disable invokes the Autofill method. Disables autofill domain 53 | // notifications. 54 | func (d *domainClient) Disable(ctx context.Context) (err error) { 55 | err = rpcc.Invoke(ctx, "Autofill.disable", nil, nil, d.conn) 56 | if err != nil { 57 | err = &internal.OpError{Domain: "Autofill", Op: "Disable", Err: err} 58 | } 59 | return 60 | } 61 | 62 | // Enable invokes the Autofill method. Enables autofill domain notifications. 63 | func (d *domainClient) Enable(ctx context.Context) (err error) { 64 | err = rpcc.Invoke(ctx, "Autofill.enable", nil, nil, d.conn) 65 | if err != nil { 66 | err = &internal.OpError{Domain: "Autofill", Op: "Enable", Err: err} 67 | } 68 | return 69 | } 70 | 71 | func (d *domainClient) AddressFormFilled(ctx context.Context) (AddressFormFilledClient, error) { 72 | s, err := rpcc.NewStream(ctx, "Autofill.addressFormFilled", d.conn) 73 | if err != nil { 74 | return nil, err 75 | } 76 | return &addressFormFilledClient{Stream: s}, nil 77 | } 78 | 79 | type addressFormFilledClient struct{ rpcc.Stream } 80 | 81 | // GetStream returns the original Stream for use with cdp.Sync. 82 | func (c *addressFormFilledClient) GetStream() rpcc.Stream { return c.Stream } 83 | 84 | func (c *addressFormFilledClient) Recv() (*AddressFormFilledReply, error) { 85 | event := new(AddressFormFilledReply) 86 | if err := c.RecvMsg(event); err != nil { 87 | return nil, &internal.OpError{Domain: "Autofill", Op: "AddressFormFilled Recv", Err: err} 88 | } 89 | return event, nil 90 | } 91 | -------------------------------------------------------------------------------- /protocol/autofill/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package autofill 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // AddressFormFilledClient is a client for AddressFormFilled events. Emitted 10 | // when an address form is filled. 11 | type AddressFormFilledClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*AddressFormFilledReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // AddressFormFilledReply is the reply for AddressFormFilled events. 19 | type AddressFormFilledReply struct { 20 | FilledFields []FilledField `json:"filledFields"` // Information about the fields that were filled 21 | AddressUI AddressUI `json:"addressUi"` // An UI representation of the address used to fill the form. Consists of a 2D array where each child represents an address/profile line. 22 | } 23 | -------------------------------------------------------------------------------- /protocol/backgroundservice/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package backgroundservice 4 | 5 | // StartObservingArgs represents the arguments for StartObserving in the BackgroundService domain. 6 | type StartObservingArgs struct { 7 | Service ServiceName `json:"service"` // No description. 8 | } 9 | 10 | // NewStartObservingArgs initializes StartObservingArgs with the required arguments. 11 | func NewStartObservingArgs(service ServiceName) *StartObservingArgs { 12 | args := new(StartObservingArgs) 13 | args.Service = service 14 | return args 15 | } 16 | 17 | // StopObservingArgs represents the arguments for StopObserving in the BackgroundService domain. 18 | type StopObservingArgs struct { 19 | Service ServiceName `json:"service"` // No description. 20 | } 21 | 22 | // NewStopObservingArgs initializes StopObservingArgs with the required arguments. 23 | func NewStopObservingArgs(service ServiceName) *StopObservingArgs { 24 | args := new(StopObservingArgs) 25 | args.Service = service 26 | return args 27 | } 28 | 29 | // SetRecordingArgs represents the arguments for SetRecording in the BackgroundService domain. 30 | type SetRecordingArgs struct { 31 | ShouldRecord bool `json:"shouldRecord"` // No description. 32 | Service ServiceName `json:"service"` // No description. 33 | } 34 | 35 | // NewSetRecordingArgs initializes SetRecordingArgs with the required arguments. 36 | func NewSetRecordingArgs(shouldRecord bool, service ServiceName) *SetRecordingArgs { 37 | args := new(SetRecordingArgs) 38 | args.ShouldRecord = shouldRecord 39 | args.Service = service 40 | return args 41 | } 42 | 43 | // ClearEventsArgs represents the arguments for ClearEvents in the BackgroundService domain. 44 | type ClearEventsArgs struct { 45 | Service ServiceName `json:"service"` // No description. 46 | } 47 | 48 | // NewClearEventsArgs initializes ClearEventsArgs with the required arguments. 49 | func NewClearEventsArgs(service ServiceName) *ClearEventsArgs { 50 | args := new(ClearEventsArgs) 51 | args.Service = service 52 | return args 53 | } 54 | -------------------------------------------------------------------------------- /protocol/backgroundservice/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package backgroundservice 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // RecordingStateChangedClient is a client for RecordingStateChanged events. 10 | // Called when the recording state for the service has been updated. 11 | type RecordingStateChangedClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*RecordingStateChangedReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // RecordingStateChangedReply is the reply for RecordingStateChanged events. 19 | type RecordingStateChangedReply struct { 20 | IsRecording bool `json:"isRecording"` // No description. 21 | Service ServiceName `json:"service"` // No description. 22 | } 23 | 24 | // EventReceivedClient is a client for BackgroundServiceEventReceived events. 25 | // Called with all existing backgroundServiceEvents when enabled, and all new 26 | // events afterwards if enabled and recording. 27 | type EventReceivedClient interface { 28 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 29 | // triggered, context canceled or connection closed. 30 | Recv() (*EventReceivedReply, error) 31 | rpcc.Stream 32 | } 33 | 34 | // EventReceivedReply is the reply for BackgroundServiceEventReceived events. 35 | type EventReceivedReply struct { 36 | BackgroundServiceEvent Event `json:"backgroundServiceEvent"` // No description. 37 | } 38 | -------------------------------------------------------------------------------- /protocol/backgroundservice/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package backgroundservice 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/network" 7 | "github.com/mafredri/cdp/protocol/serviceworker" 8 | ) 9 | 10 | // ServiceName The Background Service that will be associated with the 11 | // commands/events. Every Background Service operates independently, but they 12 | // share the same API. 13 | type ServiceName string 14 | 15 | // ServiceName as enums. 16 | const ( 17 | ServiceNameNotSet ServiceName = "" 18 | ServiceNameBackgroundFetch ServiceName = "backgroundFetch" 19 | ServiceNameBackgroundSync ServiceName = "backgroundSync" 20 | ServiceNamePushMessaging ServiceName = "pushMessaging" 21 | ServiceNameNotifications ServiceName = "notifications" 22 | ServiceNamePaymentHandler ServiceName = "paymentHandler" 23 | ServiceNamePeriodicBackgroundSync ServiceName = "periodicBackgroundSync" 24 | ) 25 | 26 | func (e ServiceName) Valid() bool { 27 | switch e { 28 | case "backgroundFetch", "backgroundSync", "pushMessaging", "notifications", "paymentHandler", "periodicBackgroundSync": 29 | return true 30 | default: 31 | return false 32 | } 33 | } 34 | 35 | func (e ServiceName) String() string { 36 | return string(e) 37 | } 38 | 39 | // EventMetadata A key-value pair for additional event information to pass 40 | // along. 41 | type EventMetadata struct { 42 | Key string `json:"key"` // No description. 43 | Value string `json:"value"` // No description. 44 | } 45 | 46 | // Event 47 | type Event struct { 48 | Timestamp network.TimeSinceEpoch `json:"timestamp"` // Timestamp of the event (in seconds). 49 | Origin string `json:"origin"` // The origin this event belongs to. 50 | ServiceWorkerRegistrationID serviceworker.RegistrationID `json:"serviceWorkerRegistrationId"` // The Service Worker ID that initiated the event. 51 | Service ServiceName `json:"service"` // The Background Service this event belongs to. 52 | EventName string `json:"eventName"` // A description of the event. 53 | InstanceID string `json:"instanceId"` // An identifier that groups related events together. 54 | EventMetadata []EventMetadata `json:"eventMetadata"` // A list of event-specific information. 55 | StorageKey string `json:"storageKey"` // Storage key this event belongs to. 56 | } 57 | -------------------------------------------------------------------------------- /protocol/bluetoothemulation/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package bluetoothemulation 4 | 5 | // EnableArgs represents the arguments for Enable in the BluetoothEmulation domain. 6 | type EnableArgs struct { 7 | State CentralState `json:"state"` // State of the simulated central. 8 | } 9 | 10 | // NewEnableArgs initializes EnableArgs with the required arguments. 11 | func NewEnableArgs(state CentralState) *EnableArgs { 12 | args := new(EnableArgs) 13 | args.State = state 14 | return args 15 | } 16 | 17 | // SimulatePreconnectedPeripheralArgs represents the arguments for SimulatePreconnectedPeripheral in the BluetoothEmulation domain. 18 | type SimulatePreconnectedPeripheralArgs struct { 19 | Address string `json:"address"` // No description. 20 | Name string `json:"name"` // No description. 21 | ManufacturerData []ManufacturerData `json:"manufacturerData"` // No description. 22 | KnownServiceUUIDs []string `json:"knownServiceUuids"` // No description. 23 | } 24 | 25 | // NewSimulatePreconnectedPeripheralArgs initializes SimulatePreconnectedPeripheralArgs with the required arguments. 26 | func NewSimulatePreconnectedPeripheralArgs(address string, name string, manufacturerData []ManufacturerData, knownServiceUUIDs []string) *SimulatePreconnectedPeripheralArgs { 27 | args := new(SimulatePreconnectedPeripheralArgs) 28 | args.Address = address 29 | args.Name = name 30 | args.ManufacturerData = manufacturerData 31 | args.KnownServiceUUIDs = knownServiceUUIDs 32 | return args 33 | } 34 | 35 | // SimulateAdvertisementArgs represents the arguments for SimulateAdvertisement in the BluetoothEmulation domain. 36 | type SimulateAdvertisementArgs struct { 37 | Entry ScanEntry `json:"entry"` // No description. 38 | } 39 | 40 | // NewSimulateAdvertisementArgs initializes SimulateAdvertisementArgs with the required arguments. 41 | func NewSimulateAdvertisementArgs(entry ScanEntry) *SimulateAdvertisementArgs { 42 | args := new(SimulateAdvertisementArgs) 43 | args.Entry = entry 44 | return args 45 | } 46 | -------------------------------------------------------------------------------- /protocol/bluetoothemulation/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package bluetoothemulation implements the BluetoothEmulation domain. This 4 | // domain allows configuring virtual Bluetooth devices to test the 5 | // web-bluetooth API. 6 | package bluetoothemulation 7 | 8 | import ( 9 | "context" 10 | 11 | "github.com/mafredri/cdp/protocol/internal" 12 | "github.com/mafredri/cdp/rpcc" 13 | ) 14 | 15 | // domainClient is a client for the BluetoothEmulation domain. This domain 16 | // allows configuring virtual Bluetooth devices to test the web-bluetooth API. 17 | type domainClient struct{ conn *rpcc.Conn } 18 | 19 | // NewClient returns a client for the BluetoothEmulation domain with the connection set to conn. 20 | func NewClient(conn *rpcc.Conn) *domainClient { 21 | return &domainClient{conn: conn} 22 | } 23 | 24 | // Enable invokes the BluetoothEmulation method. Enable the BluetoothEmulation 25 | // domain. 26 | func (d *domainClient) Enable(ctx context.Context, args *EnableArgs) (err error) { 27 | if args != nil { 28 | err = rpcc.Invoke(ctx, "BluetoothEmulation.enable", args, nil, d.conn) 29 | } else { 30 | err = rpcc.Invoke(ctx, "BluetoothEmulation.enable", nil, nil, d.conn) 31 | } 32 | if err != nil { 33 | err = &internal.OpError{Domain: "BluetoothEmulation", Op: "Enable", Err: err} 34 | } 35 | return 36 | } 37 | 38 | // Disable invokes the BluetoothEmulation method. Disable the 39 | // BluetoothEmulation domain. 40 | func (d *domainClient) Disable(ctx context.Context) (err error) { 41 | err = rpcc.Invoke(ctx, "BluetoothEmulation.disable", nil, nil, d.conn) 42 | if err != nil { 43 | err = &internal.OpError{Domain: "BluetoothEmulation", Op: "Disable", Err: err} 44 | } 45 | return 46 | } 47 | 48 | // SimulatePreconnectedPeripheral invokes the BluetoothEmulation method. 49 | // Simulates a peripheral with |address|, |name| and |knownServiceUuids| that 50 | // has already been connected to the system. 51 | func (d *domainClient) SimulatePreconnectedPeripheral(ctx context.Context, args *SimulatePreconnectedPeripheralArgs) (err error) { 52 | if args != nil { 53 | err = rpcc.Invoke(ctx, "BluetoothEmulation.simulatePreconnectedPeripheral", args, nil, d.conn) 54 | } else { 55 | err = rpcc.Invoke(ctx, "BluetoothEmulation.simulatePreconnectedPeripheral", nil, nil, d.conn) 56 | } 57 | if err != nil { 58 | err = &internal.OpError{Domain: "BluetoothEmulation", Op: "SimulatePreconnectedPeripheral", Err: err} 59 | } 60 | return 61 | } 62 | 63 | // SimulateAdvertisement invokes the BluetoothEmulation method. Simulates an 64 | // advertisement packet described in |entry| being received by the central. 65 | func (d *domainClient) SimulateAdvertisement(ctx context.Context, args *SimulateAdvertisementArgs) (err error) { 66 | if args != nil { 67 | err = rpcc.Invoke(ctx, "BluetoothEmulation.simulateAdvertisement", args, nil, d.conn) 68 | } else { 69 | err = rpcc.Invoke(ctx, "BluetoothEmulation.simulateAdvertisement", nil, nil, d.conn) 70 | } 71 | if err != nil { 72 | err = &internal.OpError{Domain: "BluetoothEmulation", Op: "SimulateAdvertisement", Err: err} 73 | } 74 | return 75 | } 76 | -------------------------------------------------------------------------------- /protocol/bluetoothemulation/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package bluetoothemulation 4 | 5 | // CentralState Indicates the various states of Central. 6 | type CentralState string 7 | 8 | // CentralState as enums. 9 | const ( 10 | CentralStateNotSet CentralState = "" 11 | CentralStateAbsent CentralState = "absent" 12 | CentralStatePoweredOff CentralState = "powered-off" 13 | CentralStatePoweredOn CentralState = "powered-on" 14 | ) 15 | 16 | func (e CentralState) Valid() bool { 17 | switch e { 18 | case "absent", "powered-off", "powered-on": 19 | return true 20 | default: 21 | return false 22 | } 23 | } 24 | 25 | func (e CentralState) String() string { 26 | return string(e) 27 | } 28 | 29 | // ManufacturerData Stores the manufacturer data 30 | type ManufacturerData struct { 31 | Key int `json:"key"` // Company identifier https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/company_identifiers/company_identifiers.yaml https://usb.org/developers 32 | Data []byte `json:"data"` // Manufacturer-specific data (Encoded as a base64 string when passed over JSON) 33 | } 34 | 35 | // ScanRecord Stores the byte data of the advertisement packet sent by a 36 | // Bluetooth device. 37 | type ScanRecord struct { 38 | Name *string `json:"name,omitempty"` // No description. 39 | UUIDs []string `json:"uuids,omitempty"` // No description. 40 | Appearance *int `json:"appearance,omitempty"` // Stores the external appearance description of the device. 41 | TxPower *int `json:"txPower,omitempty"` // Stores the transmission power of a broadcasting device. 42 | ManufacturerData []ManufacturerData `json:"manufacturerData,omitempty"` // Key is the company identifier and the value is an array of bytes of manufacturer specific data. 43 | } 44 | 45 | // ScanEntry Stores the advertisement packet information that is sent by a 46 | // Bluetooth device. 47 | type ScanEntry struct { 48 | DeviceAddress string `json:"deviceAddress"` // No description. 49 | RSSI int `json:"rssi"` // No description. 50 | ScanRecord ScanRecord `json:"scanRecord"` // No description. 51 | } 52 | -------------------------------------------------------------------------------- /protocol/browser/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package browser 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/page" 7 | "github.com/mafredri/cdp/rpcc" 8 | ) 9 | 10 | // DownloadWillBeginClient is a client for DownloadWillBegin events. Fired 11 | // when page is about to start a download. 12 | type DownloadWillBeginClient interface { 13 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 14 | // triggered, context canceled or connection closed. 15 | Recv() (*DownloadWillBeginReply, error) 16 | rpcc.Stream 17 | } 18 | 19 | // DownloadWillBeginReply is the reply for DownloadWillBegin events. 20 | type DownloadWillBeginReply struct { 21 | FrameID page.FrameID `json:"frameId"` // Id of the frame that caused the download to begin. 22 | GUID string `json:"guid"` // Global unique identifier of the download. 23 | URL string `json:"url"` // URL of the resource being downloaded. 24 | SuggestedFilename string `json:"suggestedFilename"` // Suggested file name of the resource (the actual name of the file saved on disk may differ). 25 | } 26 | 27 | // DownloadProgressClient is a client for DownloadProgress events. Fired when 28 | // download makes progress. Last call has |done| == true. 29 | type DownloadProgressClient interface { 30 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 31 | // triggered, context canceled or connection closed. 32 | Recv() (*DownloadProgressReply, error) 33 | rpcc.Stream 34 | } 35 | 36 | // DownloadProgressReply is the reply for DownloadProgress events. 37 | type DownloadProgressReply struct { 38 | GUID string `json:"guid"` // Global unique identifier of the download. 39 | TotalBytes float64 `json:"totalBytes"` // Total expected bytes to download. 40 | ReceivedBytes float64 `json:"receivedBytes"` // Total bytes received. 41 | // State Download status. 42 | // 43 | // Values: "inProgress", "completed", "canceled". 44 | State string `json:"state"` 45 | } 46 | -------------------------------------------------------------------------------- /protocol/cachestorage/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package cachestorage 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/storage" 7 | ) 8 | 9 | // CacheID Unique identifier of the Cache object. 10 | type CacheID string 11 | 12 | // CachedResponseType type of HTTP response cached 13 | type CachedResponseType string 14 | 15 | // CachedResponseType as enums. 16 | const ( 17 | CachedResponseTypeNotSet CachedResponseType = "" 18 | CachedResponseTypeBasic CachedResponseType = "basic" 19 | CachedResponseTypeCORS CachedResponseType = "cors" 20 | CachedResponseTypeDefault CachedResponseType = "default" 21 | CachedResponseTypeError CachedResponseType = "error" 22 | CachedResponseTypeOpaqueResponse CachedResponseType = "opaqueResponse" 23 | CachedResponseTypeOpaqueRedirect CachedResponseType = "opaqueRedirect" 24 | ) 25 | 26 | func (e CachedResponseType) Valid() bool { 27 | switch e { 28 | case "basic", "cors", "default", "error", "opaqueResponse", "opaqueRedirect": 29 | return true 30 | default: 31 | return false 32 | } 33 | } 34 | 35 | func (e CachedResponseType) String() string { 36 | return string(e) 37 | } 38 | 39 | // DataEntry Data entry. 40 | type DataEntry struct { 41 | RequestURL string `json:"requestURL"` // Request URL. 42 | RequestMethod string `json:"requestMethod"` // Request method. 43 | RequestHeaders []Header `json:"requestHeaders"` // Request headers 44 | ResponseTime float64 `json:"responseTime"` // Number of seconds since epoch. 45 | ResponseStatus int `json:"responseStatus"` // HTTP response status code. 46 | ResponseStatusText string `json:"responseStatusText"` // HTTP response status text. 47 | ResponseType CachedResponseType `json:"responseType"` // HTTP response type 48 | ResponseHeaders []Header `json:"responseHeaders"` // Response headers 49 | } 50 | 51 | // Cache Cache identifier. 52 | type Cache struct { 53 | CacheID CacheID `json:"cacheId"` // An opaque unique id of the cache. 54 | SecurityOrigin string `json:"securityOrigin"` // Security origin of the cache. 55 | StorageKey string `json:"storageKey"` // Storage key of the cache. 56 | StorageBucket *storage.Bucket `json:"storageBucket,omitempty"` // Storage bucket of the cache. 57 | CacheName string `json:"cacheName"` // The name of the cache. 58 | } 59 | 60 | // Header 61 | type Header struct { 62 | Name string `json:"name"` // No description. 63 | Value string `json:"value"` // No description. 64 | } 65 | 66 | // CachedResponse Cached response 67 | type CachedResponse struct { 68 | Body []byte `json:"body"` // Entry content, base64-encoded. (Encoded as a base64 string when passed over JSON) 69 | } 70 | -------------------------------------------------------------------------------- /protocol/cast/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package cast 4 | 5 | // EnableArgs represents the arguments for Enable in the Cast domain. 6 | type EnableArgs struct { 7 | PresentationURL *string `json:"presentationUrl,omitempty"` // No description. 8 | } 9 | 10 | // NewEnableArgs initializes EnableArgs with the required arguments. 11 | func NewEnableArgs() *EnableArgs { 12 | args := new(EnableArgs) 13 | 14 | return args 15 | } 16 | 17 | // SetPresentationURL sets the PresentationURL optional argument. 18 | func (a *EnableArgs) SetPresentationURL(presentationURL string) *EnableArgs { 19 | a.PresentationURL = &presentationURL 20 | return a 21 | } 22 | 23 | // SetSinkToUseArgs represents the arguments for SetSinkToUse in the Cast domain. 24 | type SetSinkToUseArgs struct { 25 | SinkName string `json:"sinkName"` // No description. 26 | } 27 | 28 | // NewSetSinkToUseArgs initializes SetSinkToUseArgs with the required arguments. 29 | func NewSetSinkToUseArgs(sinkName string) *SetSinkToUseArgs { 30 | args := new(SetSinkToUseArgs) 31 | args.SinkName = sinkName 32 | return args 33 | } 34 | 35 | // StartDesktopMirroringArgs represents the arguments for StartDesktopMirroring in the Cast domain. 36 | type StartDesktopMirroringArgs struct { 37 | SinkName string `json:"sinkName"` // No description. 38 | } 39 | 40 | // NewStartDesktopMirroringArgs initializes StartDesktopMirroringArgs with the required arguments. 41 | func NewStartDesktopMirroringArgs(sinkName string) *StartDesktopMirroringArgs { 42 | args := new(StartDesktopMirroringArgs) 43 | args.SinkName = sinkName 44 | return args 45 | } 46 | 47 | // StartTabMirroringArgs represents the arguments for StartTabMirroring in the Cast domain. 48 | type StartTabMirroringArgs struct { 49 | SinkName string `json:"sinkName"` // No description. 50 | } 51 | 52 | // NewStartTabMirroringArgs initializes StartTabMirroringArgs with the required arguments. 53 | func NewStartTabMirroringArgs(sinkName string) *StartTabMirroringArgs { 54 | args := new(StartTabMirroringArgs) 55 | args.SinkName = sinkName 56 | return args 57 | } 58 | 59 | // StopCastingArgs represents the arguments for StopCasting in the Cast domain. 60 | type StopCastingArgs struct { 61 | SinkName string `json:"sinkName"` // No description. 62 | } 63 | 64 | // NewStopCastingArgs initializes StopCastingArgs with the required arguments. 65 | func NewStopCastingArgs(sinkName string) *StopCastingArgs { 66 | args := new(StopCastingArgs) 67 | args.SinkName = sinkName 68 | return args 69 | } 70 | -------------------------------------------------------------------------------- /protocol/cast/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package cast 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // SinksUpdatedClient is a client for SinksUpdated events. This is fired 10 | // whenever the list of available sinks changes. A sink is a device or a 11 | // software surface that you can cast to. 12 | type SinksUpdatedClient interface { 13 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 14 | // triggered, context canceled or connection closed. 15 | Recv() (*SinksUpdatedReply, error) 16 | rpcc.Stream 17 | } 18 | 19 | // SinksUpdatedReply is the reply for SinksUpdated events. 20 | type SinksUpdatedReply struct { 21 | Sinks []Sink `json:"sinks"` // No description. 22 | } 23 | 24 | // IssueUpdatedClient is a client for IssueUpdated events. This is fired 25 | // whenever the outstanding issue/error message changes. |issueMessage| is 26 | // empty if there is no issue. 27 | type IssueUpdatedClient interface { 28 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 29 | // triggered, context canceled or connection closed. 30 | Recv() (*IssueUpdatedReply, error) 31 | rpcc.Stream 32 | } 33 | 34 | // IssueUpdatedReply is the reply for IssueUpdated events. 35 | type IssueUpdatedReply struct { 36 | IssueMessage string `json:"issueMessage"` // No description. 37 | } 38 | -------------------------------------------------------------------------------- /protocol/cast/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package cast 4 | 5 | // Sink 6 | type Sink struct { 7 | Name string `json:"name"` // No description. 8 | ID string `json:"id"` // No description. 9 | Session *string `json:"session,omitempty"` // Text describing the current session. Present only if there is an active session on the sink. 10 | } 11 | -------------------------------------------------------------------------------- /protocol/console/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package console implements the Console domain. This domain is deprecated - 4 | // use Runtime or Log instead. 5 | package console 6 | 7 | import ( 8 | "context" 9 | 10 | "github.com/mafredri/cdp/protocol/internal" 11 | "github.com/mafredri/cdp/rpcc" 12 | ) 13 | 14 | // domainClient is a client for the Console domain. This domain is deprecated 15 | // - use Runtime or Log instead. 16 | type domainClient struct{ conn *rpcc.Conn } 17 | 18 | // NewClient returns a client for the Console domain with the connection set to conn. 19 | func NewClient(conn *rpcc.Conn) *domainClient { 20 | return &domainClient{conn: conn} 21 | } 22 | 23 | // ClearMessages invokes the Console method. Does nothing. 24 | func (d *domainClient) ClearMessages(ctx context.Context) (err error) { 25 | err = rpcc.Invoke(ctx, "Console.clearMessages", nil, nil, d.conn) 26 | if err != nil { 27 | err = &internal.OpError{Domain: "Console", Op: "ClearMessages", Err: err} 28 | } 29 | return 30 | } 31 | 32 | // Disable invokes the Console method. Disables console domain, prevents 33 | // further console messages from being reported to the client. 34 | func (d *domainClient) Disable(ctx context.Context) (err error) { 35 | err = rpcc.Invoke(ctx, "Console.disable", nil, nil, d.conn) 36 | if err != nil { 37 | err = &internal.OpError{Domain: "Console", Op: "Disable", Err: err} 38 | } 39 | return 40 | } 41 | 42 | // Enable invokes the Console method. Enables console domain, sends the 43 | // messages collected so far to the client by means of the `messageAdded` 44 | // notification. 45 | func (d *domainClient) Enable(ctx context.Context) (err error) { 46 | err = rpcc.Invoke(ctx, "Console.enable", nil, nil, d.conn) 47 | if err != nil { 48 | err = &internal.OpError{Domain: "Console", Op: "Enable", Err: err} 49 | } 50 | return 51 | } 52 | 53 | func (d *domainClient) MessageAdded(ctx context.Context) (MessageAddedClient, error) { 54 | s, err := rpcc.NewStream(ctx, "Console.messageAdded", d.conn) 55 | if err != nil { 56 | return nil, err 57 | } 58 | return &messageAddedClient{Stream: s}, nil 59 | } 60 | 61 | type messageAddedClient struct{ rpcc.Stream } 62 | 63 | // GetStream returns the original Stream for use with cdp.Sync. 64 | func (c *messageAddedClient) GetStream() rpcc.Stream { return c.Stream } 65 | 66 | func (c *messageAddedClient) Recv() (*MessageAddedReply, error) { 67 | event := new(MessageAddedReply) 68 | if err := c.RecvMsg(event); err != nil { 69 | return nil, &internal.OpError{Domain: "Console", Op: "MessageAdded Recv", Err: err} 70 | } 71 | return event, nil 72 | } 73 | -------------------------------------------------------------------------------- /protocol/console/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package console 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // MessageAddedClient is a client for MessageAdded events. Issued when new 10 | // console message is added. 11 | type MessageAddedClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*MessageAddedReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // MessageAddedReply is the reply for MessageAdded events. 19 | type MessageAddedReply struct { 20 | Message Message `json:"message"` // Console message that has been added. 21 | } 22 | -------------------------------------------------------------------------------- /protocol/console/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package console 4 | 5 | // Message Console message. 6 | type Message struct { 7 | // Source Message source. 8 | // 9 | // Values: "xml", "javascript", "network", "console-api", "storage", "appcache", "rendering", "security", "other", "deprecation", "worker". 10 | Source string `json:"source"` 11 | // Level Message severity. 12 | // 13 | // Values: "log", "warning", "error", "debug", "info". 14 | Level string `json:"level"` 15 | Text string `json:"text"` // Message text. 16 | URL *string `json:"url,omitempty"` // URL of the message origin. 17 | Line *int `json:"line,omitempty"` // Line number in the resource that generated this message (1-based). 18 | Column *int `json:"column,omitempty"` // Column number in the resource that generated this message (1-based). 19 | } 20 | -------------------------------------------------------------------------------- /protocol/css/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package css 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // FontsUpdatedClient is a client for FontsUpdated events. Fires whenever a 10 | // web font is updated. A non-empty font parameter indicates a successfully 11 | // loaded web font. 12 | type FontsUpdatedClient interface { 13 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 14 | // triggered, context canceled or connection closed. 15 | Recv() (*FontsUpdatedReply, error) 16 | rpcc.Stream 17 | } 18 | 19 | // FontsUpdatedReply is the reply for FontsUpdated events. 20 | type FontsUpdatedReply struct { 21 | Font *FontFace `json:"font,omitempty"` // The web font that has loaded. 22 | } 23 | 24 | // MediaQueryResultChangedClient is a client for MediaQueryResultChanged events. 25 | // Fires whenever a MediaQuery result changes (for example, after a browser 26 | // window has been resized.) The current implementation considers only 27 | // viewport-dependent media features. 28 | type MediaQueryResultChangedClient interface { 29 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 30 | // triggered, context canceled or connection closed. 31 | Recv() (*MediaQueryResultChangedReply, error) 32 | rpcc.Stream 33 | } 34 | 35 | // MediaQueryResultChangedReply is the reply for MediaQueryResultChanged events. 36 | type MediaQueryResultChangedReply struct { 37 | } 38 | 39 | // StyleSheetAddedClient is a client for StyleSheetAdded events. Fired 40 | // whenever an active document stylesheet is added. 41 | type StyleSheetAddedClient interface { 42 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 43 | // triggered, context canceled or connection closed. 44 | Recv() (*StyleSheetAddedReply, error) 45 | rpcc.Stream 46 | } 47 | 48 | // StyleSheetAddedReply is the reply for StyleSheetAdded events. 49 | type StyleSheetAddedReply struct { 50 | Header StyleSheetHeader `json:"header"` // Added stylesheet metainfo. 51 | } 52 | 53 | // StyleSheetChangedClient is a client for StyleSheetChanged events. Fired 54 | // whenever a stylesheet is changed as a result of the client operation. 55 | type StyleSheetChangedClient interface { 56 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 57 | // triggered, context canceled or connection closed. 58 | Recv() (*StyleSheetChangedReply, error) 59 | rpcc.Stream 60 | } 61 | 62 | // StyleSheetChangedReply is the reply for StyleSheetChanged events. 63 | type StyleSheetChangedReply struct { 64 | StyleSheetID StyleSheetID `json:"styleSheetId"` // No description. 65 | } 66 | 67 | // StyleSheetRemovedClient is a client for StyleSheetRemoved events. Fired 68 | // whenever an active document stylesheet is removed. 69 | type StyleSheetRemovedClient interface { 70 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 71 | // triggered, context canceled or connection closed. 72 | Recv() (*StyleSheetRemovedReply, error) 73 | rpcc.Stream 74 | } 75 | 76 | // StyleSheetRemovedReply is the reply for StyleSheetRemoved events. 77 | type StyleSheetRemovedReply struct { 78 | StyleSheetID StyleSheetID `json:"styleSheetId"` // Identifier of the removed stylesheet. 79 | } 80 | -------------------------------------------------------------------------------- /protocol/database/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package database 4 | 5 | import ( 6 | "encoding/json" 7 | ) 8 | 9 | // ExecuteSQLArgs represents the arguments for ExecuteSQL in the Database domain. 10 | type ExecuteSQLArgs struct { 11 | DatabaseID ID `json:"databaseId"` // No description. 12 | Query string `json:"query"` // No description. 13 | } 14 | 15 | // NewExecuteSQLArgs initializes ExecuteSQLArgs with the required arguments. 16 | func NewExecuteSQLArgs(databaseID ID, query string) *ExecuteSQLArgs { 17 | args := new(ExecuteSQLArgs) 18 | args.DatabaseID = databaseID 19 | args.Query = query 20 | return args 21 | } 22 | 23 | // ExecuteSQLReply represents the return values for ExecuteSQL in the Database domain. 24 | type ExecuteSQLReply struct { 25 | ColumnNames []string `json:"columnNames,omitempty"` // No description. 26 | Values []json.RawMessage `json:"values,omitempty"` // No description. 27 | SQLError *Error `json:"sqlError,omitempty"` // No description. 28 | } 29 | 30 | // GetDatabaseTableNamesArgs represents the arguments for GetDatabaseTableNames in the Database domain. 31 | type GetDatabaseTableNamesArgs struct { 32 | DatabaseID ID `json:"databaseId"` // No description. 33 | } 34 | 35 | // NewGetDatabaseTableNamesArgs initializes GetDatabaseTableNamesArgs with the required arguments. 36 | func NewGetDatabaseTableNamesArgs(databaseID ID) *GetDatabaseTableNamesArgs { 37 | args := new(GetDatabaseTableNamesArgs) 38 | args.DatabaseID = databaseID 39 | return args 40 | } 41 | 42 | // GetDatabaseTableNamesReply represents the return values for GetDatabaseTableNames in the Database domain. 43 | type GetDatabaseTableNamesReply struct { 44 | TableNames []string `json:"tableNames"` // No description. 45 | } 46 | -------------------------------------------------------------------------------- /protocol/database/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package database implements the Database domain. 4 | package database 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/mafredri/cdp/protocol/internal" 10 | "github.com/mafredri/cdp/rpcc" 11 | ) 12 | 13 | // domainClient is a client for the Database domain. 14 | type domainClient struct{ conn *rpcc.Conn } 15 | 16 | // NewClient returns a client for the Database domain with the connection set to conn. 17 | func NewClient(conn *rpcc.Conn) *domainClient { 18 | return &domainClient{conn: conn} 19 | } 20 | 21 | // Disable invokes the Database method. Disables database tracking, prevents 22 | // database events from being sent to the client. 23 | func (d *domainClient) Disable(ctx context.Context) (err error) { 24 | err = rpcc.Invoke(ctx, "Database.disable", nil, nil, d.conn) 25 | if err != nil { 26 | err = &internal.OpError{Domain: "Database", Op: "Disable", Err: err} 27 | } 28 | return 29 | } 30 | 31 | // Enable invokes the Database method. Enables database tracking, database 32 | // events will now be delivered to the client. 33 | func (d *domainClient) Enable(ctx context.Context) (err error) { 34 | err = rpcc.Invoke(ctx, "Database.enable", nil, nil, d.conn) 35 | if err != nil { 36 | err = &internal.OpError{Domain: "Database", Op: "Enable", Err: err} 37 | } 38 | return 39 | } 40 | 41 | // ExecuteSQL invokes the Database method. 42 | func (d *domainClient) ExecuteSQL(ctx context.Context, args *ExecuteSQLArgs) (reply *ExecuteSQLReply, err error) { 43 | reply = new(ExecuteSQLReply) 44 | if args != nil { 45 | err = rpcc.Invoke(ctx, "Database.executeSQL", args, reply, d.conn) 46 | } else { 47 | err = rpcc.Invoke(ctx, "Database.executeSQL", nil, reply, d.conn) 48 | } 49 | if err != nil { 50 | err = &internal.OpError{Domain: "Database", Op: "ExecuteSQL", Err: err} 51 | } 52 | return 53 | } 54 | 55 | // GetDatabaseTableNames invokes the Database method. 56 | func (d *domainClient) GetDatabaseTableNames(ctx context.Context, args *GetDatabaseTableNamesArgs) (reply *GetDatabaseTableNamesReply, err error) { 57 | reply = new(GetDatabaseTableNamesReply) 58 | if args != nil { 59 | err = rpcc.Invoke(ctx, "Database.getDatabaseTableNames", args, reply, d.conn) 60 | } else { 61 | err = rpcc.Invoke(ctx, "Database.getDatabaseTableNames", nil, reply, d.conn) 62 | } 63 | if err != nil { 64 | err = &internal.OpError{Domain: "Database", Op: "GetDatabaseTableNames", Err: err} 65 | } 66 | return 67 | } 68 | 69 | func (d *domainClient) AddDatabase(ctx context.Context) (AddDatabaseClient, error) { 70 | s, err := rpcc.NewStream(ctx, "Database.addDatabase", d.conn) 71 | if err != nil { 72 | return nil, err 73 | } 74 | return &addDatabaseClient{Stream: s}, nil 75 | } 76 | 77 | type addDatabaseClient struct{ rpcc.Stream } 78 | 79 | // GetStream returns the original Stream for use with cdp.Sync. 80 | func (c *addDatabaseClient) GetStream() rpcc.Stream { return c.Stream } 81 | 82 | func (c *addDatabaseClient) Recv() (*AddDatabaseReply, error) { 83 | event := new(AddDatabaseReply) 84 | if err := c.RecvMsg(event); err != nil { 85 | return nil, &internal.OpError{Domain: "Database", Op: "AddDatabase Recv", Err: err} 86 | } 87 | return event, nil 88 | } 89 | -------------------------------------------------------------------------------- /protocol/database/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package database 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // AddDatabaseClient is a client for AddDatabase events. 10 | type AddDatabaseClient interface { 11 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 12 | // triggered, context canceled or connection closed. 13 | Recv() (*AddDatabaseReply, error) 14 | rpcc.Stream 15 | } 16 | 17 | // AddDatabaseReply is the reply for AddDatabase events. 18 | type AddDatabaseReply struct { 19 | Database Database `json:"database"` // No description. 20 | } 21 | -------------------------------------------------------------------------------- /protocol/database/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package database 4 | 5 | // ID Unique identifier of Database object. 6 | type ID string 7 | 8 | // Database Database object. 9 | type Database struct { 10 | ID ID `json:"id"` // Database ID. 11 | Domain string `json:"domain"` // Database domain. 12 | Name string `json:"name"` // Database name. 13 | Version string `json:"version"` // Database version. 14 | } 15 | 16 | // Error Database error. 17 | type Error struct { 18 | Message string `json:"message"` // Error message. 19 | Code int `json:"code"` // Error code. 20 | } 21 | -------------------------------------------------------------------------------- /protocol/deviceaccess/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package deviceaccess 4 | 5 | // SelectPromptArgs represents the arguments for SelectPrompt in the DeviceAccess domain. 6 | type SelectPromptArgs struct { 7 | ID RequestID `json:"id"` // No description. 8 | DeviceID DeviceID `json:"deviceId"` // No description. 9 | } 10 | 11 | // NewSelectPromptArgs initializes SelectPromptArgs with the required arguments. 12 | func NewSelectPromptArgs(id RequestID, deviceID DeviceID) *SelectPromptArgs { 13 | args := new(SelectPromptArgs) 14 | args.ID = id 15 | args.DeviceID = deviceID 16 | return args 17 | } 18 | 19 | // CancelPromptArgs represents the arguments for CancelPrompt in the DeviceAccess domain. 20 | type CancelPromptArgs struct { 21 | ID RequestID `json:"id"` // No description. 22 | } 23 | 24 | // NewCancelPromptArgs initializes CancelPromptArgs with the required arguments. 25 | func NewCancelPromptArgs(id RequestID) *CancelPromptArgs { 26 | args := new(CancelPromptArgs) 27 | args.ID = id 28 | return args 29 | } 30 | -------------------------------------------------------------------------------- /protocol/deviceaccess/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package deviceaccess implements the DeviceAccess domain. 4 | package deviceaccess 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/mafredri/cdp/protocol/internal" 10 | "github.com/mafredri/cdp/rpcc" 11 | ) 12 | 13 | // domainClient is a client for the DeviceAccess domain. 14 | type domainClient struct{ conn *rpcc.Conn } 15 | 16 | // NewClient returns a client for the DeviceAccess domain with the connection set to conn. 17 | func NewClient(conn *rpcc.Conn) *domainClient { 18 | return &domainClient{conn: conn} 19 | } 20 | 21 | // Enable invokes the DeviceAccess method. Enable events in this domain. 22 | func (d *domainClient) Enable(ctx context.Context) (err error) { 23 | err = rpcc.Invoke(ctx, "DeviceAccess.enable", nil, nil, d.conn) 24 | if err != nil { 25 | err = &internal.OpError{Domain: "DeviceAccess", Op: "Enable", Err: err} 26 | } 27 | return 28 | } 29 | 30 | // Disable invokes the DeviceAccess method. Disable events in this domain. 31 | func (d *domainClient) Disable(ctx context.Context) (err error) { 32 | err = rpcc.Invoke(ctx, "DeviceAccess.disable", nil, nil, d.conn) 33 | if err != nil { 34 | err = &internal.OpError{Domain: "DeviceAccess", Op: "Disable", Err: err} 35 | } 36 | return 37 | } 38 | 39 | // SelectPrompt invokes the DeviceAccess method. Select a device in response 40 | // to a DeviceAccess.deviceRequestPrompted event. 41 | func (d *domainClient) SelectPrompt(ctx context.Context, args *SelectPromptArgs) (err error) { 42 | if args != nil { 43 | err = rpcc.Invoke(ctx, "DeviceAccess.selectPrompt", args, nil, d.conn) 44 | } else { 45 | err = rpcc.Invoke(ctx, "DeviceAccess.selectPrompt", nil, nil, d.conn) 46 | } 47 | if err != nil { 48 | err = &internal.OpError{Domain: "DeviceAccess", Op: "SelectPrompt", Err: err} 49 | } 50 | return 51 | } 52 | 53 | // CancelPrompt invokes the DeviceAccess method. Cancel a prompt in response 54 | // to a DeviceAccess.deviceRequestPrompted event. 55 | func (d *domainClient) CancelPrompt(ctx context.Context, args *CancelPromptArgs) (err error) { 56 | if args != nil { 57 | err = rpcc.Invoke(ctx, "DeviceAccess.cancelPrompt", args, nil, d.conn) 58 | } else { 59 | err = rpcc.Invoke(ctx, "DeviceAccess.cancelPrompt", nil, nil, d.conn) 60 | } 61 | if err != nil { 62 | err = &internal.OpError{Domain: "DeviceAccess", Op: "CancelPrompt", Err: err} 63 | } 64 | return 65 | } 66 | 67 | func (d *domainClient) DeviceRequestPrompted(ctx context.Context) (DeviceRequestPromptedClient, error) { 68 | s, err := rpcc.NewStream(ctx, "DeviceAccess.deviceRequestPrompted", d.conn) 69 | if err != nil { 70 | return nil, err 71 | } 72 | return &deviceRequestPromptedClient{Stream: s}, nil 73 | } 74 | 75 | type deviceRequestPromptedClient struct{ rpcc.Stream } 76 | 77 | // GetStream returns the original Stream for use with cdp.Sync. 78 | func (c *deviceRequestPromptedClient) GetStream() rpcc.Stream { return c.Stream } 79 | 80 | func (c *deviceRequestPromptedClient) Recv() (*DeviceRequestPromptedReply, error) { 81 | event := new(DeviceRequestPromptedReply) 82 | if err := c.RecvMsg(event); err != nil { 83 | return nil, &internal.OpError{Domain: "DeviceAccess", Op: "DeviceRequestPrompted Recv", Err: err} 84 | } 85 | return event, nil 86 | } 87 | -------------------------------------------------------------------------------- /protocol/deviceaccess/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package deviceaccess 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // DeviceRequestPromptedClient is a client for DeviceRequestPrompted events. A 10 | // device request opened a user prompt to select a device. Respond with the 11 | // selectPrompt or cancelPrompt command. 12 | type DeviceRequestPromptedClient interface { 13 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 14 | // triggered, context canceled or connection closed. 15 | Recv() (*DeviceRequestPromptedReply, error) 16 | rpcc.Stream 17 | } 18 | 19 | // DeviceRequestPromptedReply is the reply for DeviceRequestPrompted events. 20 | type DeviceRequestPromptedReply struct { 21 | ID RequestID `json:"id"` // No description. 22 | Devices []PromptDevice `json:"devices"` // No description. 23 | } 24 | -------------------------------------------------------------------------------- /protocol/deviceaccess/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package deviceaccess 4 | 5 | // RequestID Device request id. 6 | type RequestID string 7 | 8 | // DeviceID A device id. 9 | type DeviceID string 10 | 11 | // PromptDevice Device information displayed in a user prompt to select a 12 | // device. 13 | type PromptDevice struct { 14 | ID DeviceID `json:"id"` // No description. 15 | Name string `json:"name"` // Display name as it appears in a device request user prompt. 16 | } 17 | -------------------------------------------------------------------------------- /protocol/deviceorientation/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package deviceorientation 4 | 5 | // SetDeviceOrientationOverrideArgs represents the arguments for SetDeviceOrientationOverride in the DeviceOrientation domain. 6 | type SetDeviceOrientationOverrideArgs struct { 7 | Alpha float64 `json:"alpha"` // Mock alpha 8 | Beta float64 `json:"beta"` // Mock beta 9 | Gamma float64 `json:"gamma"` // Mock gamma 10 | } 11 | 12 | // NewSetDeviceOrientationOverrideArgs initializes SetDeviceOrientationOverrideArgs with the required arguments. 13 | func NewSetDeviceOrientationOverrideArgs(alpha float64, beta float64, gamma float64) *SetDeviceOrientationOverrideArgs { 14 | args := new(SetDeviceOrientationOverrideArgs) 15 | args.Alpha = alpha 16 | args.Beta = beta 17 | args.Gamma = gamma 18 | return args 19 | } 20 | -------------------------------------------------------------------------------- /protocol/deviceorientation/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package deviceorientation implements the DeviceOrientation domain. 4 | package deviceorientation 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/mafredri/cdp/protocol/internal" 10 | "github.com/mafredri/cdp/rpcc" 11 | ) 12 | 13 | // domainClient is a client for the DeviceOrientation domain. 14 | type domainClient struct{ conn *rpcc.Conn } 15 | 16 | // NewClient returns a client for the DeviceOrientation domain with the connection set to conn. 17 | func NewClient(conn *rpcc.Conn) *domainClient { 18 | return &domainClient{conn: conn} 19 | } 20 | 21 | // ClearDeviceOrientationOverride invokes the DeviceOrientation method. Clears 22 | // the overridden Device Orientation. 23 | func (d *domainClient) ClearDeviceOrientationOverride(ctx context.Context) (err error) { 24 | err = rpcc.Invoke(ctx, "DeviceOrientation.clearDeviceOrientationOverride", nil, nil, d.conn) 25 | if err != nil { 26 | err = &internal.OpError{Domain: "DeviceOrientation", Op: "ClearDeviceOrientationOverride", Err: err} 27 | } 28 | return 29 | } 30 | 31 | // SetDeviceOrientationOverride invokes the DeviceOrientation method. 32 | // Overrides the Device Orientation. 33 | func (d *domainClient) SetDeviceOrientationOverride(ctx context.Context, args *SetDeviceOrientationOverrideArgs) (err error) { 34 | if args != nil { 35 | err = rpcc.Invoke(ctx, "DeviceOrientation.setDeviceOrientationOverride", args, nil, d.conn) 36 | } else { 37 | err = rpcc.Invoke(ctx, "DeviceOrientation.setDeviceOrientationOverride", nil, nil, d.conn) 38 | } 39 | if err != nil { 40 | err = &internal.OpError{Domain: "DeviceOrientation", Op: "SetDeviceOrientationOverride", Err: err} 41 | } 42 | return 43 | } 44 | -------------------------------------------------------------------------------- /protocol/doc.go: -------------------------------------------------------------------------------- 1 | // Package protocol contains subpackages representing all domains for 2 | // the Chrome DevTools Protocol. 3 | // 4 | // This package also contains some types shared between the subpackages. 5 | package protocol 6 | -------------------------------------------------------------------------------- /protocol/domdebugger/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package domdebugger 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/dom" 7 | "github.com/mafredri/cdp/protocol/runtime" 8 | ) 9 | 10 | // DOMBreakpointType DOM breakpoint type. 11 | type DOMBreakpointType string 12 | 13 | // DOMBreakpointType as enums. 14 | const ( 15 | DOMBreakpointTypeNotSet DOMBreakpointType = "" 16 | DOMBreakpointTypeSubtreeModified DOMBreakpointType = "subtree-modified" 17 | DOMBreakpointTypeAttributeModified DOMBreakpointType = "attribute-modified" 18 | DOMBreakpointTypeNodeRemoved DOMBreakpointType = "node-removed" 19 | ) 20 | 21 | func (e DOMBreakpointType) Valid() bool { 22 | switch e { 23 | case "subtree-modified", "attribute-modified", "node-removed": 24 | return true 25 | default: 26 | return false 27 | } 28 | } 29 | 30 | func (e DOMBreakpointType) String() string { 31 | return string(e) 32 | } 33 | 34 | // CSPViolationType CSP Violation type. 35 | // 36 | // Note: This type is experimental. 37 | type CSPViolationType string 38 | 39 | // CSPViolationType as enums. 40 | const ( 41 | CSPViolationTypeNotSet CSPViolationType = "" 42 | CSPViolationTypeTrustedtypeSinkViolation CSPViolationType = "trustedtype-sink-violation" 43 | CSPViolationTypeTrustedtypePolicyViolation CSPViolationType = "trustedtype-policy-violation" 44 | ) 45 | 46 | func (e CSPViolationType) Valid() bool { 47 | switch e { 48 | case "trustedtype-sink-violation", "trustedtype-policy-violation": 49 | return true 50 | default: 51 | return false 52 | } 53 | } 54 | 55 | func (e CSPViolationType) String() string { 56 | return string(e) 57 | } 58 | 59 | // EventListener Object event listener. 60 | type EventListener struct { 61 | Type string `json:"type"` // `EventListener`'s type. 62 | UseCapture bool `json:"useCapture"` // `EventListener`'s useCapture. 63 | Passive bool `json:"passive"` // `EventListener`'s passive flag. 64 | Once bool `json:"once"` // `EventListener`'s once flag. 65 | ScriptID runtime.ScriptID `json:"scriptId"` // Script id of the handler code. 66 | LineNumber int `json:"lineNumber"` // Line number in the script (0-based). 67 | ColumnNumber int `json:"columnNumber"` // Column number in the script (0-based). 68 | Handler *runtime.RemoteObject `json:"handler,omitempty"` // Event handler function value. 69 | OriginalHandler *runtime.RemoteObject `json:"originalHandler,omitempty"` // Event original handler function value. 70 | BackendNodeID *dom.BackendNodeID `json:"backendNodeId,omitempty"` // Node the listener is added to (if any). 71 | } 72 | -------------------------------------------------------------------------------- /protocol/domsnapshot/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package domsnapshot implements the DOMSnapshot domain. This domain 4 | // facilitates obtaining document snapshots with DOM, layout, and style 5 | // information. 6 | package domsnapshot 7 | 8 | import ( 9 | "context" 10 | 11 | "github.com/mafredri/cdp/protocol/internal" 12 | "github.com/mafredri/cdp/rpcc" 13 | ) 14 | 15 | // domainClient is a client for the DOMSnapshot domain. This domain 16 | // facilitates obtaining document snapshots with DOM, layout, and style 17 | // information. 18 | type domainClient struct{ conn *rpcc.Conn } 19 | 20 | // NewClient returns a client for the DOMSnapshot domain with the connection set to conn. 21 | func NewClient(conn *rpcc.Conn) *domainClient { 22 | return &domainClient{conn: conn} 23 | } 24 | 25 | // Disable invokes the DOMSnapshot method. Disables DOM snapshot agent for the 26 | // given page. 27 | func (d *domainClient) Disable(ctx context.Context) (err error) { 28 | err = rpcc.Invoke(ctx, "DOMSnapshot.disable", nil, nil, d.conn) 29 | if err != nil { 30 | err = &internal.OpError{Domain: "DOMSnapshot", Op: "Disable", Err: err} 31 | } 32 | return 33 | } 34 | 35 | // Enable invokes the DOMSnapshot method. Enables DOM snapshot agent for the 36 | // given page. 37 | func (d *domainClient) Enable(ctx context.Context) (err error) { 38 | err = rpcc.Invoke(ctx, "DOMSnapshot.enable", nil, nil, d.conn) 39 | if err != nil { 40 | err = &internal.OpError{Domain: "DOMSnapshot", Op: "Enable", Err: err} 41 | } 42 | return 43 | } 44 | 45 | // GetSnapshot invokes the DOMSnapshot method. Returns a document snapshot, 46 | // including the full DOM tree of the root node (including iframes, template 47 | // contents, and imported documents) in a flattened array, as well as layout 48 | // and white-listed computed style information for the nodes. Shadow DOM in the 49 | // returned DOM tree is flattened. 50 | func (d *domainClient) GetSnapshot(ctx context.Context, args *GetSnapshotArgs) (reply *GetSnapshotReply, err error) { 51 | reply = new(GetSnapshotReply) 52 | if args != nil { 53 | err = rpcc.Invoke(ctx, "DOMSnapshot.getSnapshot", args, reply, d.conn) 54 | } else { 55 | err = rpcc.Invoke(ctx, "DOMSnapshot.getSnapshot", nil, reply, d.conn) 56 | } 57 | if err != nil { 58 | err = &internal.OpError{Domain: "DOMSnapshot", Op: "GetSnapshot", Err: err} 59 | } 60 | return 61 | } 62 | 63 | // CaptureSnapshot invokes the DOMSnapshot method. Returns a document 64 | // snapshot, including the full DOM tree of the root node (including iframes, 65 | // template contents, and imported documents) in a flattened array, as well as 66 | // layout and white-listed computed style information for the nodes. Shadow DOM 67 | // in the returned DOM tree is flattened. 68 | func (d *domainClient) CaptureSnapshot(ctx context.Context, args *CaptureSnapshotArgs) (reply *CaptureSnapshotReply, err error) { 69 | reply = new(CaptureSnapshotReply) 70 | if args != nil { 71 | err = rpcc.Invoke(ctx, "DOMSnapshot.captureSnapshot", args, reply, d.conn) 72 | } else { 73 | err = rpcc.Invoke(ctx, "DOMSnapshot.captureSnapshot", nil, reply, d.conn) 74 | } 75 | if err != nil { 76 | err = &internal.OpError{Domain: "DOMSnapshot", Op: "CaptureSnapshot", Err: err} 77 | } 78 | return 79 | } 80 | -------------------------------------------------------------------------------- /protocol/domstorage/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package domstorage 4 | 5 | // ClearArgs represents the arguments for Clear in the DOMStorage domain. 6 | type ClearArgs struct { 7 | StorageID StorageID `json:"storageId"` // No description. 8 | } 9 | 10 | // NewClearArgs initializes ClearArgs with the required arguments. 11 | func NewClearArgs(storageID StorageID) *ClearArgs { 12 | args := new(ClearArgs) 13 | args.StorageID = storageID 14 | return args 15 | } 16 | 17 | // GetDOMStorageItemsArgs represents the arguments for GetDOMStorageItems in the DOMStorage domain. 18 | type GetDOMStorageItemsArgs struct { 19 | StorageID StorageID `json:"storageId"` // No description. 20 | } 21 | 22 | // NewGetDOMStorageItemsArgs initializes GetDOMStorageItemsArgs with the required arguments. 23 | func NewGetDOMStorageItemsArgs(storageID StorageID) *GetDOMStorageItemsArgs { 24 | args := new(GetDOMStorageItemsArgs) 25 | args.StorageID = storageID 26 | return args 27 | } 28 | 29 | // GetDOMStorageItemsReply represents the return values for GetDOMStorageItems in the DOMStorage domain. 30 | type GetDOMStorageItemsReply struct { 31 | Entries []Item `json:"entries"` // No description. 32 | } 33 | 34 | // RemoveDOMStorageItemArgs represents the arguments for RemoveDOMStorageItem in the DOMStorage domain. 35 | type RemoveDOMStorageItemArgs struct { 36 | StorageID StorageID `json:"storageId"` // No description. 37 | Key string `json:"key"` // No description. 38 | } 39 | 40 | // NewRemoveDOMStorageItemArgs initializes RemoveDOMStorageItemArgs with the required arguments. 41 | func NewRemoveDOMStorageItemArgs(storageID StorageID, key string) *RemoveDOMStorageItemArgs { 42 | args := new(RemoveDOMStorageItemArgs) 43 | args.StorageID = storageID 44 | args.Key = key 45 | return args 46 | } 47 | 48 | // SetDOMStorageItemArgs represents the arguments for SetDOMStorageItem in the DOMStorage domain. 49 | type SetDOMStorageItemArgs struct { 50 | StorageID StorageID `json:"storageId"` // No description. 51 | Key string `json:"key"` // No description. 52 | Value string `json:"value"` // No description. 53 | } 54 | 55 | // NewSetDOMStorageItemArgs initializes SetDOMStorageItemArgs with the required arguments. 56 | func NewSetDOMStorageItemArgs(storageID StorageID, key string, value string) *SetDOMStorageItemArgs { 57 | args := new(SetDOMStorageItemArgs) 58 | args.StorageID = storageID 59 | args.Key = key 60 | args.Value = value 61 | return args 62 | } 63 | -------------------------------------------------------------------------------- /protocol/domstorage/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package domstorage 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // ItemAddedClient is a client for DOMStorageItemAdded events. 10 | type ItemAddedClient interface { 11 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 12 | // triggered, context canceled or connection closed. 13 | Recv() (*ItemAddedReply, error) 14 | rpcc.Stream 15 | } 16 | 17 | // ItemAddedReply is the reply for DOMStorageItemAdded events. 18 | type ItemAddedReply struct { 19 | StorageID StorageID `json:"storageId"` // No description. 20 | Key string `json:"key"` // No description. 21 | NewValue string `json:"newValue"` // No description. 22 | } 23 | 24 | // ItemRemovedClient is a client for DOMStorageItemRemoved events. 25 | type ItemRemovedClient interface { 26 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 27 | // triggered, context canceled or connection closed. 28 | Recv() (*ItemRemovedReply, error) 29 | rpcc.Stream 30 | } 31 | 32 | // ItemRemovedReply is the reply for DOMStorageItemRemoved events. 33 | type ItemRemovedReply struct { 34 | StorageID StorageID `json:"storageId"` // No description. 35 | Key string `json:"key"` // No description. 36 | } 37 | 38 | // ItemUpdatedClient is a client for DOMStorageItemUpdated events. 39 | type ItemUpdatedClient interface { 40 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 41 | // triggered, context canceled or connection closed. 42 | Recv() (*ItemUpdatedReply, error) 43 | rpcc.Stream 44 | } 45 | 46 | // ItemUpdatedReply is the reply for DOMStorageItemUpdated events. 47 | type ItemUpdatedReply struct { 48 | StorageID StorageID `json:"storageId"` // No description. 49 | Key string `json:"key"` // No description. 50 | OldValue string `json:"oldValue"` // No description. 51 | NewValue string `json:"newValue"` // No description. 52 | } 53 | 54 | // ItemsClearedClient is a client for DOMStorageItemsCleared events. 55 | type ItemsClearedClient interface { 56 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 57 | // triggered, context canceled or connection closed. 58 | Recv() (*ItemsClearedReply, error) 59 | rpcc.Stream 60 | } 61 | 62 | // ItemsClearedReply is the reply for DOMStorageItemsCleared events. 63 | type ItemsClearedReply struct { 64 | StorageID StorageID `json:"storageId"` // No description. 65 | } 66 | -------------------------------------------------------------------------------- /protocol/domstorage/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package domstorage 4 | 5 | // SerializedStorageKey 6 | type SerializedStorageKey string 7 | 8 | // StorageID DOM Storage identifier. 9 | type StorageID struct { 10 | SecurityOrigin *string `json:"securityOrigin,omitempty"` // Security origin for the storage. 11 | StorageKey *SerializedStorageKey `json:"storageKey,omitempty"` // Represents a key by which DOM Storage keys its CachedStorageAreas 12 | IsLocalStorage bool `json:"isLocalStorage"` // Whether the storage is local storage (not session storage). 13 | } 14 | 15 | // Item DOM Storage item. 16 | type Item []string 17 | -------------------------------------------------------------------------------- /protocol/emulation/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package emulation 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // VirtualTimeBudgetExpiredClient is a client for VirtualTimeBudgetExpired events. 10 | // Notification sent after the virtual time budget for the current 11 | // VirtualTimePolicy has run out. 12 | type VirtualTimeBudgetExpiredClient interface { 13 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 14 | // triggered, context canceled or connection closed. 15 | Recv() (*VirtualTimeBudgetExpiredReply, error) 16 | rpcc.Stream 17 | } 18 | 19 | // VirtualTimeBudgetExpiredReply is the reply for VirtualTimeBudgetExpired events. 20 | type VirtualTimeBudgetExpiredReply struct { 21 | } 22 | -------------------------------------------------------------------------------- /protocol/eventbreakpoints/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package eventbreakpoints 4 | 5 | // SetInstrumentationBreakpointArgs represents the arguments for SetInstrumentationBreakpoint in the EventBreakpoints domain. 6 | type SetInstrumentationBreakpointArgs struct { 7 | EventName string `json:"eventName"` // Instrumentation name to stop on. 8 | } 9 | 10 | // NewSetInstrumentationBreakpointArgs initializes SetInstrumentationBreakpointArgs with the required arguments. 11 | func NewSetInstrumentationBreakpointArgs(eventName string) *SetInstrumentationBreakpointArgs { 12 | args := new(SetInstrumentationBreakpointArgs) 13 | args.EventName = eventName 14 | return args 15 | } 16 | 17 | // RemoveInstrumentationBreakpointArgs represents the arguments for RemoveInstrumentationBreakpoint in the EventBreakpoints domain. 18 | type RemoveInstrumentationBreakpointArgs struct { 19 | EventName string `json:"eventName"` // Instrumentation name to stop on. 20 | } 21 | 22 | // NewRemoveInstrumentationBreakpointArgs initializes RemoveInstrumentationBreakpointArgs with the required arguments. 23 | func NewRemoveInstrumentationBreakpointArgs(eventName string) *RemoveInstrumentationBreakpointArgs { 24 | args := new(RemoveInstrumentationBreakpointArgs) 25 | args.EventName = eventName 26 | return args 27 | } 28 | -------------------------------------------------------------------------------- /protocol/eventbreakpoints/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package eventbreakpoints implements the EventBreakpoints domain. 4 | // EventBreakpoints permits setting JavaScript breakpoints on operations and 5 | // events occurring in native code invoked from JavaScript. Once breakpoint is 6 | // hit, it is reported through Debugger domain, similarly to regular 7 | // breakpoints being hit. 8 | package eventbreakpoints 9 | 10 | import ( 11 | "context" 12 | 13 | "github.com/mafredri/cdp/protocol/internal" 14 | "github.com/mafredri/cdp/rpcc" 15 | ) 16 | 17 | // domainClient is a client for the EventBreakpoints domain. EventBreakpoints 18 | // permits setting JavaScript breakpoints on operations and events occurring in 19 | // native code invoked from JavaScript. Once breakpoint is hit, it is reported 20 | // through Debugger domain, similarly to regular breakpoints being hit. 21 | type domainClient struct{ conn *rpcc.Conn } 22 | 23 | // NewClient returns a client for the EventBreakpoints domain with the connection set to conn. 24 | func NewClient(conn *rpcc.Conn) *domainClient { 25 | return &domainClient{conn: conn} 26 | } 27 | 28 | // SetInstrumentationBreakpoint invokes the EventBreakpoints method. Sets 29 | // breakpoint on particular native event. 30 | func (d *domainClient) SetInstrumentationBreakpoint(ctx context.Context, args *SetInstrumentationBreakpointArgs) (err error) { 31 | if args != nil { 32 | err = rpcc.Invoke(ctx, "EventBreakpoints.setInstrumentationBreakpoint", args, nil, d.conn) 33 | } else { 34 | err = rpcc.Invoke(ctx, "EventBreakpoints.setInstrumentationBreakpoint", nil, nil, d.conn) 35 | } 36 | if err != nil { 37 | err = &internal.OpError{Domain: "EventBreakpoints", Op: "SetInstrumentationBreakpoint", Err: err} 38 | } 39 | return 40 | } 41 | 42 | // RemoveInstrumentationBreakpoint invokes the EventBreakpoints method. 43 | // Removes breakpoint on particular native event. 44 | func (d *domainClient) RemoveInstrumentationBreakpoint(ctx context.Context, args *RemoveInstrumentationBreakpointArgs) (err error) { 45 | if args != nil { 46 | err = rpcc.Invoke(ctx, "EventBreakpoints.removeInstrumentationBreakpoint", args, nil, d.conn) 47 | } else { 48 | err = rpcc.Invoke(ctx, "EventBreakpoints.removeInstrumentationBreakpoint", nil, nil, d.conn) 49 | } 50 | if err != nil { 51 | err = &internal.OpError{Domain: "EventBreakpoints", Op: "RemoveInstrumentationBreakpoint", Err: err} 52 | } 53 | return 54 | } 55 | 56 | // Disable invokes the EventBreakpoints method. Removes all breakpoints 57 | func (d *domainClient) Disable(ctx context.Context) (err error) { 58 | err = rpcc.Invoke(ctx, "EventBreakpoints.disable", nil, nil, d.conn) 59 | if err != nil { 60 | err = &internal.OpError{Domain: "EventBreakpoints", Op: "Disable", Err: err} 61 | } 62 | return 63 | } 64 | -------------------------------------------------------------------------------- /protocol/extensions/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package extensions 4 | 5 | // StorageArea Storage areas. 6 | type StorageArea string 7 | 8 | // StorageArea as enums. 9 | const ( 10 | StorageAreaNotSet StorageArea = "" 11 | StorageAreaSession StorageArea = "session" 12 | StorageAreaLocal StorageArea = "local" 13 | StorageAreaSync StorageArea = "sync" 14 | StorageAreaManaged StorageArea = "managed" 15 | ) 16 | 17 | func (e StorageArea) Valid() bool { 18 | switch e { 19 | case "session", "local", "sync", "managed": 20 | return true 21 | default: 22 | return false 23 | } 24 | } 25 | 26 | func (e StorageArea) String() string { 27 | return string(e) 28 | } 29 | -------------------------------------------------------------------------------- /protocol/fedcm/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package fedcm 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // DialogShownClient is a client for DialogShown events. 10 | type DialogShownClient interface { 11 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 12 | // triggered, context canceled or connection closed. 13 | Recv() (*DialogShownReply, error) 14 | rpcc.Stream 15 | } 16 | 17 | // DialogShownReply is the reply for DialogShown events. 18 | type DialogShownReply struct { 19 | DialogID string `json:"dialogId"` // No description. 20 | DialogType DialogType `json:"dialogType"` // No description. 21 | Accounts []Account `json:"accounts"` // No description. 22 | Title string `json:"title"` // These exist primarily so that the caller can verify the RP context was used appropriately. 23 | Subtitle *string `json:"subtitle,omitempty"` // No description. 24 | } 25 | 26 | // DialogClosedClient is a client for DialogClosed events. Triggered when a 27 | // dialog is closed, either by user action, JS abort, or a command below. 28 | type DialogClosedClient interface { 29 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 30 | // triggered, context canceled or connection closed. 31 | Recv() (*DialogClosedReply, error) 32 | rpcc.Stream 33 | } 34 | 35 | // DialogClosedReply is the reply for DialogClosed events. 36 | type DialogClosedReply struct { 37 | DialogID string `json:"dialogId"` // No description. 38 | } 39 | -------------------------------------------------------------------------------- /protocol/fetch/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package fetch 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/network" 7 | ) 8 | 9 | // RequestID Unique request identifier. 10 | type RequestID string 11 | 12 | // RequestStage Stages of the request to handle. Request will intercept before 13 | // the request is sent. Response will intercept after the response is received 14 | // (but before response body is received). 15 | type RequestStage string 16 | 17 | // RequestStage as enums. 18 | const ( 19 | RequestStageNotSet RequestStage = "" 20 | RequestStageRequest RequestStage = "Request" 21 | RequestStageResponse RequestStage = "Response" 22 | ) 23 | 24 | func (e RequestStage) Valid() bool { 25 | switch e { 26 | case "Request", "Response": 27 | return true 28 | default: 29 | return false 30 | } 31 | } 32 | 33 | func (e RequestStage) String() string { 34 | return string(e) 35 | } 36 | 37 | // RequestPattern 38 | type RequestPattern struct { 39 | URLPattern *string `json:"urlPattern,omitempty"` // Wildcards (`'*'` -> zero or more, `'?'` -> exactly one) are allowed. Escape character is backslash. Omitting is equivalent to `"*"`. 40 | ResourceType *network.ResourceType `json:"resourceType,omitempty"` // If set, only requests for matching resource types will be intercepted. 41 | RequestStage RequestStage `json:"requestStage,omitempty"` // Stage at which to begin intercepting requests. Default is Request. 42 | } 43 | 44 | // HeaderEntry Response HTTP header entry 45 | type HeaderEntry struct { 46 | Name string `json:"name"` // No description. 47 | Value string `json:"value"` // No description. 48 | } 49 | 50 | // AuthChallenge Authorization challenge for HTTP status code 401 or 407. 51 | type AuthChallenge struct { 52 | // Source Source of the authentication challenge. 53 | // 54 | // Values: "Server", "Proxy". 55 | Source *string `json:"source,omitempty"` 56 | Origin string `json:"origin"` // Origin of the challenger. 57 | Scheme string `json:"scheme"` // The authentication scheme used, such as basic or digest 58 | Realm string `json:"realm"` // The realm of the challenge. May be empty. 59 | } 60 | 61 | // AuthChallengeResponse Response to an AuthChallenge. 62 | type AuthChallengeResponse struct { 63 | // Response The decision on what to do in response to the 64 | // authorization challenge. Default means deferring to the default 65 | // behavior of the net stack, which will likely either the Cancel 66 | // authentication or display a popup dialog box. 67 | // 68 | // Values: "Default", "CancelAuth", "ProvideCredentials". 69 | Response string `json:"response"` 70 | Username *string `json:"username,omitempty"` // The username to provide, possibly empty. Should only be set if response is ProvideCredentials. 71 | Password *string `json:"password,omitempty"` // The password to provide, possibly empty. Should only be set if response is ProvideCredentials. 72 | } 73 | -------------------------------------------------------------------------------- /protocol/filesystem/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package filesystem 4 | 5 | // GetDirectoryArgs represents the arguments for GetDirectory in the FileSystem domain. 6 | type GetDirectoryArgs struct { 7 | BucketFileSystemLocator BucketFileSystemLocator `json:"bucketFileSystemLocator"` // No description. 8 | } 9 | 10 | // NewGetDirectoryArgs initializes GetDirectoryArgs with the required arguments. 11 | func NewGetDirectoryArgs(bucketFileSystemLocator BucketFileSystemLocator) *GetDirectoryArgs { 12 | args := new(GetDirectoryArgs) 13 | args.BucketFileSystemLocator = bucketFileSystemLocator 14 | return args 15 | } 16 | 17 | // GetDirectoryReply represents the return values for GetDirectory in the FileSystem domain. 18 | type GetDirectoryReply struct { 19 | Directory Directory `json:"directory"` // Returns the directory object at the path. 20 | } 21 | -------------------------------------------------------------------------------- /protocol/filesystem/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package filesystem implements the FileSystem domain. 4 | package filesystem 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/mafredri/cdp/protocol/internal" 10 | "github.com/mafredri/cdp/rpcc" 11 | ) 12 | 13 | // domainClient is a client for the FileSystem domain. 14 | type domainClient struct{ conn *rpcc.Conn } 15 | 16 | // NewClient returns a client for the FileSystem domain with the connection set to conn. 17 | func NewClient(conn *rpcc.Conn) *domainClient { 18 | return &domainClient{conn: conn} 19 | } 20 | 21 | // GetDirectory invokes the FileSystem method. 22 | func (d *domainClient) GetDirectory(ctx context.Context, args *GetDirectoryArgs) (reply *GetDirectoryReply, err error) { 23 | reply = new(GetDirectoryReply) 24 | if args != nil { 25 | err = rpcc.Invoke(ctx, "FileSystem.getDirectory", args, reply, d.conn) 26 | } else { 27 | err = rpcc.Invoke(ctx, "FileSystem.getDirectory", nil, reply, d.conn) 28 | } 29 | if err != nil { 30 | err = &internal.OpError{Domain: "FileSystem", Op: "GetDirectory", Err: err} 31 | } 32 | return 33 | } 34 | -------------------------------------------------------------------------------- /protocol/filesystem/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package filesystem 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/network" 7 | "github.com/mafredri/cdp/protocol/storage" 8 | ) 9 | 10 | // File 11 | type File struct { 12 | Name string `json:"name"` // No description. 13 | LastModified network.TimeSinceEpoch `json:"lastModified"` // Timestamp 14 | Size float64 `json:"size"` // Size in bytes 15 | Type string `json:"type"` // No description. 16 | } 17 | 18 | // Directory 19 | type Directory struct { 20 | Name string `json:"name"` // No description. 21 | NestedDirectories []string `json:"nestedDirectories"` // No description. 22 | NestedFiles []File `json:"nestedFiles"` // Files that are directly nested under this directory. 23 | } 24 | 25 | // BucketFileSystemLocator 26 | type BucketFileSystemLocator struct { 27 | StorageKey storage.SerializedStorageKey `json:"storageKey"` // Storage key 28 | BucketName *string `json:"bucketName,omitempty"` // Bucket name. Not passing a `bucketName` will retrieve the default Bucket. (https://developer.mozilla.org/en-US/docs/Web/API/Storage_API#storage_buckets) 29 | PathComponents []string `json:"pathComponents"` // Path to the directory using each path component as an array item. 30 | } 31 | -------------------------------------------------------------------------------- /protocol/headlessexperimental/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package headlessexperimental implements the HeadlessExperimental domain. 4 | // This domain provides experimental commands only supported in headless mode. 5 | package headlessexperimental 6 | 7 | import ( 8 | "context" 9 | 10 | "github.com/mafredri/cdp/protocol/internal" 11 | "github.com/mafredri/cdp/rpcc" 12 | ) 13 | 14 | // domainClient is a client for the HeadlessExperimental domain. This domain 15 | // provides experimental commands only supported in headless mode. 16 | type domainClient struct{ conn *rpcc.Conn } 17 | 18 | // NewClient returns a client for the HeadlessExperimental domain with the connection set to conn. 19 | func NewClient(conn *rpcc.Conn) *domainClient { 20 | return &domainClient{conn: conn} 21 | } 22 | 23 | // BeginFrame invokes the HeadlessExperimental method. Sends a BeginFrame to 24 | // the target and returns when the frame was completed. Optionally captures a 25 | // screenshot from the resulting frame. Requires that the target was created 26 | // with enabled BeginFrameControl. Designed for use with 27 | // --run-all-compositor-stages-before-draw, see also 28 | // https://goo.gle/chrome-headless-rendering for more background. 29 | func (d *domainClient) BeginFrame(ctx context.Context, args *BeginFrameArgs) (reply *BeginFrameReply, err error) { 30 | reply = new(BeginFrameReply) 31 | if args != nil { 32 | err = rpcc.Invoke(ctx, "HeadlessExperimental.beginFrame", args, reply, d.conn) 33 | } else { 34 | err = rpcc.Invoke(ctx, "HeadlessExperimental.beginFrame", nil, reply, d.conn) 35 | } 36 | if err != nil { 37 | err = &internal.OpError{Domain: "HeadlessExperimental", Op: "BeginFrame", Err: err} 38 | } 39 | return 40 | } 41 | 42 | // Disable invokes the HeadlessExperimental method. Disables headless events 43 | // for the target. 44 | func (d *domainClient) Disable(ctx context.Context) (err error) { 45 | err = rpcc.Invoke(ctx, "HeadlessExperimental.disable", nil, nil, d.conn) 46 | if err != nil { 47 | err = &internal.OpError{Domain: "HeadlessExperimental", Op: "Disable", Err: err} 48 | } 49 | return 50 | } 51 | 52 | // Enable invokes the HeadlessExperimental method. Enables headless events for 53 | // the target. 54 | func (d *domainClient) Enable(ctx context.Context) (err error) { 55 | err = rpcc.Invoke(ctx, "HeadlessExperimental.enable", nil, nil, d.conn) 56 | if err != nil { 57 | err = &internal.OpError{Domain: "HeadlessExperimental", Op: "Enable", Err: err} 58 | } 59 | return 60 | } 61 | -------------------------------------------------------------------------------- /protocol/headlessexperimental/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package headlessexperimental 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // NeedsBeginFramesChangedClient is a client for NeedsBeginFramesChanged events. 10 | // Issued when the target starts or stops needing BeginFrames. Deprecated. 11 | // Issue beginFrame unconditionally instead and use result from beginFrame to 12 | // detect whether the frames were suppressed. 13 | type NeedsBeginFramesChangedClient interface { 14 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 15 | // triggered, context canceled or connection closed. 16 | Recv() (*NeedsBeginFramesChangedReply, error) 17 | rpcc.Stream 18 | } 19 | 20 | // NeedsBeginFramesChangedReply is the reply for NeedsBeginFramesChanged events. 21 | type NeedsBeginFramesChangedReply struct { 22 | NeedsBeginFrames bool `json:"needsBeginFrames"` // True if BeginFrames are needed, false otherwise. 23 | } 24 | -------------------------------------------------------------------------------- /protocol/headlessexperimental/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package headlessexperimental 4 | 5 | // ScreenshotParams Encoding options for a screenshot. 6 | type ScreenshotParams struct { 7 | // Format Image compression format (defaults to png). 8 | // 9 | // Values: "jpeg", "png", "webp". 10 | Format *string `json:"format,omitempty"` 11 | Quality *int `json:"quality,omitempty"` // Compression quality from range [0..100] (jpeg and webp only). 12 | OptimizeForSpeed *bool `json:"optimizeForSpeed,omitempty"` // Optimize image encoding for speed, not for resulting size (defaults to false) 13 | } 14 | -------------------------------------------------------------------------------- /protocol/heapprofiler/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package heapprofiler 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/runtime" 7 | ) 8 | 9 | // HeapSnapshotObjectID Heap snapshot object id. 10 | type HeapSnapshotObjectID string 11 | 12 | // SamplingHeapProfileNode Sampling Heap Profile node. Holds callsite 13 | // information, allocation statistics and child nodes. 14 | type SamplingHeapProfileNode struct { 15 | CallFrame runtime.CallFrame `json:"callFrame"` // Function location. 16 | SelfSize float64 `json:"selfSize"` // Allocations size in bytes for the node excluding children. 17 | ID int `json:"id"` // Node id. Ids are unique across all profiles collected between startSampling and stopSampling. 18 | Children []SamplingHeapProfileNode `json:"children"` // Child nodes. 19 | } 20 | 21 | // SamplingHeapProfileSample A single sample from a sampling profile. 22 | type SamplingHeapProfileSample struct { 23 | Size float64 `json:"size"` // Allocation size in bytes attributed to the sample. 24 | NodeID int `json:"nodeId"` // Id of the corresponding profile tree node. 25 | Ordinal float64 `json:"ordinal"` // Time-ordered sample ordinal number. It is unique across all profiles retrieved between startSampling and stopSampling. 26 | } 27 | 28 | // SamplingHeapProfile Sampling profile. 29 | type SamplingHeapProfile struct { 30 | Head SamplingHeapProfileNode `json:"head"` // No description. 31 | Samples []SamplingHeapProfileSample `json:"samples"` // No description. 32 | } 33 | -------------------------------------------------------------------------------- /protocol/indexeddb/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package indexeddb 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/runtime" 7 | ) 8 | 9 | // DatabaseWithObjectStores Database with an array of object stores. 10 | type DatabaseWithObjectStores struct { 11 | Name string `json:"name"` // Database name. 12 | Version float64 `json:"version"` // Database version (type is not 'integer', as the standard requires the version number to be 'unsigned long long') 13 | ObjectStores []ObjectStore `json:"objectStores"` // Object stores in this database. 14 | } 15 | 16 | // ObjectStore Object store. 17 | type ObjectStore struct { 18 | Name string `json:"name"` // Object store name. 19 | KeyPath KeyPath `json:"keyPath"` // Object store key path. 20 | AutoIncrement bool `json:"autoIncrement"` // If true, object store has auto increment flag set. 21 | Indexes []ObjectStoreIndex `json:"indexes"` // Indexes in this object store. 22 | } 23 | 24 | // ObjectStoreIndex Object store index. 25 | type ObjectStoreIndex struct { 26 | Name string `json:"name"` // Index name. 27 | KeyPath KeyPath `json:"keyPath"` // Index key path. 28 | Unique bool `json:"unique"` // If true, index is unique. 29 | MultiEntry bool `json:"multiEntry"` // If true, index allows multiple entries for a key. 30 | } 31 | 32 | // Key Key. 33 | type Key struct { 34 | // Type Key type. 35 | // 36 | // Values: "number", "string", "date", "array". 37 | Type string `json:"type"` 38 | Number *float64 `json:"number,omitempty"` // Number value. 39 | String *string `json:"string,omitempty"` // String value. 40 | Date *float64 `json:"date,omitempty"` // Date value. 41 | Array []Key `json:"array,omitempty"` // Array value. 42 | } 43 | 44 | // KeyRange Key range. 45 | type KeyRange struct { 46 | Lower *Key `json:"lower,omitempty"` // Lower bound. 47 | Upper *Key `json:"upper,omitempty"` // Upper bound. 48 | LowerOpen bool `json:"lowerOpen"` // If true lower bound is open. 49 | UpperOpen bool `json:"upperOpen"` // If true upper bound is open. 50 | } 51 | 52 | // DataEntry Data entry. 53 | type DataEntry struct { 54 | Key runtime.RemoteObject `json:"key"` // Key object. 55 | PrimaryKey runtime.RemoteObject `json:"primaryKey"` // Primary key object. 56 | Value runtime.RemoteObject `json:"value"` // Value object. 57 | } 58 | 59 | // KeyPath Key path. 60 | type KeyPath struct { 61 | // Type Key path type. 62 | // 63 | // Values: "null", "string", "array". 64 | Type string `json:"type"` 65 | String *string `json:"string,omitempty"` // String value. 66 | Array []string `json:"array,omitempty"` // Array value. 67 | } 68 | -------------------------------------------------------------------------------- /protocol/input/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package input 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // DragInterceptedClient is a client for DragIntercepted events. Emitted only 10 | // when `Input.setInterceptDrags` is enabled. Use this data with 11 | // `Input.dispatchDragEvent` to restore normal drag and drop behavior. 12 | type DragInterceptedClient interface { 13 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 14 | // triggered, context canceled or connection closed. 15 | Recv() (*DragInterceptedReply, error) 16 | rpcc.Stream 17 | } 18 | 19 | // DragInterceptedReply is the reply for DragIntercepted events. 20 | type DragInterceptedReply struct { 21 | Data DragData `json:"data"` // No description. 22 | } 23 | -------------------------------------------------------------------------------- /protocol/inspector/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package inspector 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // DetachedClient is a client for Detached events. Fired when remote debugging 10 | // connection is about to be terminated. Contains detach reason. 11 | type DetachedClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*DetachedReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // DetachedReply is the reply for Detached events. 19 | type DetachedReply struct { 20 | Reason string `json:"reason"` // The reason why connection has been terminated. 21 | } 22 | 23 | // TargetCrashedClient is a client for TargetCrashed events. Fired when 24 | // debugging target has crashed 25 | type TargetCrashedClient interface { 26 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 27 | // triggered, context canceled or connection closed. 28 | Recv() (*TargetCrashedReply, error) 29 | rpcc.Stream 30 | } 31 | 32 | // TargetCrashedReply is the reply for TargetCrashed events. 33 | type TargetCrashedReply struct { 34 | } 35 | 36 | // TargetReloadedAfterCrashClient is a client for TargetReloadedAfterCrash events. 37 | // Fired when debugging target has reloaded after crash 38 | type TargetReloadedAfterCrashClient interface { 39 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 40 | // triggered, context canceled or connection closed. 41 | Recv() (*TargetReloadedAfterCrashReply, error) 42 | rpcc.Stream 43 | } 44 | 45 | // TargetReloadedAfterCrashReply is the reply for TargetReloadedAfterCrash events. 46 | type TargetReloadedAfterCrashReply struct { 47 | } 48 | -------------------------------------------------------------------------------- /protocol/internal/browser.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package internal 4 | 5 | // BrowserContextID 6 | // 7 | // This type cannot be used directly. Use browser.ContextID instead. 8 | // 9 | // Note: This type is experimental. 10 | type BrowserContextID string 11 | -------------------------------------------------------------------------------- /protocol/internal/error.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // OpError represents an operational error. 8 | type OpError struct { 9 | Domain string 10 | Op string 11 | Err error 12 | } 13 | 14 | func (e OpError) Error() string { 15 | return fmt.Sprintf("cdp.%s: %s: %s", e.Domain, e.Op, e.Err.Error()) 16 | } 17 | 18 | // Cause implements error causer. 19 | func (e *OpError) Cause() error { 20 | return e.Err 21 | } 22 | 23 | // Unwrap implements Wrapper. 24 | func (e *OpError) Unwrap() error { 25 | return e.Err 26 | } 27 | 28 | type ( 29 | causer interface{ Cause() error } 30 | wrapper interface{ Unwrap() error } 31 | ) 32 | 33 | var ( 34 | _ error = (*OpError)(nil) 35 | _ causer = (*OpError)(nil) 36 | _ wrapper = (*OpError)(nil) 37 | ) 38 | -------------------------------------------------------------------------------- /protocol/internal/error_test.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func TestOpError_ErrorContainsErrorCauser(t *testing.T) { 10 | causer := errors.New("error causer") 11 | err := &OpError{ 12 | Domain: "Test", 13 | Op: "Method", 14 | Err: causer, 15 | } 16 | 17 | got := err.Error() 18 | if !strings.Contains(got, causer.Error()) { 19 | t.Errorf("Error() should contain error causer, got: %s", got) 20 | } 21 | 22 | if err.Cause() != causer { 23 | t.Errorf("Cause() got: %v, want: %v", err.Cause(), causer) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /protocol/internal/network.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package internal 4 | 5 | import ( 6 | "encoding/json" 7 | "errors" 8 | "time" 9 | ) 10 | 11 | // NetworkTimeSinceEpoch UTC time in seconds, counted from January 1, 1970. 12 | // 13 | // This type cannot be used directly. Use network.TimeSinceEpoch instead. 14 | type NetworkTimeSinceEpoch float64 15 | 16 | // String calls (time.Time).String(). 17 | func (t NetworkTimeSinceEpoch) String() string { 18 | return t.Time().String() 19 | } 20 | 21 | // Time parses the Unix time. 22 | func (t NetworkTimeSinceEpoch) Time() time.Time { 23 | ts := float64(t) / 1 24 | secs := int64(ts) 25 | nsecs := int64((ts - float64(secs)) * 1000000000) 26 | return time.Unix(secs, nsecs) 27 | } 28 | 29 | // MarshalJSON implements json.Marshaler. Encodes to null if t is zero. 30 | func (t NetworkTimeSinceEpoch) MarshalJSON() ([]byte, error) { 31 | if t == 0 { 32 | return []byte("null"), nil 33 | } 34 | f := float64(t) 35 | return json.Marshal(&f) 36 | } 37 | 38 | // UnmarshalJSON implements json.Unmarshaler. 39 | func (t *NetworkTimeSinceEpoch) UnmarshalJSON(data []byte) error { 40 | *t = 0 41 | if len(data) == 0 { 42 | return nil 43 | } 44 | var f float64 45 | if err := json.Unmarshal(data, &f); err != nil { 46 | return errors.New("internal.NetworkTimeSinceEpoch: " + err.Error()) 47 | } 48 | *t = NetworkTimeSinceEpoch(f) 49 | return nil 50 | } 51 | 52 | var _ json.Marshaler = (*NetworkTimeSinceEpoch)(nil) 53 | var _ json.Unmarshaler = (*NetworkTimeSinceEpoch)(nil) 54 | -------------------------------------------------------------------------------- /protocol/internal/page.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package internal 4 | 5 | // PageFrameID Unique frame identifier. 6 | // 7 | // This type cannot be used directly. Use page.FrameID instead. 8 | type PageFrameID string 9 | -------------------------------------------------------------------------------- /protocol/io/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package io 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/runtime" 7 | ) 8 | 9 | // CloseArgs represents the arguments for Close in the IO domain. 10 | type CloseArgs struct { 11 | Handle StreamHandle `json:"handle"` // Handle of the stream to close. 12 | } 13 | 14 | // NewCloseArgs initializes CloseArgs with the required arguments. 15 | func NewCloseArgs(handle StreamHandle) *CloseArgs { 16 | args := new(CloseArgs) 17 | args.Handle = handle 18 | return args 19 | } 20 | 21 | // ReadArgs represents the arguments for Read in the IO domain. 22 | type ReadArgs struct { 23 | Handle StreamHandle `json:"handle"` // Handle of the stream to read. 24 | Offset *int `json:"offset,omitempty"` // Seek to the specified offset before reading (if not specified, proceed with offset following the last read). Some types of streams may only support sequential reads. 25 | Size *int `json:"size,omitempty"` // Maximum number of bytes to read (left upon the agent discretion if not specified). 26 | } 27 | 28 | // NewReadArgs initializes ReadArgs with the required arguments. 29 | func NewReadArgs(handle StreamHandle) *ReadArgs { 30 | args := new(ReadArgs) 31 | args.Handle = handle 32 | return args 33 | } 34 | 35 | // SetOffset sets the Offset optional argument. Seek to the specified 36 | // offset before reading (if not specified, proceed with offset 37 | // following the last read). Some types of streams may only support 38 | // sequential reads. 39 | func (a *ReadArgs) SetOffset(offset int) *ReadArgs { 40 | a.Offset = &offset 41 | return a 42 | } 43 | 44 | // SetSize sets the Size optional argument. Maximum number of bytes to 45 | // read (left upon the agent discretion if not specified). 46 | func (a *ReadArgs) SetSize(size int) *ReadArgs { 47 | a.Size = &size 48 | return a 49 | } 50 | 51 | // ReadReply represents the return values for Read in the IO domain. 52 | type ReadReply struct { 53 | Base64Encoded *bool `json:"base64Encoded,omitempty"` // Set if the data is base64-encoded 54 | Data string `json:"data"` // Data that were read. 55 | EOF bool `json:"eof"` // Set if the end-of-file condition occurred while reading. 56 | } 57 | 58 | // ResolveBlobArgs represents the arguments for ResolveBlob in the IO domain. 59 | type ResolveBlobArgs struct { 60 | ObjectID runtime.RemoteObjectID `json:"objectId"` // Object id of a Blob object wrapper. 61 | } 62 | 63 | // NewResolveBlobArgs initializes ResolveBlobArgs with the required arguments. 64 | func NewResolveBlobArgs(objectID runtime.RemoteObjectID) *ResolveBlobArgs { 65 | args := new(ResolveBlobArgs) 66 | args.ObjectID = objectID 67 | return args 68 | } 69 | 70 | // ResolveBlobReply represents the return values for ResolveBlob in the IO domain. 71 | type ResolveBlobReply struct { 72 | UUID string `json:"uuid"` // UUID of the specified Blob. 73 | } 74 | -------------------------------------------------------------------------------- /protocol/io/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package io implements the IO domain. Input/Output operations for streams 4 | // produced by DevTools. 5 | package io 6 | 7 | import ( 8 | "context" 9 | 10 | "github.com/mafredri/cdp/protocol/internal" 11 | "github.com/mafredri/cdp/rpcc" 12 | ) 13 | 14 | // domainClient is a client for the IO domain. Input/Output operations for 15 | // streams produced by DevTools. 16 | type domainClient struct{ conn *rpcc.Conn } 17 | 18 | // NewClient returns a client for the IO domain with the connection set to conn. 19 | func NewClient(conn *rpcc.Conn) *domainClient { 20 | return &domainClient{conn: conn} 21 | } 22 | 23 | // Close invokes the IO method. Close the stream, discard any temporary 24 | // backing storage. 25 | func (d *domainClient) Close(ctx context.Context, args *CloseArgs) (err error) { 26 | if args != nil { 27 | err = rpcc.Invoke(ctx, "IO.close", args, nil, d.conn) 28 | } else { 29 | err = rpcc.Invoke(ctx, "IO.close", nil, nil, d.conn) 30 | } 31 | if err != nil { 32 | err = &internal.OpError{Domain: "IO", Op: "Close", Err: err} 33 | } 34 | return 35 | } 36 | 37 | // Read invokes the IO method. Read a chunk of the stream 38 | func (d *domainClient) Read(ctx context.Context, args *ReadArgs) (reply *ReadReply, err error) { 39 | reply = new(ReadReply) 40 | if args != nil { 41 | err = rpcc.Invoke(ctx, "IO.read", args, reply, d.conn) 42 | } else { 43 | err = rpcc.Invoke(ctx, "IO.read", nil, reply, d.conn) 44 | } 45 | if err != nil { 46 | err = &internal.OpError{Domain: "IO", Op: "Read", Err: err} 47 | } 48 | return 49 | } 50 | 51 | // ResolveBlob invokes the IO method. Return UUID of Blob object specified by 52 | // a remote object id. 53 | func (d *domainClient) ResolveBlob(ctx context.Context, args *ResolveBlobArgs) (reply *ResolveBlobReply, err error) { 54 | reply = new(ResolveBlobReply) 55 | if args != nil { 56 | err = rpcc.Invoke(ctx, "IO.resolveBlob", args, reply, d.conn) 57 | } else { 58 | err = rpcc.Invoke(ctx, "IO.resolveBlob", nil, reply, d.conn) 59 | } 60 | if err != nil { 61 | err = &internal.OpError{Domain: "IO", Op: "ResolveBlob", Err: err} 62 | } 63 | return 64 | } 65 | -------------------------------------------------------------------------------- /protocol/io/stream_reader.go: -------------------------------------------------------------------------------- 1 | package io 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "encoding/base64" 7 | "io" 8 | "strings" 9 | "time" 10 | ) 11 | 12 | // StreamReader represents a stream reader. 13 | type StreamReader struct { 14 | next func(pos, size int) (*ReadReply, error) 15 | close func() error 16 | r io.Reader 17 | pos int 18 | eof bool 19 | } 20 | 21 | var _ io.ReadCloser = (*StreamReader)(nil) 22 | 23 | // NewStreamReader returns a reader for io.Streams that implements io.Reader 24 | // from the standard library. 25 | func NewStreamReader(ctx context.Context, ioClient interface { 26 | Read(context.Context, *ReadArgs) (*ReadReply, error) 27 | Close(context.Context, *CloseArgs) error 28 | }, handle StreamHandle, 29 | ) *StreamReader { 30 | args := NewReadArgs(handle) 31 | return &StreamReader{ 32 | next: func(pos, size int) (*ReadReply, error) { 33 | args.SetOffset(pos).SetSize(size) 34 | return ioClient.Read(ctx, args) 35 | }, 36 | close: func() error { 37 | // TODO(mafredri): We should ideally allow the user to define a timeout here. 38 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 39 | defer cancel() 40 | 41 | return ioClient.Close(ctx, NewCloseArgs(handle)) 42 | }, 43 | } 44 | } 45 | 46 | func (r *StreamReader) read(p []byte) (n int, err error) { 47 | n, err = r.r.Read(p) 48 | r.pos += n 49 | if !r.eof && err == io.EOF { 50 | r.r = nil 51 | err = nil 52 | } 53 | return n, err 54 | } 55 | 56 | // Read a chunk of the stream. 57 | func (r *StreamReader) Read(p []byte) (n int, err error) { 58 | if r.r != nil { 59 | // Continue reading from buffer. 60 | return r.read(p) 61 | } 62 | if r.eof { 63 | return 0, io.EOF 64 | } 65 | if len(p) == 0 { 66 | return 0, nil 67 | } 68 | 69 | // Chrome might have an off-by-one when deciding the maximum 70 | // size (at least for base64 encoded data), usually it will 71 | // overflow. We subtract one to make sure it fits into p. 72 | size := len(p) - 1 73 | if size < 1 { 74 | // Safety-check to avoid crashing Chrome (e.g. via SetSize(-1)). 75 | size = 1 76 | } 77 | 78 | reply, err := r.next(r.pos, size) 79 | if err != nil { 80 | return 0, err 81 | } 82 | 83 | r.eof = reply.EOF 84 | 85 | switch { 86 | case reply.Base64Encoded != nil && *reply.Base64Encoded: 87 | b := []byte(reply.Data) 88 | size := base64.StdEncoding.DecodedLen(len(b)) 89 | 90 | // Safety-check for fast-path to avoid panics. 91 | if len(p) >= size { 92 | n, err = base64.StdEncoding.Decode(p, b) 93 | r.pos += n 94 | return n, err 95 | } 96 | 97 | r.r = base64.NewDecoder(base64.StdEncoding, bytes.NewReader(b)) 98 | default: 99 | r.r = strings.NewReader(reply.Data) 100 | } 101 | 102 | return r.read(p) 103 | } 104 | 105 | // Close the stream, discard any temporary backing storage. 106 | func (r *StreamReader) Close() error { 107 | return r.close() 108 | } 109 | -------------------------------------------------------------------------------- /protocol/io/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package io 4 | 5 | // StreamHandle This is either obtained from another method or specified as 6 | // `blob:` where `` is an UUID of a Blob. 7 | type StreamHandle string 8 | -------------------------------------------------------------------------------- /protocol/layertree/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package layertree 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/dom" 7 | "github.com/mafredri/cdp/rpcc" 8 | ) 9 | 10 | // LayerPaintedClient is a client for LayerPainted events. 11 | type LayerPaintedClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*LayerPaintedReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // LayerPaintedReply is the reply for LayerPainted events. 19 | type LayerPaintedReply struct { 20 | LayerID LayerID `json:"layerId"` // The id of the painted layer. 21 | Clip dom.Rect `json:"clip"` // Clip rectangle. 22 | } 23 | 24 | // DidChangeClient is a client for LayerTreeDidChange events. 25 | type DidChangeClient interface { 26 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 27 | // triggered, context canceled or connection closed. 28 | Recv() (*DidChangeReply, error) 29 | rpcc.Stream 30 | } 31 | 32 | // DidChangeReply is the reply for LayerTreeDidChange events. 33 | type DidChangeReply struct { 34 | Layers []Layer `json:"layers,omitempty"` // Layer tree, absent if not in the compositing mode. 35 | } 36 | -------------------------------------------------------------------------------- /protocol/log/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package log 4 | 5 | // StartViolationsReportArgs represents the arguments for StartViolationsReport in the Log domain. 6 | type StartViolationsReportArgs struct { 7 | Config []ViolationSetting `json:"config"` // Configuration for violations. 8 | } 9 | 10 | // NewStartViolationsReportArgs initializes StartViolationsReportArgs with the required arguments. 11 | func NewStartViolationsReportArgs(config []ViolationSetting) *StartViolationsReportArgs { 12 | args := new(StartViolationsReportArgs) 13 | args.Config = config 14 | return args 15 | } 16 | -------------------------------------------------------------------------------- /protocol/log/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package log 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // EntryAddedClient is a client for EntryAdded events. Issued when new message 10 | // was logged. 11 | type EntryAddedClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*EntryAddedReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // EntryAddedReply is the reply for EntryAdded events. 19 | type EntryAddedReply struct { 20 | Entry Entry `json:"entry"` // The entry. 21 | } 22 | -------------------------------------------------------------------------------- /protocol/log/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package log 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/network" 7 | "github.com/mafredri/cdp/protocol/runtime" 8 | ) 9 | 10 | // Entry Log entry. 11 | type Entry struct { 12 | // Source Log entry source. 13 | // 14 | // Values: "xml", "javascript", "network", "storage", "appcache", "rendering", "security", "deprecation", "worker", "violation", "intervention", "recommendation", "other". 15 | Source string `json:"source"` 16 | // Level Log entry severity. 17 | // 18 | // Values: "verbose", "info", "warning", "error". 19 | Level string `json:"level"` 20 | Text string `json:"text"` // Logged text. 21 | // Category 22 | // 23 | // Values: "cors". 24 | Category *string `json:"category,omitempty"` 25 | Timestamp runtime.Timestamp `json:"timestamp"` // Timestamp when this entry was added. 26 | URL *string `json:"url,omitempty"` // URL of the resource if known. 27 | LineNumber *int `json:"lineNumber,omitempty"` // Line number in the resource. 28 | StackTrace *runtime.StackTrace `json:"stackTrace,omitempty"` // JavaScript stack trace. 29 | NetworkRequestID *network.RequestID `json:"networkRequestId,omitempty"` // Identifier of the network request associated with this entry. 30 | WorkerID *string `json:"workerId,omitempty"` // Identifier of the worker associated with this entry. 31 | Args []runtime.RemoteObject `json:"args,omitempty"` // Call arguments. 32 | } 33 | 34 | // ViolationSetting Violation configuration setting. 35 | type ViolationSetting struct { 36 | // Name Violation type. 37 | // 38 | // Values: "longTask", "longLayout", "blockedEvent", "blockedParser", "discouragedAPIUse", "handler", "recurringHandler". 39 | Name string `json:"name"` 40 | Threshold float64 `json:"threshold"` // Time threshold to trigger upon. 41 | } 42 | -------------------------------------------------------------------------------- /protocol/memory/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package memory 4 | 5 | // PressureLevel Memory pressure level. 6 | type PressureLevel string 7 | 8 | // PressureLevel as enums. 9 | const ( 10 | PressureLevelNotSet PressureLevel = "" 11 | PressureLevelModerate PressureLevel = "moderate" 12 | PressureLevelCritical PressureLevel = "critical" 13 | ) 14 | 15 | func (e PressureLevel) Valid() bool { 16 | switch e { 17 | case "moderate", "critical": 18 | return true 19 | default: 20 | return false 21 | } 22 | } 23 | 24 | func (e PressureLevel) String() string { 25 | return string(e) 26 | } 27 | 28 | // SamplingProfileNode Heap profile sample. 29 | type SamplingProfileNode struct { 30 | Size float64 `json:"size"` // Size of the sampled allocation. 31 | Total float64 `json:"total"` // Total bytes attributed to this sample. 32 | Stack []string `json:"stack"` // Execution stack at the point of allocation. 33 | } 34 | 35 | // SamplingProfile Array of heap profile samples. 36 | type SamplingProfile struct { 37 | Samples []SamplingProfileNode `json:"samples"` // No description. 38 | Modules []Module `json:"modules"` // No description. 39 | } 40 | 41 | // Module Executable module information 42 | type Module struct { 43 | Name string `json:"name"` // Name of the module. 44 | UUID string `json:"uuid"` // UUID of the module. 45 | BaseAddress string `json:"baseAddress"` // Base address where the module is loaded into memory. Encoded as a decimal or hexadecimal (0x prefixed) string. 46 | Size float64 `json:"size"` // Size of the module in bytes. 47 | } 48 | 49 | // DOMCounter DOM object counter data. 50 | type DOMCounter struct { 51 | Name string `json:"name"` // Object name. Note: object names should be presumed volatile and clients should not expect the returned names to be consistent across runs. 52 | Count int `json:"count"` // Object count. 53 | } 54 | -------------------------------------------------------------------------------- /protocol/network/util.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | // Map returns the headers decoded into a map. 8 | func (n Headers) Map() (map[string]string, error) { 9 | m := make(map[string]string) 10 | err := json.Unmarshal(n, &m) 11 | return m, err 12 | } 13 | -------------------------------------------------------------------------------- /protocol/overlay/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package overlay 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/dom" 7 | "github.com/mafredri/cdp/protocol/page" 8 | "github.com/mafredri/cdp/rpcc" 9 | ) 10 | 11 | // InspectNodeRequestedClient is a client for InspectNodeRequested events. 12 | // Fired when the node should be inspected. This happens after call to 13 | // `setInspectMode` or when user manually inspects an element. 14 | type InspectNodeRequestedClient interface { 15 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 16 | // triggered, context canceled or connection closed. 17 | Recv() (*InspectNodeRequestedReply, error) 18 | rpcc.Stream 19 | } 20 | 21 | // InspectNodeRequestedReply is the reply for InspectNodeRequested events. 22 | type InspectNodeRequestedReply struct { 23 | BackendNodeID dom.BackendNodeID `json:"backendNodeId"` // Id of the node to inspect. 24 | } 25 | 26 | // NodeHighlightRequestedClient is a client for NodeHighlightRequested events. 27 | // Fired when the node should be highlighted. This happens after call to 28 | // `setInspectMode`. 29 | type NodeHighlightRequestedClient interface { 30 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 31 | // triggered, context canceled or connection closed. 32 | Recv() (*NodeHighlightRequestedReply, error) 33 | rpcc.Stream 34 | } 35 | 36 | // NodeHighlightRequestedReply is the reply for NodeHighlightRequested events. 37 | type NodeHighlightRequestedReply struct { 38 | NodeID dom.NodeID `json:"nodeId"` // No description. 39 | } 40 | 41 | // ScreenshotRequestedClient is a client for ScreenshotRequested events. Fired 42 | // when user asks to capture screenshot of some area on the page. 43 | type ScreenshotRequestedClient interface { 44 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 45 | // triggered, context canceled or connection closed. 46 | Recv() (*ScreenshotRequestedReply, error) 47 | rpcc.Stream 48 | } 49 | 50 | // ScreenshotRequestedReply is the reply for ScreenshotRequested events. 51 | type ScreenshotRequestedReply struct { 52 | Viewport page.Viewport `json:"viewport"` // Viewport to capture, in device independent pixels (dip). 53 | } 54 | 55 | // InspectModeCanceledClient is a client for InspectModeCanceled events. Fired 56 | // when user cancels the inspect mode. 57 | type InspectModeCanceledClient interface { 58 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 59 | // triggered, context canceled or connection closed. 60 | Recv() (*InspectModeCanceledReply, error) 61 | rpcc.Stream 62 | } 63 | 64 | // InspectModeCanceledReply is the reply for InspectModeCanceled events. 65 | type InspectModeCanceledReply struct { 66 | } 67 | -------------------------------------------------------------------------------- /protocol/performance/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package performance 4 | 5 | // EnableArgs represents the arguments for Enable in the Performance domain. 6 | type EnableArgs struct { 7 | // TimeDomain Time domain to use for collecting and reporting duration 8 | // metrics. 9 | // 10 | // Values: "timeTicks", "threadTicks". 11 | TimeDomain *string `json:"timeDomain,omitempty"` 12 | } 13 | 14 | // NewEnableArgs initializes EnableArgs with the required arguments. 15 | func NewEnableArgs() *EnableArgs { 16 | args := new(EnableArgs) 17 | 18 | return args 19 | } 20 | 21 | // SetTimeDomain sets the TimeDomain optional argument. Time domain to 22 | // use for collecting and reporting duration metrics. 23 | // 24 | // Values: "timeTicks", "threadTicks". 25 | func (a *EnableArgs) SetTimeDomain(timeDomain string) *EnableArgs { 26 | a.TimeDomain = &timeDomain 27 | return a 28 | } 29 | 30 | // SetTimeDomainArgs represents the arguments for SetTimeDomain in the Performance domain. 31 | type SetTimeDomainArgs struct { 32 | // TimeDomain Time domain 33 | // 34 | // Values: "timeTicks", "threadTicks". 35 | TimeDomain string `json:"timeDomain"` 36 | } 37 | 38 | // NewSetTimeDomainArgs initializes SetTimeDomainArgs with the required arguments. 39 | func NewSetTimeDomainArgs(timeDomain string) *SetTimeDomainArgs { 40 | args := new(SetTimeDomainArgs) 41 | args.TimeDomain = timeDomain 42 | return args 43 | } 44 | 45 | // GetMetricsReply represents the return values for GetMetrics in the Performance domain. 46 | type GetMetricsReply struct { 47 | Metrics []Metric `json:"metrics"` // Current values for run-time metrics. 48 | } 49 | -------------------------------------------------------------------------------- /protocol/performance/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package performance implements the Performance domain. 4 | package performance 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/mafredri/cdp/protocol/internal" 10 | "github.com/mafredri/cdp/rpcc" 11 | ) 12 | 13 | // domainClient is a client for the Performance domain. 14 | type domainClient struct{ conn *rpcc.Conn } 15 | 16 | // NewClient returns a client for the Performance domain with the connection set to conn. 17 | func NewClient(conn *rpcc.Conn) *domainClient { 18 | return &domainClient{conn: conn} 19 | } 20 | 21 | // Disable invokes the Performance method. Disable collecting and reporting 22 | // metrics. 23 | func (d *domainClient) Disable(ctx context.Context) (err error) { 24 | err = rpcc.Invoke(ctx, "Performance.disable", nil, nil, d.conn) 25 | if err != nil { 26 | err = &internal.OpError{Domain: "Performance", Op: "Disable", Err: err} 27 | } 28 | return 29 | } 30 | 31 | // Enable invokes the Performance method. Enable collecting and reporting 32 | // metrics. 33 | func (d *domainClient) Enable(ctx context.Context, args *EnableArgs) (err error) { 34 | if args != nil { 35 | err = rpcc.Invoke(ctx, "Performance.enable", args, nil, d.conn) 36 | } else { 37 | err = rpcc.Invoke(ctx, "Performance.enable", nil, nil, d.conn) 38 | } 39 | if err != nil { 40 | err = &internal.OpError{Domain: "Performance", Op: "Enable", Err: err} 41 | } 42 | return 43 | } 44 | 45 | // SetTimeDomain invokes the Performance method. Sets time domain to use for 46 | // collecting and reporting duration metrics. Note that this must be called 47 | // before enabling metrics collection. Calling this method while metrics 48 | // collection is enabled returns an error. 49 | func (d *domainClient) SetTimeDomain(ctx context.Context, args *SetTimeDomainArgs) (err error) { 50 | if args != nil { 51 | err = rpcc.Invoke(ctx, "Performance.setTimeDomain", args, nil, d.conn) 52 | } else { 53 | err = rpcc.Invoke(ctx, "Performance.setTimeDomain", nil, nil, d.conn) 54 | } 55 | if err != nil { 56 | err = &internal.OpError{Domain: "Performance", Op: "SetTimeDomain", Err: err} 57 | } 58 | return 59 | } 60 | 61 | // GetMetrics invokes the Performance method. Retrieve current values of 62 | // run-time metrics. 63 | func (d *domainClient) GetMetrics(ctx context.Context) (reply *GetMetricsReply, err error) { 64 | reply = new(GetMetricsReply) 65 | err = rpcc.Invoke(ctx, "Performance.getMetrics", nil, reply, d.conn) 66 | if err != nil { 67 | err = &internal.OpError{Domain: "Performance", Op: "GetMetrics", Err: err} 68 | } 69 | return 70 | } 71 | 72 | func (d *domainClient) Metrics(ctx context.Context) (MetricsClient, error) { 73 | s, err := rpcc.NewStream(ctx, "Performance.metrics", d.conn) 74 | if err != nil { 75 | return nil, err 76 | } 77 | return &metricsClient{Stream: s}, nil 78 | } 79 | 80 | type metricsClient struct{ rpcc.Stream } 81 | 82 | // GetStream returns the original Stream for use with cdp.Sync. 83 | func (c *metricsClient) GetStream() rpcc.Stream { return c.Stream } 84 | 85 | func (c *metricsClient) Recv() (*MetricsReply, error) { 86 | event := new(MetricsReply) 87 | if err := c.RecvMsg(event); err != nil { 88 | return nil, &internal.OpError{Domain: "Performance", Op: "Metrics Recv", Err: err} 89 | } 90 | return event, nil 91 | } 92 | -------------------------------------------------------------------------------- /protocol/performance/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package performance 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // MetricsClient is a client for Metrics events. Current values of the 10 | // metrics. 11 | type MetricsClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*MetricsReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // MetricsReply is the reply for Metrics events. 19 | type MetricsReply struct { 20 | Metrics []Metric `json:"metrics"` // Current values of the metrics. 21 | Title string `json:"title"` // Timestamp title. 22 | } 23 | -------------------------------------------------------------------------------- /protocol/performance/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package performance 4 | 5 | // Metric Run-time execution metric. 6 | type Metric struct { 7 | Name string `json:"name"` // Metric name. 8 | Value float64 `json:"value"` // Metric value. 9 | } 10 | -------------------------------------------------------------------------------- /protocol/performancetimeline/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package performancetimeline 4 | 5 | // EnableArgs represents the arguments for Enable in the PerformanceTimeline domain. 6 | type EnableArgs struct { 7 | EventTypes []string `json:"eventTypes"` // The types of event to report, as specified in https://w3c.github.io/performance-timeline/#dom-performanceentry-entrytype The specified filter overrides any previous filters, passing empty filter disables recording. Note that not all types exposed to the web platform are currently supported. 8 | } 9 | 10 | // NewEnableArgs initializes EnableArgs with the required arguments. 11 | func NewEnableArgs(eventTypes []string) *EnableArgs { 12 | args := new(EnableArgs) 13 | args.EventTypes = eventTypes 14 | return args 15 | } 16 | -------------------------------------------------------------------------------- /protocol/performancetimeline/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package performancetimeline implements the PerformanceTimeline domain. 4 | // Reporting of performance timeline events, as specified in 5 | // https://w3c.github.io/performance-timeline/#dom-performanceobserver. 6 | package performancetimeline 7 | 8 | import ( 9 | "context" 10 | 11 | "github.com/mafredri/cdp/protocol/internal" 12 | "github.com/mafredri/cdp/rpcc" 13 | ) 14 | 15 | // domainClient is a client for the PerformanceTimeline domain. Reporting of 16 | // performance timeline events, as specified in 17 | // https://w3c.github.io/performance-timeline/#dom-performanceobserver. 18 | type domainClient struct{ conn *rpcc.Conn } 19 | 20 | // NewClient returns a client for the PerformanceTimeline domain with the connection set to conn. 21 | func NewClient(conn *rpcc.Conn) *domainClient { 22 | return &domainClient{conn: conn} 23 | } 24 | 25 | // Enable invokes the PerformanceTimeline method. Previously buffered events 26 | // would be reported before method returns. See also: timelineEventAdded 27 | func (d *domainClient) Enable(ctx context.Context, args *EnableArgs) (err error) { 28 | if args != nil { 29 | err = rpcc.Invoke(ctx, "PerformanceTimeline.enable", args, nil, d.conn) 30 | } else { 31 | err = rpcc.Invoke(ctx, "PerformanceTimeline.enable", nil, nil, d.conn) 32 | } 33 | if err != nil { 34 | err = &internal.OpError{Domain: "PerformanceTimeline", Op: "Enable", Err: err} 35 | } 36 | return 37 | } 38 | 39 | func (d *domainClient) TimelineEventAdded(ctx context.Context) (TimelineEventAddedClient, error) { 40 | s, err := rpcc.NewStream(ctx, "PerformanceTimeline.timelineEventAdded", d.conn) 41 | if err != nil { 42 | return nil, err 43 | } 44 | return &timelineEventAddedClient{Stream: s}, nil 45 | } 46 | 47 | type timelineEventAddedClient struct{ rpcc.Stream } 48 | 49 | // GetStream returns the original Stream for use with cdp.Sync. 50 | func (c *timelineEventAddedClient) GetStream() rpcc.Stream { return c.Stream } 51 | 52 | func (c *timelineEventAddedClient) Recv() (*TimelineEventAddedReply, error) { 53 | event := new(TimelineEventAddedReply) 54 | if err := c.RecvMsg(event); err != nil { 55 | return nil, &internal.OpError{Domain: "PerformanceTimeline", Op: "TimelineEventAdded Recv", Err: err} 56 | } 57 | return event, nil 58 | } 59 | -------------------------------------------------------------------------------- /protocol/performancetimeline/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package performancetimeline 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // TimelineEventAddedClient is a client for TimelineEventAdded events. Sent 10 | // when a performance timeline event is added. See reportPerformanceTimeline 11 | // method. 12 | type TimelineEventAddedClient interface { 13 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 14 | // triggered, context canceled or connection closed. 15 | Recv() (*TimelineEventAddedReply, error) 16 | rpcc.Stream 17 | } 18 | 19 | // TimelineEventAddedReply is the reply for TimelineEventAdded events. 20 | type TimelineEventAddedReply struct { 21 | Event TimelineEvent `json:"event"` // No description. 22 | } 23 | -------------------------------------------------------------------------------- /protocol/performancetimeline/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package performancetimeline 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/dom" 7 | "github.com/mafredri/cdp/protocol/network" 8 | "github.com/mafredri/cdp/protocol/page" 9 | ) 10 | 11 | // LargestContentfulPaint See https://github.com/WICG/LargestContentfulPaint 12 | // and largest_contentful_paint.idl 13 | type LargestContentfulPaint struct { 14 | RenderTime network.TimeSinceEpoch `json:"renderTime"` // No description. 15 | LoadTime network.TimeSinceEpoch `json:"loadTime"` // No description. 16 | Size float64 `json:"size"` // The number of pixels being painted. 17 | ElementID *string `json:"elementId,omitempty"` // The id attribute of the element, if available. 18 | URL *string `json:"url,omitempty"` // The URL of the image (may be trimmed). 19 | NodeID *dom.BackendNodeID `json:"nodeId,omitempty"` // No description. 20 | } 21 | 22 | // LayoutShiftAttribution 23 | type LayoutShiftAttribution struct { 24 | PreviousRect dom.Rect `json:"previousRect"` // No description. 25 | CurrentRect dom.Rect `json:"currentRect"` // No description. 26 | NodeID *dom.BackendNodeID `json:"nodeId,omitempty"` // No description. 27 | } 28 | 29 | // LayoutShift See https://wicg.github.io/layout-instability/#sec-layout-shift 30 | // and layout_shift.idl 31 | type LayoutShift struct { 32 | Value float64 `json:"value"` // Score increment produced by this event. 33 | HadRecentInput bool `json:"hadRecentInput"` // No description. 34 | LastInputTime network.TimeSinceEpoch `json:"lastInputTime"` // No description. 35 | Sources []LayoutShiftAttribution `json:"sources"` // No description. 36 | } 37 | 38 | // TimelineEvent 39 | type TimelineEvent struct { 40 | FrameID page.FrameID `json:"frameId"` // Identifies the frame that this event is related to. Empty for non-frame targets. 41 | Type string `json:"type"` // The event type, as specified in https://w3c.github.io/performance-timeline/#dom-performanceentry-entrytype This determines which of the optional "details" fields is present. 42 | Name string `json:"name"` // Name may be empty depending on the type. 43 | Time network.TimeSinceEpoch `json:"time"` // Time in seconds since Epoch, monotonically increasing within document lifetime. 44 | Duration *float64 `json:"duration,omitempty"` // Event duration, if applicable. 45 | LcpDetails *LargestContentfulPaint `json:"lcpDetails,omitempty"` // No description. 46 | LayoutShiftDetails *LayoutShift `json:"layoutShiftDetails,omitempty"` // No description. 47 | } 48 | -------------------------------------------------------------------------------- /protocol/profiler/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package profiler 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/debugger" 7 | "github.com/mafredri/cdp/rpcc" 8 | ) 9 | 10 | // ConsoleProfileFinishedClient is a client for ConsoleProfileFinished events. 11 | type ConsoleProfileFinishedClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*ConsoleProfileFinishedReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // ConsoleProfileFinishedReply is the reply for ConsoleProfileFinished events. 19 | type ConsoleProfileFinishedReply struct { 20 | ID string `json:"id"` // No description. 21 | Location debugger.Location `json:"location"` // Location of console.profileEnd(). 22 | Profile Profile `json:"profile"` // No description. 23 | Title *string `json:"title,omitempty"` // Profile title passed as an argument to console.profile(). 24 | } 25 | 26 | // ConsoleProfileStartedClient is a client for ConsoleProfileStarted events. 27 | // Sent when new profile recording is started using console.profile() call. 28 | type ConsoleProfileStartedClient interface { 29 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 30 | // triggered, context canceled or connection closed. 31 | Recv() (*ConsoleProfileStartedReply, error) 32 | rpcc.Stream 33 | } 34 | 35 | // ConsoleProfileStartedReply is the reply for ConsoleProfileStarted events. 36 | type ConsoleProfileStartedReply struct { 37 | ID string `json:"id"` // No description. 38 | Location debugger.Location `json:"location"` // Location of console.profile(). 39 | Title *string `json:"title,omitempty"` // Profile title passed as an argument to console.profile(). 40 | } 41 | 42 | // PreciseCoverageDeltaUpdateClient is a client for PreciseCoverageDeltaUpdate events. 43 | // Reports coverage delta since the last poll (either from an event like this, 44 | // or from `takePreciseCoverage` for the current isolate. May only be sent if 45 | // precise code coverage has been started. This event can be trigged by the 46 | // embedder to, for example, trigger collection of coverage data immediately at 47 | // a certain point in time. 48 | type PreciseCoverageDeltaUpdateClient interface { 49 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 50 | // triggered, context canceled or connection closed. 51 | Recv() (*PreciseCoverageDeltaUpdateReply, error) 52 | rpcc.Stream 53 | } 54 | 55 | // PreciseCoverageDeltaUpdateReply is the reply for PreciseCoverageDeltaUpdate events. 56 | type PreciseCoverageDeltaUpdateReply struct { 57 | Timestamp float64 `json:"timestamp"` // Monotonically increasing time (in seconds) when the coverage update was taken in the backend. 58 | Occasion string `json:"occasion"` // Identifier for distinguishing coverage events. 59 | Result []ScriptCoverage `json:"result"` // Coverage data for the current isolate. 60 | } 61 | -------------------------------------------------------------------------------- /protocol/profiler/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package profiler 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/runtime" 7 | ) 8 | 9 | // ProfileNode Profile node. Holds callsite information, execution statistics 10 | // and child nodes. 11 | type ProfileNode struct { 12 | ID int `json:"id"` // Unique id of the node. 13 | CallFrame runtime.CallFrame `json:"callFrame"` // Function location. 14 | HitCount *int `json:"hitCount,omitempty"` // Number of samples where this node was on top of the call stack. 15 | Children []int `json:"children,omitempty"` // Child node ids. 16 | DeoptReason *string `json:"deoptReason,omitempty"` // The reason of being not optimized. The function may be deoptimized or marked as don't optimize. 17 | PositionTicks []PositionTickInfo `json:"positionTicks,omitempty"` // An array of source position ticks. 18 | } 19 | 20 | // Profile Profile. 21 | type Profile struct { 22 | Nodes []ProfileNode `json:"nodes"` // The list of profile nodes. First item is the root node. 23 | StartTime float64 `json:"startTime"` // Profiling start timestamp in microseconds. 24 | EndTime float64 `json:"endTime"` // Profiling end timestamp in microseconds. 25 | Samples []int `json:"samples,omitempty"` // Ids of samples top nodes. 26 | TimeDeltas []int `json:"timeDeltas,omitempty"` // Time intervals between adjacent samples in microseconds. The first delta is relative to the profile startTime. 27 | } 28 | 29 | // PositionTickInfo Specifies a number of samples attributed to a certain 30 | // source position. 31 | type PositionTickInfo struct { 32 | Line int `json:"line"` // Source line number (1-based). 33 | Ticks int `json:"ticks"` // Number of samples attributed to the source line. 34 | } 35 | 36 | // CoverageRange Coverage data for a source range. 37 | type CoverageRange struct { 38 | StartOffset int `json:"startOffset"` // JavaScript script source offset for the range start. 39 | EndOffset int `json:"endOffset"` // JavaScript script source offset for the range end. 40 | Count int `json:"count"` // Collected execution count of the source range. 41 | } 42 | 43 | // FunctionCoverage Coverage data for a JavaScript function. 44 | type FunctionCoverage struct { 45 | FunctionName string `json:"functionName"` // JavaScript function name. 46 | Ranges []CoverageRange `json:"ranges"` // Source ranges inside the function with coverage data. 47 | IsBlockCoverage bool `json:"isBlockCoverage"` // Whether coverage data for this function has block granularity. 48 | } 49 | 50 | // ScriptCoverage Coverage data for a JavaScript script. 51 | type ScriptCoverage struct { 52 | ScriptID runtime.ScriptID `json:"scriptId"` // JavaScript script id. 53 | URL string `json:"url"` // JavaScript script name or url. 54 | Functions []FunctionCoverage `json:"functions"` // Functions contained in the script that has coverage data. 55 | } 56 | -------------------------------------------------------------------------------- /protocol/pwa/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package pwa 4 | 5 | // FileHandlerAccept The following types are the replica of 6 | // https://crsrc.org/c/chrome/browser/web_applications/proto/web_app_os_integration_state.proto;drc=9910d3be894c8f142c977ba1023f30a656bc13fc;l=67 7 | type FileHandlerAccept struct { 8 | MediaType string `json:"mediaType"` // New name of the mimetype according to https://www.iana.org/assignments/media-types/media-types.xhtml 9 | FileExtensions []string `json:"fileExtensions"` // No description. 10 | } 11 | 12 | // FileHandler 13 | type FileHandler struct { 14 | Action string `json:"action"` // No description. 15 | Accepts []FileHandlerAccept `json:"accepts"` // No description. 16 | DisplayName string `json:"displayName"` // No description. 17 | } 18 | 19 | // DisplayMode If user prefers opening the app in browser or an app window. 20 | type DisplayMode string 21 | 22 | // DisplayMode as enums. 23 | const ( 24 | DisplayModeNotSet DisplayMode = "" 25 | DisplayModeStandalone DisplayMode = "standalone" 26 | DisplayModeBrowser DisplayMode = "browser" 27 | ) 28 | 29 | func (e DisplayMode) Valid() bool { 30 | switch e { 31 | case "standalone", "browser": 32 | return true 33 | default: 34 | return false 35 | } 36 | } 37 | 38 | func (e DisplayMode) String() string { 39 | return string(e) 40 | } 41 | -------------------------------------------------------------------------------- /protocol/runtime/testdata/log.golden: -------------------------------------------------------------------------------- 1 | "foo" 2 | String 3 | 42 4 | Number 5 | Infinity 6 | -Infinity 7 | NaN 8 | Number 9 | true 10 | Boolean 11 | undefined 12 | null 13 | Object 14 | Object 15 | Object 16 | Object 17 | Array(0) 18 | Array(4) 19 | 1257894000000 20 | Wed Nov 11 2009 01:00:00 GMT+0200 (Eastern European Standard Time) 21 | /\/.*\//g 22 | /\/$^\// 23 | Symbol(=)) 24 | Symbol(=() 25 | Map(1) 26 | Map(0) 27 | Map(1) 28 | WeakMap 29 | Set(3) 30 | Set(0) 31 | Set(3) 32 | WeakSet 33 | Promise 34 | Promise 35 | Uint8Array(2) 36 | Int8Array(0) 37 | function() {} 38 | () => {} 39 | "foo" 40 | String("bar") 41 | 42 42 | Number(9001) 43 | Infinity 44 | -Infinity 45 | NaN 46 | Number(NaN) 47 | true 48 | Boolean(false) 49 | undefined 50 | null 51 | Object {} 52 | Object {:^): "^_^", ping: "pong", t: -10} 53 | Object {a: 1} 54 | Object {a: true, b: false, c: Object, d: Array(0), e: Wed Nov 11 2009 01:00:00 GMT+0200 (Eastern European Standard Time), ...} 55 | Array(0) [] 56 | Array(4) [1, 2.333, 666, Object] 57 | 1257894000000 58 | Wed Nov 11 2009 01:00:00 GMT+0200 (Eastern European Standard Time) 59 | /\/.*\//g 60 | /\/$^\// 61 | Symbol(=)) 62 | Symbol(=() 63 | Map(1) {true => false} 64 | Map(0) {} 65 | Map(1) {1337 => "hello"} 66 | WeakMap {} 67 | Set(3) {true, false, null} 68 | Set(0) {} 69 | Set(3) {1, 2, 3} 70 | WeakSet {} 71 | Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined} 72 | Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "'ello"} 73 | Uint8Array(2) [1, 0] 74 | Int8Array(0) [] 75 | function() {} 76 | () => {} 77 | -------------------------------------------------------------------------------- /protocol/runtime/testdata/log.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Console log 5 | 6 | 7 | 65 | 66 | -------------------------------------------------------------------------------- /protocol/runtime/util_test.go: -------------------------------------------------------------------------------- 1 | package runtime_test 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "encoding/json" 7 | "flag" 8 | "io" 9 | "io/ioutil" 10 | "path/filepath" 11 | "testing" 12 | 13 | "github.com/mafredri/cdp/protocol/runtime" 14 | ) 15 | 16 | var update = flag.Bool("update", false, "update .golden files") 17 | 18 | func TestRuntimeRemoteObject_String(t *testing.T) { 19 | in := filepath.Join("testdata", "log.input") 20 | input, err := ioutil.ReadFile(in) 21 | if err != nil { 22 | t.Fatal(err) 23 | } 24 | 25 | scanner := bufio.NewScanner(bytes.NewReader(input)) 26 | var buf bytes.Buffer 27 | 28 | for scanner.Scan() { 29 | var logEv runtime.ConsoleAPICalledReply 30 | err := json.Unmarshal(scanner.Bytes(), &logEv) 31 | if err != nil { 32 | t.Fatal(err) 33 | } 34 | for _, arg := range logEv.Args { 35 | buf.WriteString(arg.String()) 36 | buf.WriteByte('\n') 37 | } 38 | } 39 | if err := scanner.Err(); err != nil { 40 | t.Fatal(err) 41 | } 42 | 43 | out := filepath.Join("testdata", "log.golden") 44 | want, err := ioutil.ReadFile(out) 45 | if err != nil { 46 | t.Fatal(err) 47 | } 48 | 49 | if got := buf.Bytes(); !bytes.Equal(got, want) { 50 | if *update { 51 | err := ioutil.WriteFile(out, got, 0o666) 52 | if err != nil { 53 | t.Error(err) 54 | } 55 | return 56 | } 57 | t.Error("output does not match golden file") 58 | showDiff(t, got, want) 59 | } 60 | } 61 | 62 | func showDiff(t testing.TB, got, want []byte) { 63 | gr := bufio.NewReader(bytes.NewReader(got)) 64 | wr := bufio.NewReader(bytes.NewReader(want)) 65 | var lineno int 66 | for { 67 | lineno++ 68 | g, err1 := gr.ReadBytes('\n') 69 | w, err2 := wr.ReadBytes('\n') 70 | if err1 != nil || err2 != nil { 71 | if err1 != io.EOF || err2 != io.EOF { 72 | t.Error(err1, err2) 73 | } 74 | break 75 | } 76 | if !bytes.Equal(g, w) { 77 | t.Errorf("line %d: got %s; want %s", lineno, g[:len(g)-1], w[:len(w)-1]) 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /protocol/schema/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package schema 4 | 5 | // GetDomainsReply represents the return values for GetDomains in the Schema domain. 6 | type GetDomainsReply struct { 7 | Domains []Domain `json:"domains"` // List of supported domains. 8 | } 9 | -------------------------------------------------------------------------------- /protocol/schema/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package schema implements the Schema domain. This domain is deprecated. 4 | package schema 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/mafredri/cdp/protocol/internal" 10 | "github.com/mafredri/cdp/rpcc" 11 | ) 12 | 13 | // domainClient is a client for the Schema domain. This domain is deprecated. 14 | type domainClient struct{ conn *rpcc.Conn } 15 | 16 | // NewClient returns a client for the Schema domain with the connection set to conn. 17 | func NewClient(conn *rpcc.Conn) *domainClient { 18 | return &domainClient{conn: conn} 19 | } 20 | 21 | // GetDomains invokes the Schema method. Returns supported domains. 22 | func (d *domainClient) GetDomains(ctx context.Context) (reply *GetDomainsReply, err error) { 23 | reply = new(GetDomainsReply) 24 | err = rpcc.Invoke(ctx, "Schema.getDomains", nil, reply, d.conn) 25 | if err != nil { 26 | err = &internal.OpError{Domain: "Schema", Op: "GetDomains", Err: err} 27 | } 28 | return 29 | } 30 | -------------------------------------------------------------------------------- /protocol/schema/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package schema 4 | 5 | // Domain Description of the protocol domain. 6 | type Domain struct { 7 | Name string `json:"name"` // Domain name. 8 | Version string `json:"version"` // Domain version. 9 | } 10 | -------------------------------------------------------------------------------- /protocol/security/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package security 4 | 5 | // SetIgnoreCertificateErrorsArgs represents the arguments for SetIgnoreCertificateErrors in the Security domain. 6 | type SetIgnoreCertificateErrorsArgs struct { 7 | Ignore bool `json:"ignore"` // If true, all certificate errors will be ignored. 8 | } 9 | 10 | // NewSetIgnoreCertificateErrorsArgs initializes SetIgnoreCertificateErrorsArgs with the required arguments. 11 | func NewSetIgnoreCertificateErrorsArgs(ignore bool) *SetIgnoreCertificateErrorsArgs { 12 | args := new(SetIgnoreCertificateErrorsArgs) 13 | args.Ignore = ignore 14 | return args 15 | } 16 | 17 | // HandleCertificateErrorArgs represents the arguments for HandleCertificateError in the Security domain. 18 | type HandleCertificateErrorArgs struct { 19 | EventID int `json:"eventId"` // The ID of the event. 20 | Action CertificateErrorAction `json:"action"` // The action to take on the certificate error. 21 | } 22 | 23 | // NewHandleCertificateErrorArgs initializes HandleCertificateErrorArgs with the required arguments. 24 | func NewHandleCertificateErrorArgs(eventID int, action CertificateErrorAction) *HandleCertificateErrorArgs { 25 | args := new(HandleCertificateErrorArgs) 26 | args.EventID = eventID 27 | args.Action = action 28 | return args 29 | } 30 | 31 | // SetOverrideCertificateErrorsArgs represents the arguments for SetOverrideCertificateErrors in the Security domain. 32 | type SetOverrideCertificateErrorsArgs struct { 33 | Override bool `json:"override"` // If true, certificate errors will be overridden. 34 | } 35 | 36 | // NewSetOverrideCertificateErrorsArgs initializes SetOverrideCertificateErrorsArgs with the required arguments. 37 | func NewSetOverrideCertificateErrorsArgs(override bool) *SetOverrideCertificateErrorsArgs { 38 | args := new(SetOverrideCertificateErrorsArgs) 39 | args.Override = override 40 | return args 41 | } 42 | -------------------------------------------------------------------------------- /protocol/security/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package security 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // CertificateErrorClient is a client for CertificateError events. There is a 10 | // certificate error. If overriding certificate errors is enabled, then it 11 | // should be handled with the `handleCertificateError` command. Note: this 12 | // event does not fire if the certificate error has been allowed internally. 13 | // Only one client per target should override certificate errors at the same 14 | // time. 15 | type CertificateErrorClient interface { 16 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 17 | // triggered, context canceled or connection closed. 18 | Recv() (*CertificateErrorReply, error) 19 | rpcc.Stream 20 | } 21 | 22 | // CertificateErrorReply is the reply for CertificateError events. 23 | type CertificateErrorReply struct { 24 | EventID int `json:"eventId"` // The ID of the event. 25 | ErrorType string `json:"errorType"` // The type of the error. 26 | RequestURL string `json:"requestURL"` // The url that was requested. 27 | } 28 | 29 | // VisibleSecurityStateChangedClient is a client for VisibleSecurityStateChanged events. 30 | // The security state of the page changed. 31 | type VisibleSecurityStateChangedClient interface { 32 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 33 | // triggered, context canceled or connection closed. 34 | Recv() (*VisibleSecurityStateChangedReply, error) 35 | rpcc.Stream 36 | } 37 | 38 | // VisibleSecurityStateChangedReply is the reply for VisibleSecurityStateChanged events. 39 | type VisibleSecurityStateChangedReply struct { 40 | VisibleSecurityState VisibleSecurityState `json:"visibleSecurityState"` // Security state information about the page. 41 | } 42 | 43 | // StateChangedClient is a client for SecurityStateChanged events. The 44 | // security state of the page changed. No longer being sent. 45 | type StateChangedClient interface { 46 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 47 | // triggered, context canceled or connection closed. 48 | Recv() (*StateChangedReply, error) 49 | rpcc.Stream 50 | } 51 | 52 | // StateChangedReply is the reply for SecurityStateChanged events. 53 | type StateChangedReply struct { 54 | SecurityState State `json:"securityState"` // Security state. 55 | // SchemeIsCryptographic is deprecated. 56 | // 57 | // Deprecated: True if the page was loaded over cryptographic 58 | // transport such as HTTPS. 59 | SchemeIsCryptographic bool `json:"schemeIsCryptographic"` 60 | // Explanations is deprecated. 61 | // 62 | // Deprecated: Previously a list of explanations for the security 63 | // state. Now always empty. 64 | Explanations []StateExplanation `json:"explanations"` 65 | // InsecureContentStatus is deprecated. 66 | // 67 | // Deprecated: Information about insecure content on the page. 68 | InsecureContentStatus InsecureContentStatus `json:"insecureContentStatus"` 69 | // Summary is deprecated. 70 | // 71 | // Deprecated: Overrides user-visible description of the state. Always 72 | // omitted. 73 | Summary *string `json:"summary,omitempty"` 74 | } 75 | -------------------------------------------------------------------------------- /protocol/serviceworker/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package serviceworker 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // WorkerErrorReportedClient is a client for WorkerErrorReported events. 10 | type WorkerErrorReportedClient interface { 11 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 12 | // triggered, context canceled or connection closed. 13 | Recv() (*WorkerErrorReportedReply, error) 14 | rpcc.Stream 15 | } 16 | 17 | // WorkerErrorReportedReply is the reply for WorkerErrorReported events. 18 | type WorkerErrorReportedReply struct { 19 | ErrorMessage ErrorMessage `json:"errorMessage"` // No description. 20 | } 21 | 22 | // WorkerRegistrationUpdatedClient is a client for WorkerRegistrationUpdated events. 23 | type WorkerRegistrationUpdatedClient interface { 24 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 25 | // triggered, context canceled or connection closed. 26 | Recv() (*WorkerRegistrationUpdatedReply, error) 27 | rpcc.Stream 28 | } 29 | 30 | // WorkerRegistrationUpdatedReply is the reply for WorkerRegistrationUpdated events. 31 | type WorkerRegistrationUpdatedReply struct { 32 | Registrations []Registration `json:"registrations"` // No description. 33 | } 34 | 35 | // WorkerVersionUpdatedClient is a client for WorkerVersionUpdated events. 36 | type WorkerVersionUpdatedClient interface { 37 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 38 | // triggered, context canceled or connection closed. 39 | Recv() (*WorkerVersionUpdatedReply, error) 40 | rpcc.Stream 41 | } 42 | 43 | // WorkerVersionUpdatedReply is the reply for WorkerVersionUpdated events. 44 | type WorkerVersionUpdatedReply struct { 45 | Versions []Version `json:"versions"` // No description. 46 | } 47 | -------------------------------------------------------------------------------- /protocol/systeminfo/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package systeminfo 4 | 5 | // GetInfoReply represents the return values for GetInfo in the SystemInfo domain. 6 | type GetInfoReply struct { 7 | GPU GPUInfo `json:"gpu"` // Information about the GPUs on the system. 8 | ModelName string `json:"modelName"` // A platform-dependent description of the model of the machine. On Mac OS, this is, for example, 'MacBookPro'. Will be the empty string if not supported. 9 | ModelVersion string `json:"modelVersion"` // A platform-dependent description of the version of the machine. On Mac OS, this is, for example, '10.1'. Will be the empty string if not supported. 10 | CommandLine string `json:"commandLine"` // The command line string used to launch the browser. Will be the empty string if not supported. 11 | } 12 | 13 | // GetFeatureStateArgs represents the arguments for GetFeatureState in the SystemInfo domain. 14 | type GetFeatureStateArgs struct { 15 | FeatureState string `json:"featureState"` // No description. 16 | } 17 | 18 | // NewGetFeatureStateArgs initializes GetFeatureStateArgs with the required arguments. 19 | func NewGetFeatureStateArgs(featureState string) *GetFeatureStateArgs { 20 | args := new(GetFeatureStateArgs) 21 | args.FeatureState = featureState 22 | return args 23 | } 24 | 25 | // GetFeatureStateReply represents the return values for GetFeatureState in the SystemInfo domain. 26 | type GetFeatureStateReply struct { 27 | FeatureEnabled bool `json:"featureEnabled"` // No description. 28 | } 29 | 30 | // GetProcessInfoReply represents the return values for GetProcessInfo in the SystemInfo domain. 31 | type GetProcessInfoReply struct { 32 | ProcessInfo []ProcessInfo `json:"processInfo"` // An array of process info blocks. 33 | } 34 | -------------------------------------------------------------------------------- /protocol/systeminfo/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package systeminfo implements the SystemInfo domain. The SystemInfo domain 4 | // defines methods and events for querying low-level system information. 5 | package systeminfo 6 | 7 | import ( 8 | "context" 9 | 10 | "github.com/mafredri/cdp/protocol/internal" 11 | "github.com/mafredri/cdp/rpcc" 12 | ) 13 | 14 | // domainClient is a client for the SystemInfo domain. The SystemInfo domain 15 | // defines methods and events for querying low-level system information. 16 | type domainClient struct{ conn *rpcc.Conn } 17 | 18 | // NewClient returns a client for the SystemInfo domain with the connection set to conn. 19 | func NewClient(conn *rpcc.Conn) *domainClient { 20 | return &domainClient{conn: conn} 21 | } 22 | 23 | // GetInfo invokes the SystemInfo method. Returns information about the 24 | // system. 25 | func (d *domainClient) GetInfo(ctx context.Context) (reply *GetInfoReply, err error) { 26 | reply = new(GetInfoReply) 27 | err = rpcc.Invoke(ctx, "SystemInfo.getInfo", nil, reply, d.conn) 28 | if err != nil { 29 | err = &internal.OpError{Domain: "SystemInfo", Op: "GetInfo", Err: err} 30 | } 31 | return 32 | } 33 | 34 | // GetFeatureState invokes the SystemInfo method. Returns information about 35 | // the feature state. 36 | func (d *domainClient) GetFeatureState(ctx context.Context, args *GetFeatureStateArgs) (reply *GetFeatureStateReply, err error) { 37 | reply = new(GetFeatureStateReply) 38 | if args != nil { 39 | err = rpcc.Invoke(ctx, "SystemInfo.getFeatureState", args, reply, d.conn) 40 | } else { 41 | err = rpcc.Invoke(ctx, "SystemInfo.getFeatureState", nil, reply, d.conn) 42 | } 43 | if err != nil { 44 | err = &internal.OpError{Domain: "SystemInfo", Op: "GetFeatureState", Err: err} 45 | } 46 | return 47 | } 48 | 49 | // GetProcessInfo invokes the SystemInfo method. Returns information about all 50 | // running processes. 51 | func (d *domainClient) GetProcessInfo(ctx context.Context) (reply *GetProcessInfoReply, err error) { 52 | reply = new(GetProcessInfoReply) 53 | err = rpcc.Invoke(ctx, "SystemInfo.getProcessInfo", nil, reply, d.conn) 54 | if err != nil { 55 | err = &internal.OpError{Domain: "SystemInfo", Op: "GetProcessInfo", Err: err} 56 | } 57 | return 58 | } 59 | -------------------------------------------------------------------------------- /protocol/target/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package target 4 | 5 | import ( 6 | "github.com/mafredri/cdp/protocol/internal" 7 | "github.com/mafredri/cdp/protocol/page" 8 | ) 9 | 10 | // ID 11 | type ID string 12 | 13 | // SessionID Unique identifier of attached debugging session. 14 | type SessionID string 15 | 16 | // Info 17 | type Info struct { 18 | TargetID ID `json:"targetId"` // No description. 19 | Type string `json:"type"` // List of types: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/devtools/devtools_agent_host_impl.cc?ss=chromium&q=f:devtools%20-f:out%20%22::kTypeTab%5B%5D%22 20 | Title string `json:"title"` // No description. 21 | URL string `json:"url"` // No description. 22 | Attached bool `json:"attached"` // Whether the target has an attached client. 23 | OpenerID *ID `json:"openerId,omitempty"` // Opener target Id 24 | // CanAccessOpener Whether the target has access to the originating 25 | // window. 26 | // 27 | // Note: This property is experimental. 28 | CanAccessOpener bool `json:"canAccessOpener"` 29 | // OpenerFrameID Frame id of originating window (is only set if target 30 | // has an opener). 31 | // 32 | // Note: This property is experimental. 33 | OpenerFrameID *page.FrameID `json:"openerFrameId,omitempty"` 34 | // BrowserContextID 35 | // 36 | // Note: This property is experimental. 37 | BrowserContextID *internal.BrowserContextID `json:"browserContextId,omitempty"` 38 | // Subtype Provides additional details for specific target types. For 39 | // example, for the type of "page", this may be set to "prerender". 40 | // 41 | // Note: This property is experimental. 42 | Subtype *string `json:"subtype,omitempty"` 43 | } 44 | 45 | // FilterEntry A filter used by target query/discovery/auto-attach operations. 46 | // 47 | // Note: This type is experimental. 48 | type FilterEntry struct { 49 | Exclude *bool `json:"exclude,omitempty"` // If set, causes exclusion of matching targets from the list. 50 | Type *string `json:"type,omitempty"` // If not present, matches any type. 51 | } 52 | 53 | // Filter The entries in TargetFilter are matched sequentially against targets 54 | // and the first entry that matches determines if the target is included or 55 | // not, depending on the value of `exclude` field in the entry. If filter is 56 | // not specified, the one assumed is [{type: "browser", exclude: true}, {type: 57 | // "tab", exclude: true}, {}] (i.e. include everything but `browser` and 58 | // `tab`). 59 | // 60 | // Note: This type is experimental. 61 | type Filter []FilterEntry 62 | 63 | // RemoteLocation 64 | // 65 | // Note: This type is experimental. 66 | type RemoteLocation struct { 67 | Host string `json:"host"` // No description. 68 | Port int `json:"port"` // No description. 69 | } 70 | -------------------------------------------------------------------------------- /protocol/tethering/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package tethering 4 | 5 | // BindArgs represents the arguments for Bind in the Tethering domain. 6 | type BindArgs struct { 7 | Port int `json:"port"` // Port number to bind. 8 | } 9 | 10 | // NewBindArgs initializes BindArgs with the required arguments. 11 | func NewBindArgs(port int) *BindArgs { 12 | args := new(BindArgs) 13 | args.Port = port 14 | return args 15 | } 16 | 17 | // UnbindArgs represents the arguments for Unbind in the Tethering domain. 18 | type UnbindArgs struct { 19 | Port int `json:"port"` // Port number to unbind. 20 | } 21 | 22 | // NewUnbindArgs initializes UnbindArgs with the required arguments. 23 | func NewUnbindArgs(port int) *UnbindArgs { 24 | args := new(UnbindArgs) 25 | args.Port = port 26 | return args 27 | } 28 | -------------------------------------------------------------------------------- /protocol/tethering/domain.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | // Package tethering implements the Tethering domain. The Tethering domain 4 | // defines methods and events for browser port binding. 5 | package tethering 6 | 7 | import ( 8 | "context" 9 | 10 | "github.com/mafredri/cdp/protocol/internal" 11 | "github.com/mafredri/cdp/rpcc" 12 | ) 13 | 14 | // domainClient is a client for the Tethering domain. The Tethering domain 15 | // defines methods and events for browser port binding. 16 | type domainClient struct{ conn *rpcc.Conn } 17 | 18 | // NewClient returns a client for the Tethering domain with the connection set to conn. 19 | func NewClient(conn *rpcc.Conn) *domainClient { 20 | return &domainClient{conn: conn} 21 | } 22 | 23 | // Bind invokes the Tethering method. Request browser port binding. 24 | func (d *domainClient) Bind(ctx context.Context, args *BindArgs) (err error) { 25 | if args != nil { 26 | err = rpcc.Invoke(ctx, "Tethering.bind", args, nil, d.conn) 27 | } else { 28 | err = rpcc.Invoke(ctx, "Tethering.bind", nil, nil, d.conn) 29 | } 30 | if err != nil { 31 | err = &internal.OpError{Domain: "Tethering", Op: "Bind", Err: err} 32 | } 33 | return 34 | } 35 | 36 | // Unbind invokes the Tethering method. Request browser port unbinding. 37 | func (d *domainClient) Unbind(ctx context.Context, args *UnbindArgs) (err error) { 38 | if args != nil { 39 | err = rpcc.Invoke(ctx, "Tethering.unbind", args, nil, d.conn) 40 | } else { 41 | err = rpcc.Invoke(ctx, "Tethering.unbind", nil, nil, d.conn) 42 | } 43 | if err != nil { 44 | err = &internal.OpError{Domain: "Tethering", Op: "Unbind", Err: err} 45 | } 46 | return 47 | } 48 | 49 | func (d *domainClient) Accepted(ctx context.Context) (AcceptedClient, error) { 50 | s, err := rpcc.NewStream(ctx, "Tethering.accepted", d.conn) 51 | if err != nil { 52 | return nil, err 53 | } 54 | return &acceptedClient{Stream: s}, nil 55 | } 56 | 57 | type acceptedClient struct{ rpcc.Stream } 58 | 59 | // GetStream returns the original Stream for use with cdp.Sync. 60 | func (c *acceptedClient) GetStream() rpcc.Stream { return c.Stream } 61 | 62 | func (c *acceptedClient) Recv() (*AcceptedReply, error) { 63 | event := new(AcceptedReply) 64 | if err := c.RecvMsg(event); err != nil { 65 | return nil, &internal.OpError{Domain: "Tethering", Op: "Accepted Recv", Err: err} 66 | } 67 | return event, nil 68 | } 69 | -------------------------------------------------------------------------------- /protocol/tethering/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package tethering 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // AcceptedClient is a client for Accepted events. Informs that port was 10 | // successfully bound and got a specified connection id. 11 | type AcceptedClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*AcceptedReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // AcceptedReply is the reply for Accepted events. 19 | type AcceptedReply struct { 20 | Port int `json:"port"` // Port number that was successfully bound. 21 | ConnectionID string `json:"connectionId"` // Connection id to be used. 22 | } 23 | -------------------------------------------------------------------------------- /protocol/tracing/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package tracing 4 | 5 | import ( 6 | "encoding/json" 7 | 8 | "github.com/mafredri/cdp/protocol/io" 9 | "github.com/mafredri/cdp/rpcc" 10 | ) 11 | 12 | // BufferUsageClient is a client for BufferUsage events. 13 | type BufferUsageClient interface { 14 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 15 | // triggered, context canceled or connection closed. 16 | Recv() (*BufferUsageReply, error) 17 | rpcc.Stream 18 | } 19 | 20 | // BufferUsageReply is the reply for BufferUsage events. 21 | type BufferUsageReply struct { 22 | PercentFull *float64 `json:"percentFull,omitempty"` // A number in range [0..1] that indicates the used size of event buffer as a fraction of its total size. 23 | EventCount *float64 `json:"eventCount,omitempty"` // An approximate number of events in the trace log. 24 | Value *float64 `json:"value,omitempty"` // A number in range [0..1] that indicates the used size of event buffer as a fraction of its total size. 25 | } 26 | 27 | // DataCollectedClient is a client for DataCollected events. Contains a bucket 28 | // of collected trace events. When tracing is stopped collected events will be 29 | // sent as a sequence of dataCollected events followed by tracingComplete 30 | // event. 31 | type DataCollectedClient interface { 32 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 33 | // triggered, context canceled or connection closed. 34 | Recv() (*DataCollectedReply, error) 35 | rpcc.Stream 36 | } 37 | 38 | // DataCollectedReply is the reply for DataCollected events. 39 | type DataCollectedReply struct { 40 | Value []json.RawMessage `json:"value"` // No description. 41 | } 42 | 43 | // CompleteClient is a client for TracingComplete events. Signals that tracing 44 | // is stopped and there is no trace buffers pending flush, all data were 45 | // delivered via dataCollected events. 46 | type CompleteClient interface { 47 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 48 | // triggered, context canceled or connection closed. 49 | Recv() (*CompleteReply, error) 50 | rpcc.Stream 51 | } 52 | 53 | // CompleteReply is the reply for TracingComplete events. 54 | type CompleteReply struct { 55 | DataLossOccurred bool `json:"dataLossOccurred"` // Indicates whether some trace data is known to have been lost, e.g. because the trace ring buffer wrapped around. 56 | Stream *io.StreamHandle `json:"stream,omitempty"` // A handle of the stream that holds resulting trace data. 57 | TraceFormat StreamFormat `json:"traceFormat,omitempty"` // Trace data format of returned stream. 58 | StreamCompression StreamCompression `json:"streamCompression,omitempty"` // Compression format of returned stream. 59 | } 60 | -------------------------------------------------------------------------------- /protocol/webaudio/command.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package webaudio 4 | 5 | // GetRealtimeDataArgs represents the arguments for GetRealtimeData in the WebAudio domain. 6 | type GetRealtimeDataArgs struct { 7 | ContextID GraphObjectID `json:"contextId"` // No description. 8 | } 9 | 10 | // NewGetRealtimeDataArgs initializes GetRealtimeDataArgs with the required arguments. 11 | func NewGetRealtimeDataArgs(contextID GraphObjectID) *GetRealtimeDataArgs { 12 | args := new(GetRealtimeDataArgs) 13 | args.ContextID = contextID 14 | return args 15 | } 16 | 17 | // GetRealtimeDataReply represents the return values for GetRealtimeData in the WebAudio domain. 18 | type GetRealtimeDataReply struct { 19 | RealtimeData ContextRealtimeData `json:"realtimeData"` // No description. 20 | } 21 | -------------------------------------------------------------------------------- /protocol/webauthn/event.go: -------------------------------------------------------------------------------- 1 | // Code generated by cdpgen. DO NOT EDIT. 2 | 3 | package webauthn 4 | 5 | import ( 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | // CredentialAddedClient is a client for CredentialAdded events. Triggered 10 | // when a credential is added to an authenticator. 11 | type CredentialAddedClient interface { 12 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 13 | // triggered, context canceled or connection closed. 14 | Recv() (*CredentialAddedReply, error) 15 | rpcc.Stream 16 | } 17 | 18 | // CredentialAddedReply is the reply for CredentialAdded events. 19 | type CredentialAddedReply struct { 20 | AuthenticatorID AuthenticatorID `json:"authenticatorId"` // No description. 21 | Credential Credential `json:"credential"` // No description. 22 | } 23 | 24 | // CredentialAssertedClient is a client for CredentialAsserted events. 25 | // Triggered when a credential is used in a webauthn assertion. 26 | type CredentialAssertedClient interface { 27 | // Recv calls RecvMsg on rpcc.Stream, blocks until the event is 28 | // triggered, context canceled or connection closed. 29 | Recv() (*CredentialAssertedReply, error) 30 | rpcc.Stream 31 | } 32 | 33 | // CredentialAssertedReply is the reply for CredentialAsserted events. 34 | type CredentialAssertedReply struct { 35 | AuthenticatorID AuthenticatorID `json:"authenticatorId"` // No description. 36 | Credential Credential `json:"credential"` // No description. 37 | } 38 | -------------------------------------------------------------------------------- /rpcc/call.go: -------------------------------------------------------------------------------- 1 | package rpcc 2 | 3 | import "context" 4 | 5 | type rpcCall struct { 6 | Method string 7 | Args interface{} 8 | Reply interface{} 9 | Error chan error 10 | } 11 | 12 | func (c *rpcCall) done(err error) { 13 | c.Error <- err 14 | } 15 | 16 | // Invoke sends an RPC request and blocks until the response is received. 17 | // This function is called by generated code but can be used to issue 18 | // requests manually. 19 | func Invoke(ctx context.Context, method string, args, reply interface{}, conn *Conn) error { 20 | if ctx == nil { 21 | ctx = context.Background() 22 | } 23 | 24 | call := &rpcCall{ 25 | Method: method, 26 | Args: args, 27 | Reply: reply, 28 | Error: make(chan error, 1), // Do not block. 29 | } 30 | 31 | err := conn.send(ctx, call) 32 | if err != nil { 33 | return err 34 | } 35 | 36 | select { 37 | case <-ctx.Done(): 38 | return ctx.Err() 39 | case err = <-call.Error: 40 | return err 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /rpcc/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package rpcc provides an RPC client connection with support for the 3 | JSON-RPC 2.0 specification, not including Batch requests. Server side 4 | RPC notifications are also supported. 5 | 6 | Dial connects to an RPC server listening on a websocket using the 7 | gorilla/websocket package. 8 | 9 | conn, err := rpcc.Dial("ws://127.0.0.1:9999/f39a3624-e972-4a77-8a5f-6f8c42ef5129") 10 | // ... 11 | 12 | The user must close the connection when finnished with it: 13 | 14 | conn, err := rpcc.Dial("ws://127.0.0.1:9999/f39a3624-e972-4a77-8a5f-6f8c42ef5129") 15 | if err != nil { 16 | // Handle error. 17 | } 18 | defer conn.Close() 19 | // ... 20 | 21 | A custom dialer can be used to change the websocket lib or communicate 22 | over other protocols. 23 | 24 | netDial := func(ctx context.Context, addr string) (io.ReadWriteCloser, error) { 25 | conn, err := net.Dial("tcp", addr) 26 | if err != nil { 27 | // Handle error. 28 | } 29 | // Wrap connection to handle writing JSON. 30 | // ... 31 | return conn, nil 32 | } 33 | conn, err := rpcc.Dial("127.0.0.1:9999", rpcc.WithDialer(netDial)) 34 | // ... 35 | 36 | # Communicating with the server 37 | 38 | Send a request using Invoke: 39 | 40 | ctx, cancel := context.WithCancel(context.Background()) 41 | defer cancel() 42 | err := rpcc.Invoke(ctx, "Domain.method", args, reply, conn) 43 | // ... 44 | 45 | Receive a notification using NewStream: 46 | 47 | stream, err := rpcc.NewStream(ctx, "Domain.event", conn) 48 | if err != nil { 49 | // Handle error. 50 | } 51 | err = stream.RecvMsg(&reply) 52 | if err != nil { 53 | // Handle error. 54 | } 55 | 56 | The stream should be closed when it is no longer used to avoid leaking 57 | memory: 58 | 59 | stream, err := rpcc.NewStream(ctx, "Domain.event", conn) 60 | if err != nil { 61 | // Handle error. 62 | } 63 | defer stream.Close() 64 | 65 | When order is important, two streams can be synchronized with Sync: 66 | 67 | err := rpcc.Sync(stream1, stream2) 68 | if err != nil { 69 | // Handle error. 70 | } 71 | */ 72 | package rpcc 73 | -------------------------------------------------------------------------------- /rpcc/socket.go: -------------------------------------------------------------------------------- 1 | package rpcc 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/gorilla/websocket" 7 | ) 8 | 9 | type wsConn interface { 10 | NextReader() (messageType int, r io.Reader, err error) 11 | NextWriter(messageType int) (io.WriteCloser, error) 12 | Close() error 13 | } 14 | 15 | // wsReadWriteCloser wraps a gorilla/websocket connection 16 | // and implements io.Reader and io.Writer. 17 | type wsReadWriteCloser struct { 18 | wsConn 19 | r io.Reader 20 | } 21 | 22 | var _ io.ReadWriteCloser = (*wsReadWriteCloser)(nil) 23 | 24 | // Read calls Read on the WebSocket Reader and requests the NextReader 25 | // when io.EOF is encountered. Imlpements io.Reader. 26 | func (cw *wsReadWriteCloser) Read(p []byte) (n int, err error) { 27 | if cw.r != nil { 28 | // Check if previous reader still has data in the buffer. 29 | // Otherwise pass on to next reader. 30 | n, err = cw.r.Read(p) 31 | if err != io.EOF { 32 | return n, err 33 | } 34 | } 35 | _, r, err := cw.wsConn.NextReader() 36 | if err != nil { 37 | return 0, err 38 | } 39 | cw.r = r // Store reader for next call to Read. 40 | 41 | n, err = r.Read(p) 42 | return n, err 43 | } 44 | 45 | // Write requests the NextWriter for the WebSocket and writes the 46 | // message. Implements io.Writer. 47 | func (cw *wsReadWriteCloser) Write(p []byte) (n int, err error) { 48 | w, err := cw.wsConn.NextWriter(websocket.TextMessage) 49 | if err != nil { 50 | return 0, err 51 | } 52 | if n, err = w.Write(p); err != nil { 53 | return n, err 54 | } 55 | err = w.Close() 56 | return n, err 57 | } 58 | -------------------------------------------------------------------------------- /session/conn.go: -------------------------------------------------------------------------------- 1 | package session 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/mafredri/cdp/internal/errors" 7 | ) 8 | 9 | // closeConn is a fake connection with a close function. 10 | type closeConn struct{ close func() error } 11 | 12 | var _ io.ReadWriteCloser = (*closeConn)(nil) 13 | 14 | func (c *closeConn) Close() error { return c.close() } 15 | func (c *closeConn) Read(b []byte) (n int, err error) { return 0, errors.New("not allowed") } 16 | func (c *closeConn) Write(b []byte) (n int, err error) { return 0, errors.New("not allowed") } 17 | -------------------------------------------------------------------------------- /session/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package session implements a session Manager for establishing session 3 | connections to targets (via the Target domain). Session connections allow a 4 | single websocket connection (from the provided cdp.Client) to be used for 5 | communicating with multiple targets. 6 | 7 | Initialize a new session Manager. 8 | 9 | c := cdp.NewClient(conn) // cdp.Client with websocket connection. 10 | 11 | m, err := session.NewManager(c) 12 | if err != nil { 13 | // Handle error. 14 | } 15 | defer m.Close() // Cleanup. 16 | 17 | Establish a new session connection to targetID. 18 | 19 | pageConn, err := m.Dial(context.TODO(), targetID) 20 | if err != nil { 21 | // Handle error. 22 | } 23 | defer pageConn.Close() 24 | 25 | Use the session connection. 26 | 27 | pageClient := cdp.NewClient(pageConn) 28 | err = pageClient.Page.Enable(context.TODO()) 29 | // ... 30 | 31 | If session connections are behaving unexpectedly, you can debug the session 32 | Manager by checking the error channel. 33 | 34 | go func() { 35 | for err := range m.Err() { 36 | log.Println(err) 37 | } 38 | // Manager is closed. 39 | }() 40 | */ 41 | package session 42 | -------------------------------------------------------------------------------- /session/manager_test.go: -------------------------------------------------------------------------------- 1 | package session 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/mafredri/cdp/internal/errors" 7 | "github.com/mafredri/cdp/protocol/target" 8 | "github.com/mafredri/cdp/rpcc" 9 | ) 10 | 11 | type testEventClient struct { 12 | w chan struct{} 13 | done chan struct{} 14 | } 15 | 16 | func (c *testEventClient) next() { c.done = make(chan struct{}); close(c.w) } 17 | func (c *testEventClient) markReady() { close(c.done) } 18 | func (c *testEventClient) Ready() <-chan struct{} { 19 | <-c.w 20 | c.w = make(chan struct{}) 21 | return c.done 22 | } 23 | func (c *testEventClient) Close() error { return nil } 24 | func (c *testEventClient) RecvMsg(m interface{}) error { panic("not implemented") } 25 | 26 | func newTestEventClient() *testEventClient { 27 | return &testEventClient{w: make(chan struct{})} 28 | } 29 | 30 | var _ rpcc.Stream = (*testEventClient)(nil) 31 | 32 | type testDetacher struct { 33 | *testEventClient 34 | err error 35 | } 36 | 37 | func (ev *testDetacher) Recv() (*target.DetachedFromTargetReply, error) { 38 | return nil, ev.err 39 | } 40 | 41 | type testMessenger struct { 42 | *testEventClient 43 | err error 44 | } 45 | 46 | func (ev *testMessenger) Recv() (*target.ReceivedMessageFromTargetReply, error) { 47 | return nil, ev.err 48 | } 49 | 50 | func TestManager_ErrorsAreSentOnErrChan(t *testing.T) { 51 | detached := &testDetacher{testEventClient: newTestEventClient()} 52 | message := &testMessenger{testEventClient: newTestEventClient()} 53 | ev := &sessionEvents{ 54 | detached: detached, 55 | message: message, 56 | } 57 | 58 | m := Manager{cancel: func() {}, errC: make(chan error, 1)} 59 | go m.watch(ev, nil, make(chan error, 1), m.errC) 60 | 61 | message.next() 62 | 63 | detached.next() 64 | detached.err = errors.New("detach nope") 65 | detached.markReady() 66 | err := <-m.Err() 67 | if !errors.Is(err, detached.err) { 68 | t.Errorf("got error: %v; want: %v", err, detached.err) 69 | } 70 | detached.next() 71 | 72 | message.next() 73 | message.err = errors.New("message nope") 74 | message.markReady() 75 | err = <-m.Err() 76 | if !errors.Is(err, message.err) { 77 | t.Errorf("got error: %v; want: %v", err, message.err) 78 | } 79 | message.next() 80 | 81 | // Close the watcher goroutine. 82 | detached.err = rpcc.ErrConnClosing 83 | detached.markReady() 84 | } 85 | -------------------------------------------------------------------------------- /sync.go: -------------------------------------------------------------------------------- 1 | package cdp 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/mafredri/cdp/rpcc" 7 | ) 8 | 9 | type eventClient interface { 10 | rpcc.Stream 11 | } 12 | 13 | type getStreamer interface { 14 | GetStream() rpcc.Stream 15 | } 16 | 17 | // Sync takes two or more event clients and sets them into synchronous operation, 18 | // relative to each other. This operation cannot be undone. If an error is 19 | // returned this function is no-op and the event clients will continue in 20 | // asynchronous operation. 21 | // 22 | // All event clients must belong to the same connection and they must not be 23 | // closed. Passing multiple clients of the same event type to Sync is not 24 | // supported and will return an error. 25 | // 26 | // An event client that is closed is removed and has no further affect on the 27 | // clients that were synchronized. 28 | // 29 | // When two event clients, A and B, are in sync they will receive events in the 30 | // order of arrival. If an event for both A and B is triggered, in that order, 31 | // it will not be possible to receive the event from B before the event from A 32 | // has been received. 33 | func Sync(c ...eventClient) error { 34 | var s []rpcc.Stream 35 | for _, cc := range c { 36 | cs, ok := cc.(getStreamer) 37 | if !ok { 38 | return fmt.Errorf("cdp: Sync: bad eventClient type: %T", cc) 39 | } 40 | s = append(s, cs.GetStream()) 41 | } 42 | return rpcc.Sync(s...) 43 | } 44 | --------------------------------------------------------------------------------