From cd451af7be1ae457aecc9beae6412f3e0d281530 Mon Sep 17 00:00:00 2001 From: Lukasz Gut Date: Thu, 18 Jul 2024 14:59:08 +0200 Subject: [PATCH] Cloud Insights Browser Audits PoC --- .gitignore | 6 +++++- Makefile | 3 +++ common/http.go | 20 ++++++++++++++------ common/http_test.go | 10 ++++++---- common/page.go | 11 +++++++++++ examples/pagegoto.js | 27 +++++++++++++++++++++++++++ go.mod | 8 ++++++-- go.sum | 21 +++++++++++++++++---- 8 files changed, 89 insertions(+), 17 deletions(-) create mode 100644 examples/pagegoto.js diff --git a/.gitignore b/.gitignore index 9d5ed69a2..e66400c78 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.dll *.so *.dylib +xk6-browser # Test binary, built with `go test -c` *.test @@ -23,4 +24,7 @@ .DS_Store # Screenshot example output -screenshots \ No newline at end of file +screenshots + +# VS Code directory entries +.vscode diff --git a/Makefile b/Makefile index dad95094c..ade6d2939 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,9 @@ all: build build : go install go.k6.io/xk6/cmd/xk6@latest && xk6 build --output xk6-browser --with github.com/grafana/xk6-browser=. +build-debug: + go install go.k6.io/xk6/cmd/xk6@latest && XK6_BUILD_FLAGS='-gcflags=all="-N -l"' xk6 build --output xk6-browser --with github.com/grafana/xk6-browser=. + format : find . -name '*.go' -exec gofmt -s -w {} + diff --git a/common/http.go b/common/http.go index df7a1e509..4cb5d5669 100644 --- a/common/http.go +++ b/common/http.go @@ -1,6 +1,7 @@ package common import ( + "bytes" "context" "encoding/json" "errors" @@ -105,12 +106,19 @@ func NewRequest(ctx context.Context, rp NewRequestParams) (*Request, error) { ev.Type == network.ResourceTypeDocument r := Request{ - url: u, - frame: rp.frame, - redirectChain: rp.redirectChain, - requestID: ev.RequestID, - method: ev.Request.Method, - postData: ev.Request.PostData, + url: u, + frame: rp.frame, + redirectChain: rp.redirectChain, + requestID: ev.RequestID, + method: ev.Request.Method, + // TODO(lukasz): This is most likely wrong. I just did it this way to make the code compile. + postData: func(ents []*network.PostDataEntry) string { + var b bytes.Buffer + for _, e := range ents { + b.WriteString(e.Bytes) + } + return b.String() + }(ev.Request.PostDataEntries), resourceType: ev.Type.String(), isNavigationRequest: isNavigationRequest, allowInterception: rp.allowInterception, diff --git a/common/http_test.go b/common/http_test.go index f57f78e94..51013d3b5 100644 --- a/common/http_test.go +++ b/common/http_test.go @@ -21,10 +21,12 @@ func TestRequest(t *testing.T) { evt := &network.EventRequestWillBeSent{ RequestID: network.RequestID("1234"), Request: &network.Request{ - URL: "https://test/post", - Method: "POST", - Headers: network.Headers(headers), - PostData: "hello", + URL: "https://test/post", + Method: "POST", + Headers: network.Headers(headers), + PostDataEntries: []*network.PostDataEntry{ + &network.PostDataEntry{Bytes: "hello"}, + }, }, Timestamp: &ts, WallTime: &wt, diff --git a/common/page.go b/common/page.go index 35b2f296e..a355614be 100644 --- a/common/page.go +++ b/common/page.go @@ -11,6 +11,7 @@ import ( "time" "github.com/chromedp/cdproto" + "github.com/chromedp/cdproto/audits" "github.com/chromedp/cdproto/cdp" "github.com/chromedp/cdproto/dom" "github.com/chromedp/cdproto/emulation" @@ -321,6 +322,11 @@ func NewPage( return nil, fmt.Errorf("internal error while adding binding to page: %w", err) } + enableAction := audits.Enable() + if err := enableAction.Do(cdp.WithExecutor(p.ctx, p.session)); err != nil { + return nil, fmt.Errorf("internal error while enabling audits for a browser: %w", err) + } + if err := bctx.applyAllInitScripts(&p); err != nil { return nil, fmt.Errorf("internal error while applying init scripts to page: %w", err) } @@ -334,6 +340,7 @@ func (p *Page) initEvents() { events := []string{ cdproto.EventRuntimeConsoleAPICalled, + cdproto.EventAuditsIssueAdded, } p.session.on(p.ctx, events, p.eventCh) @@ -358,6 +365,10 @@ func (p *Page) initEvents() { case event := <-p.eventCh: if ev, ok := event.data.(*cdpruntime.EventConsoleAPICalled); ok { p.onConsoleAPICalled(ev) + } else if ev, ok := event.data.(*audits.EventIssueAdded); ok { + p.logger.Debugf("Page:initEvents:onIssueAdded", "issue:%+v", ev.Issue) + } else { + p.logger.Debugf("Page:initEvents:unknownEvent", "event:%+v", event) } } } diff --git a/examples/pagegoto.js b/examples/pagegoto.js new file mode 100644 index 000000000..c4dcfb875 --- /dev/null +++ b/examples/pagegoto.js @@ -0,0 +1,27 @@ +import { browser } from "k6/browser"; +import { sleep } from "k6"; + +export const options = { + scenarios: { + ui: { + executor: "shared-iterations", + options: { + browser: { + type: "chromium", + }, + }, + }, + }, + thresholds: { + checks: ["rate==1.0"], + }, +}; + +export default async function () { + const page = await browser.newPage(); + console.log("hello, world!"); + + await page.goto("https://grafana.com/"); + + sleep(1); +} diff --git a/go.mod b/go.mod index 80c89c147..4bcd35328 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/grafana/xk6-browser go 1.20 require ( - github.com/chromedp/cdproto v0.0.0-20221023212508-67ada9507fb2 + github.com/chromedp/cdproto v0.0.0-20240709201219-e202069cc16b github.com/gorilla/websocket v1.5.1 github.com/grafana/sobek v0.0.0-20240613124309-cb36746e8fee github.com/mailru/easyjson v0.7.7 @@ -26,6 +26,7 @@ require ( github.com/andybalholm/brotli v1.1.0 // indirect github.com/andybalholm/cascadia v1.3.2 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/chromedp/chromedp v0.9.5 // indirect github.com/chromedp/sysutil v1.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dlclark/regexp2 v1.9.0 // indirect @@ -35,6 +36,9 @@ require ( github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect + github.com/gobwas/httphead v0.1.0 // indirect + github.com/gobwas/pool v0.2.1 // indirect + github.com/gobwas/ws v1.4.0 // indirect github.com/google/pprof v0.0.0-20230728192033-2ba5b33183c6 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -58,7 +62,7 @@ require ( go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.1.0 // indirect golang.org/x/crypto v0.24.0 // indirect - golang.org/x/sys v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect diff --git a/go.sum b/go.sum index bc1945bdf..92ba49e2d 100644 --- a/go.sum +++ b/go.sum @@ -12,8 +12,11 @@ github.com/bufbuild/protocompile v0.8.0 h1:9Kp1q6OkS9L4nM3FYbr8vlJnEwtbpDPQlQOVX github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/chromedp/cdproto v0.0.0-20221023212508-67ada9507fb2 h1:xESwMZNYkDnZf9MUk+6lXfMbpDnEJwlEuIxKYKM1vJY= -github.com/chromedp/cdproto v0.0.0-20221023212508-67ada9507fb2/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= +github.com/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= +github.com/chromedp/cdproto v0.0.0-20240709201219-e202069cc16b h1:U1h0qXjQvrOWOjagZmtDkxg/A4QKkWJyGWoQ3sXt6Vg= +github.com/chromedp/cdproto v0.0.0-20240709201219-e202069cc16b/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= +github.com/chromedp/chromedp v0.9.5 h1:viASzruPJOiThk7c5bueOUY91jGLJVximoEMGoH93rg= +github.com/chromedp/chromedp v0.9.5/go.mod h1:D4I2qONslauw/C7INoCir1BJkSwBYMyZgx8X276z3+Y= github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -39,6 +42,13 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-sourcemap/sourcemap v2.1.4+incompatible h1:a+iTbH5auLKxaNwQFg0B+TCYl6lbukKPc7b5x0n1s6Q= github.com/go-sourcemap/sourcemap v2.1.4+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.3.2/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= +github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs= +github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -71,6 +81,7 @@ github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLA github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -98,6 +109,7 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY= github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= @@ -186,8 +198,9 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=