Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ go 1.27.0
require (
cel.dev/cel-go v0.32.0
github.com/MakeNowJust/heredoc/v2 v2.0.1
github.com/chromedp/cdproto v0.0.0-20260714215040-dc233986426f
github.com/chromedp/chromedp v0.16.0
github.com/chromedp/cdproto v0.157.8
github.com/chromedp/chromedp v0.20.1
github.com/coreos/go-oidc/v3 v3.21.0
github.com/coreos/go-semver v0.3.1
github.com/creack/pty v1.1.24
Expand All @@ -20,7 +20,7 @@ require (
github.com/go-logr/zapr v1.3.0
github.com/gofrs/flock v0.13.1
github.com/google/go-cmp v0.7.0
github.com/google/go-github/v91 v91.0.0
github.com/google/go-github/v92 v92.0.0
github.com/google/gofuzz v1.2.0
github.com/google/uuid v1.6.0
github.com/gorilla/securecookie v1.1.2
Expand All @@ -34,7 +34,7 @@ require (
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
github.com/stretchr/testify v1.12.1
github.com/tdewolff/minify/v2 v2.24.17
github.com/tdewolff/minify/v2 v2.24.19
go.uber.org/mock v0.6.0
go.uber.org/zap v1.28.0
golang.org/x/crypto v0.57.0
Expand Down Expand Up @@ -68,7 +68,6 @@ require (
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chromedp/sysutil v1.1.0 // indirect
github.com/coreos/go-oidc v2.5.0+incompatible // indirect
github.com/coreos/go-systemd/v22 v22.7.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
Expand All @@ -95,9 +94,6 @@ require (
github.com/go-openapi/swag/typeutils v0.27.1 // indirect
github.com/go-openapi/swag/yamlutils v0.27.1 // indirect
github.com/gobuffalo/pop/v6 v6.1.1 // 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/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/cel-go v0.29.2 // indirect
Expand Down
29 changes: 8 additions & 21 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,10 @@ github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F9
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chromedp/cdproto v0.0.0-20260714215040-dc233986426f h1:0Z1zcSLEmnj2c2CmJYBqewtS6pxhB39bNWUSEUAWjgk=
github.com/chromedp/cdproto v0.0.0-20260714215040-dc233986426f/go.mod h1:RwFsSODCtFExll+GhHM6R92SARHR3Z3oipaxLHj46C0=
github.com/chromedp/chromedp v0.16.0 h1:rOO4deOm4CbZgBCa8mD9g2rDyIoNs0BkgvNrlbp5ouk=
github.com/chromedp/chromedp v0.16.0/go.mod h1:rbuGKFT1vMcFcFqKfPIO1GpX/N+2s8onm2qMxZLbU5U=
github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM=
github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8=
github.com/chromedp/cdproto v0.157.8 h1:Tkq0AjsUlC3Z4sJfHBzV/uAAxnTF/AZyuSTjfV/1gvk=
github.com/chromedp/cdproto v0.157.8/go.mod h1:h68JaIuFr9o3yiayxEYhBdvaxgYO3shDrPSYhNlyfu0=
github.com/chromedp/chromedp v0.20.1 h1:983T9wmyM09JtROWlxhLQwljKOQovqt8CVE89W3U0NA=
github.com/chromedp/chromedp v0.20.1/go.mod h1:6z1Y5FdKUxRzxx2qcC5h1xjaBJrSWrZp1mjgITfNZig=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
Expand Down Expand Up @@ -206,12 +204,6 @@ github.com/gobuffalo/pop/v6 v6.1.1 h1:eUDBaZcb0gYrmFnKwpuTEUA7t5ZHqNfvS4POqJYXDZ
github.com/gobuffalo/pop/v6 v6.1.1/go.mod h1:1n7jAmI1i7fxuXPZjZb0VBPQDbksRtCoFnrDV5IsvaI=
github.com/gobuffalo/tags/v3 v3.1.4/go.mod h1:ArRNo3ErlHO8BtdA0REaZxijuWnWzF6PUXngmMXd2I0=
github.com/gobuffalo/validate/v3 v3.3.3/go.mod h1:YC7FsbJ/9hW/VjQdmXPvFqvRis4vrRYFxr69WiNZw6g=
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.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs=
github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc=
github.com/gofrs/flock v0.13.1 h1:jjREztyBeSKBZYAC+mgc1laB+xsgy4kYMf3FbKF2UBo=
github.com/gofrs/flock v0.13.1/go.mod h1:sf4BFiHwnvgxa25DlQoDqXQnwRMEOwqxRq37P6MzzmE=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
Expand Down Expand Up @@ -269,8 +261,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-github/v73 v73.0.0 h1:aR+Utnh+Y4mMkS+2qLQwcQ/cF9mOTpdwnzlaw//rG24=
github.com/google/go-github/v73 v73.0.0/go.mod h1:fa6w8+/V+edSU0muqdhCVY7Beh1M8F1IlQPZIANKIYw=
github.com/google/go-github/v91 v91.0.0 h1:fpulREh37uBvOj4kF0vLuzjwJ1HHmFcAfquNjJfmpYs=
github.com/google/go-github/v91 v91.0.0/go.mod h1:rHtn7haKvmkTLhUK/aCQypiIj/suWSB3rnS+a1FdH6M=
github.com/google/go-github/v92 v92.0.0 h1:4vW4RVffwIvoEfIA4RX09mRSB47qQX557/2+HgeWRRg=
github.com/google/go-github/v92 v92.0.0/go.mod h1:w3CH62ZcmRfvW1cdXpyTztSOVMtdjxtKpgo0GouLmjY=
github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0=
github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
Expand Down Expand Up @@ -418,8 +410,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
Expand Down Expand Up @@ -471,8 +461,6 @@ github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0
github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60=
github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/ory/fosite v0.49.1-0.20250703093431-a5f0b09bf31c h1:YFGYDiasRdbScLqJYSPe6Y6maTwwmoUn8CvLDnIbOj4=
github.com/ory/fosite v0.49.1-0.20250703093431-a5f0b09bf31c/go.mod h1:IhAwHrxwNgB3smKB75jkMVQjFTHq9HveITItLGX8/GU=
github.com/ory/go-acc v0.2.9-0.20230103102148-6b1c9a70dbbe h1:rvu4obdvqR0fkSIJ8IfgzKOWwZ5kOT2UNfLq81Qk7rc=
Expand Down Expand Up @@ -570,8 +558,8 @@ github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWD
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/tdewolff/minify/v2 v2.24.17 h1:6AbitfVyq0M7aW6i+XL7+49DeTQZwloOMs9O574arBg=
github.com/tdewolff/minify/v2 v2.24.17/go.mod h1:kVqn9vxXUKtlHexSNrWbYePqioOT5mc4ou/KVSMpfCM=
github.com/tdewolff/minify/v2 v2.24.19 h1:j2exx54gvrCFN9UiFm0Z5vbNWBFcuY5Ql1VmaM2Dkeo=
github.com/tdewolff/minify/v2 v2.24.19/go.mod h1:HVgQO08FJeDxQx+lcFOVDi1IySi/77WlN/dDckCkZoA=
github.com/tdewolff/parse/v2 v2.8.16 h1:bLk5svUOQRkW/Y2SJ+DeENSIkZBcTIkq+Atyv5D8feI=
github.com/tdewolff/parse/v2 v2.8.16/go.mod h1:XdsoSFThlVIRIajAuqz1evNY7bagZS8LBOPA3aVopwQ=
github.com/tdewolff/test v1.0.12 h1:7F21DqIajswxuche0geHdrUZRCWE4oko4b7bcmkkrxk=
Expand Down Expand Up @@ -850,7 +838,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
Expand Down
2 changes: 1 addition & 1 deletion internal/githubclient/githubclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"strings"
"time"

"github.com/google/go-github/v91/github"
"github.com/google/go-github/v92/github"
"k8s.io/apimachinery/pkg/util/sets"

"go.pinniped.dev/internal/plog"
Expand Down
2 changes: 1 addition & 1 deletion internal/githubclient/githubclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"testing"
"time"

"github.com/google/go-github/v91/github"
"github.com/google/go-github/v92/github"
"github.com/migueleliasweb/go-github-mock/src/mock"
"github.com/stretchr/testify/require"
"k8s.io/client-go/util/cert"
Expand Down
115 changes: 67 additions & 48 deletions test/testlib/browsertest/browsertest.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"compress/gzip"
"context"
"encoding/base64"
"errors"
"fmt"
"log"
"regexp"
Expand All @@ -19,6 +20,7 @@ import (
"time"

chromedpbrowser "github.com/chromedp/cdproto/browser"
"github.com/chromedp/cdproto/cdp"
chromedpdom "github.com/chromedp/cdproto/dom"
chromedppage "github.com/chromedp/cdproto/page"
chromedpruntime "github.com/chromedp/cdproto/runtime"
Expand Down Expand Up @@ -110,39 +112,49 @@ func OpenBrowser(t *testing.T) *Browser {
b := &Browser{chromeCtx: chromeCtx}

// Subscribe to console events and exceptions to make them available later.
chromedp.ListenTarget(chromeCtx, func(ev any) {
switch ev := ev.(type) {
case *chromedpruntime.EventConsoleAPICalled:
// The subscriptions end when the browser context is cancelled at the end of the test.
consoleEvents := chromedp.Events(chromeCtx, chromedpruntime.ConsoleAPICalled)
exceptionEvents := chromedp.Events(chromeCtx, chromedpruntime.ExceptionThrown)
go func() {
for ev, err := range consoleEvents {
if err != nil {
return
}
args := make([]string, len(ev.Args))
for i, arg := range ev.Args {
// Could also pay attention to arg.Type here, but choosing to keep it simple for now.
args[i] = arg.Value.String()
}
b.lock.Lock()
defer b.lock.Unlock()
b.consoleEvents = append(b.consoleEvents, consoleEvent{
api: ev.Type.String(),
api: string(ev.Type),
args: args,
})
case *chromedpruntime.EventExceptionThrown:
b.lock.Unlock()
}
}()
go func() {
for ev, err := range exceptionEvents {
if err != nil {
return
}
b.lock.Lock()
defer b.lock.Unlock()
b.exceptionEvents = append(b.exceptionEvents, ev.ExceptionDetails.Error())
b.exceptionEvents = append(b.exceptionEvents, exceptionDetailsString(ev.ExceptionDetails))
b.lock.Unlock()
}
})
}()

// Start the web browser subprocess. Do not use a timeout here or else the browser will close after that timeout.
// The subprocess will be cleaned up at the end of the test when the browser context is cancelled.
require.NoError(t, chromedp.Run(chromeCtx))
require.NoError(t, chromedp.Do(chromeCtx))

// Grant permission to write to the clipboard because the Pinniped formpost UI has a button to copy the
// authcode to the clipboard, and we want to be able to use that button in tests.
require.NoError(t, chromedp.Run(chromeCtx,
chromedpbrowser.SetPermission(
&chromedpbrowser.PermissionDescriptor{Name: chromedppage.PermissionsPolicyFeatureClipboardWrite.String()},
chromedpbrowser.PermissionSettingGranted,
),
))
_, err := chromedp.CallBrowser(chromeCtx, chromedpbrowser.SetPermission, chromedpbrowser.SetPermissionParams{
Permission: &chromedpbrowser.PermissionDescriptor{Name: chromedppage.PermissionsPolicyFeatureClipboardWrite.String()},
Setting: chromedpbrowser.PermissionSettingGranted,
})
require.NoError(t, err)

// To aid in debugging test failures, print the events received from the browser at the end of the test.
t.Cleanup(func() {
Expand Down Expand Up @@ -180,31 +192,43 @@ func OpenBrowser(t *testing.T) *Browser {
return b
}

// exceptionDetailsString formats the exception similar to how ExceptionDetails.Error() did in older versions of cdproto.
func exceptionDetailsString(e *chromedpruntime.ExceptionDetails) string {
if e == nil {
return "<nil exception details>"
}
s := fmt.Sprintf("exception %q (%d:%d)", e.Text, e.LineNumber, e.ColumnNumber)
if e.Exception != nil {
s += ": " + e.Exception.Description
}
return s
}

func (b *Browser) dumpPage(t *testing.T) {
// Log the URL of the current page.
var url string
b.runWithTimeout(t, b.timeout(), chromedp.Location(&url))
url := runWithTimeout(t, b, b.timeout(), chromedp.Location())
t.Logf("Browser URL from end of test %q: %s", t.Name(), url)

// Log the title of the current page.
t.Logf("Browser page title from end of test %q: %q", t.Name(), b.Title(t))

// Log a screenshot of the current page.
var screenBuf []byte
b.runWithTimeout(t, b.timeout(), chromedp.FullScreenshot(&screenBuf, 10)) // low quality to make it smaller
screenBuf := runWithTimeout(t, b, b.timeout(), chromedp.FullScreenshot(10)) // low quality to make it smaller
t.Logf("Browser screenshot (base64 encoded jpeg format) from end of test %q:\n%s\n",
t.Name(), base64.StdEncoding.EncodeToString(screenBuf))

// Log the HTML of the current page.
var html string
b.runWithTimeout(t, b.timeout(), chromedp.ActionFunc(func(ctx context.Context) error {
node, err := chromedpdom.GetDocument().Do(ctx)
html := runWithTimeout(t, b, b.timeout(), func(ctx context.Context, target *chromedp.Target) (string, error) {
doc, err := cdp.Call(ctx, target, chromedpdom.GetDocument, chromedpdom.GetDocumentParams{})
if err != nil {
return "", err
}
res, err := cdp.Call(ctx, target, chromedpdom.GetOuterHTML, chromedpdom.GetOuterHTMLParams{NodeID: doc.Root.NodeID})
if err != nil {
return err
return "", err
}
html, err = chromedpdom.GetOuterHTML().WithNodeID(node.NodeID).Do(ctx)
return err
}))
return res.OuterHTML, nil
})
var htmlBuf bytes.Buffer
gz := gzip.NewWriter(&htmlBuf)
_, err := gz.Write([]byte(html))
Expand All @@ -219,67 +243,62 @@ func (b *Browser) timeout() time.Duration {
return 30 * time.Second
}

func (b *Browser) runWithTimeout(t *testing.T, timeout time.Duration, actions ...chromedp.Action) {
func runWithTimeout[T any](t *testing.T, b *Browser, timeout time.Duration, action chromedp.Action[T]) T {
t.Helper()
timeoutCtx, cancel := context.WithTimeout(b.chromeCtx, timeout)
t.Cleanup(cancel)

err := chromedp.Run(timeoutCtx, actions...)
if err != nil && err == context.Canceled || err == context.DeadlineExceeded {
result, err := chromedp.Run(timeoutCtx, action)
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
require.NoError(t, err, "the browser operation took longer than the allowed timeout")
}
require.NoError(t, err, "the browser operation failed")
return result
}

func (b *Browser) Navigate(t *testing.T, url string) {
t.Helper()
b.runWithTimeout(t, b.timeout(), chromedp.Navigate(url))
runWithTimeout(t, b, b.timeout(), chromedp.Navigate(url))
}

func (b *Browser) Title(t *testing.T) string {
t.Helper()
var title string
b.runWithTimeout(t, b.timeout(), chromedp.Title(&title))
return title
return runWithTimeout(t, b, b.timeout(), chromedp.Title())
}

func (b *Browser) WaitForVisibleElements(t *testing.T, cssSelectors ...string) {
t.Helper()
for _, s := range cssSelectors {
b.runWithTimeout(t, b.timeout(), chromedp.WaitVisible(s, chromedp.ByQuery))
runWithTimeout(t, b, b.timeout(), chromedp.WaitVisible(chromedp.CSS(s)))
}
}

func (b *Browser) TextOfFirstMatch(t *testing.T, cssSelector string) string {
t.Helper()
var text string
b.runWithTimeout(t, b.timeout(), chromedp.Text(cssSelector, &text, chromedp.NodeVisible, chromedp.ByQuery))
return text
return runWithTimeout(t, b, b.timeout(), chromedp.Text(chromedp.CSS(cssSelector), chromedp.NodeVisible))
}

func (b *Browser) AttrValueOfFirstMatch(t *testing.T, cssSelector string, attributeName string) string {
t.Helper()
var value string
var ok bool
b.runWithTimeout(t, b.timeout(), chromedp.AttributeValue(cssSelector, attributeName, &value, &ok, chromedp.ByQuery))
require.Truef(t, ok, "did not find attribute named %q on first element returned by selector %q", attributeName, cssSelector)
return value
attr := runWithTimeout(t, b, b.timeout(), chromedp.AttributeValue(chromedp.CSS(cssSelector), attributeName))
require.Truef(t, attr.Exists, "did not find attribute named %q on first element returned by selector %q", attributeName, cssSelector)
return attr.Value
}

func (b *Browser) SendKeysToFirstMatch(t *testing.T, cssSelector string, runesToType string) {
t.Helper()
b.runWithTimeout(t, b.timeout(), chromedp.SendKeys(cssSelector, runesToType, chromedp.NodeVisible, chromedp.NodeEnabled, chromedp.ByQuery))
runWithTimeout(t, b, b.timeout(), chromedp.SendKeys(chromedp.CSS(cssSelector), runesToType, chromedp.NodeVisible, chromedp.NodeEnabled))
}

func (b *Browser) ClearFirstMatch(t *testing.T, cssSelector string) {
t.Helper()
b.runWithTimeout(t, b.timeout(), chromedp.Clear(cssSelector, chromedp.NodeVisible, chromedp.NodeEnabled, chromedp.ByQuery))
runWithTimeout(t, b, b.timeout(), chromedp.Clear(chromedp.CSS(cssSelector), chromedp.NodeVisible, chromedp.NodeEnabled))
}

func (b *Browser) ClickFirstMatch(t *testing.T, cssSelector string) string {
t.Helper()
var text string
b.runWithTimeout(t, b.timeout(), chromedp.Click(cssSelector, chromedp.NodeVisible, chromedp.NodeEnabled, chromedp.ByQuery))
runWithTimeout(t, b, b.timeout(), chromedp.Click(chromedp.CSS(cssSelector), chromedp.NodeVisible, chromedp.NodeEnabled))
return text
}

Expand All @@ -289,8 +308,8 @@ func (b *Browser) WaitForURL(t *testing.T, regex *regexp.Regexp) {
var lastURL string
testlib.RequireEventuallyf(t,
func(requireEventually *require.Assertions) {
var url string
requireEventually.NoError(chromedp.Run(b.chromeCtx, chromedp.Location(&url)))
url, err := chromedp.Run(b.chromeCtx, chromedp.Location())
requireEventually.NoError(err)
if url != lastURL {
t.Logf("saw URL %s", testlib.MaskTokens(url))
lastURL = url
Expand Down
Loading