From 777f18489572b5143980fc9cd9682e534d235c80 Mon Sep 17 00:00:00 2001 From: Onsi Fakhouri Date: Tue, 2 May 2023 21:29:02 -0600 Subject: [PATCH] emit failure message when running with BILOBA_INTERACTIVE=true --- biloba.go | 9 +++++++-- biloba_suite_test.go | 6 +++++- docs/index.md | 10 +++++++++- go.mod | 14 +++++++------- go.sum | 28 ++++++++++++++-------------- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/biloba.go b/biloba.go index f89dee2..148207f 100644 --- a/biloba.go +++ b/biloba.go @@ -35,6 +35,7 @@ const BILOBA_VERSION = "0.1.3" GinkgoTInterface is the interface by which Biloba receives GinkgoT() */ type GinkgoTInterface interface { + Name() string Helper() Fatal(args ...interface{}) Fatalf(format string, args ...interface{}) @@ -54,6 +55,7 @@ type GinkgoTInterface interface { ParallelProcess() int ParallelTotal() int AttachProgressReporter(func() string) func() + RenderTimeline() string } /* @@ -107,7 +109,6 @@ func SpinUpChrome(ginkgoT GinkgoTInterface, options ...chromedp.ExecAllocatorOpt ginkgoT.Fatalf("failed to spin up chrome: %w", err) return ChromeConnection{} } - bs, err := os.ReadFile(filepath.Join(tmp, "DevToolsActivePort")) if err != nil { ginkgoT.Fatalf("failed to spin up chrome: %w", err) @@ -365,7 +366,11 @@ func (b *Biloba) Prepare() { if os.Getenv("BILOBA_INTERACTIVE") != "" { b.gt.DeferCleanup(func(ctx context.Context) { if b.gt.Failed() { - fmt.Println(b.gt.F("{{red}}{{bold}}This spec failed and you are running in interactive mode. Biloba will sleep so you can interact with the browser. Hit ^C when you're done to shut down the suite{{/}}")) + fmt.Println(b.gt.F("{{red}}{{bold}}This spec failed and you are running in interactive mode. Here's a timeline of the spec:{{/}}")) + fmt.Println(b.gt.Fi(1, b.gt.Name())) + fmt.Println(b.gt.Fi(1, b.gt.RenderTimeline())) + + fmt.Println(b.gt.F("{{red}}{{bold}}Biloba will now sleep so you can interact with the browser. Hit ^C when you're done to shut down the suite{{/}}")) <-ctx.Done() } }) diff --git a/biloba_suite_test.go b/biloba_suite_test.go index 8591293..f76a9b0 100644 --- a/biloba_suite_test.go +++ b/biloba_suite_test.go @@ -76,7 +76,8 @@ func (b *bilobaT) reset() { b.failures = []string{} } -func (b *bilobaT) Helper() { types.MarkAsHelper(1) } +func (b *bilobaT) Name() string { return b.ginkgoT.Name() } +func (b *bilobaT) Helper() { types.MarkAsHelper(1) } func (b *bilobaT) Logf(format string, args ...interface{}) { fmt.Fprintf(b.buffer, format, args...) GinkgoWriter.Printf(format+"\n", args...) @@ -123,6 +124,9 @@ func (b *bilobaT) ParallelTotal() int { func (b *bilobaT) AttachProgressReporter(f func() string) func() { return b.ginkgoT.AttachProgressReporter(f) } +func (b *bilobaT) RenderTimeline() string { + return b.ginkgoT.RenderTimeline() +} func matcherOrEqual(expected interface{}) OmegaMatcher { var matcher OmegaMatcher diff --git a/docs/index.md b/docs/index.md index 9eb5c63..d971f78 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1720,7 +1720,7 @@ var result map[string]int b.Run("({a:1, b:2})", &result) ``` -## Window Size, Screenshots, and Configuration +## Window Size, Screenshots, Configuration, and Debugging There are a few other odds and ends to cover, let's dive in @@ -1798,6 +1798,14 @@ and sit back and watch those windows appear and disappear as you run your specs. - `BilobaConfigFailureScreenshotsSize(width, height)` specifies the window size to use when generating a screenshot on failure - `BilobaConfigProgressReportScreenshotSize(width, height)` specifies the window size to use when generating a screenshot when progress reports are requested +### Debugging +The configuration outlined above has to be added to your code. But sometimes you just want to focus a single failing test, run chrome with headless mode turned off, watch as the test fails, and then play with the browser. You can do this by setting the `BILOBA_INTERACTIVE=true` environment variable: + +```bash +BILOBA_INTERACTIVE=true ginkgo +``` + +Biloba will run with `headless` set to `false` and will emit the failure message when a spec fails and then pause until you send a `^C` signal to end the suite. You should generally do this with a small handful of focused spec and only in serial (running in non-headless mode in parallel is... a lot). {% endraw %} diff --git a/go.mod b/go.mod index 95aaafc..ef3bab9 100644 --- a/go.mod +++ b/go.mod @@ -5,14 +5,14 @@ go 1.19 require ( github.com/chromedp/cdproto v0.0.0-20230220211738-2b1ec77315c9 github.com/chromedp/chromedp v0.8.8 - github.com/onsi/ginkgo/v2 v2.9.2 - github.com/onsi/gomega v1.27.5 - golang.org/x/net v0.8.0 + github.com/onsi/ginkgo/v2 v2.9.3 + github.com/onsi/gomega v1.27.6 + golang.org/x/net v0.9.0 ) require ( github.com/chromedp/sysutil v1.0.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect @@ -22,9 +22,9 @@ require ( github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/tools v0.8.0 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index aceb134..9299a14 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= @@ -34,10 +34,10 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= -github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= -github.com/onsi/gomega v1.27.5 h1:T/X6I0RNFw/kTqgfkZPcQ5KU6vCnWNBGdtrIx2dpGeQ= -github.com/onsi/gomega v1.27.5/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/onsi/ginkgo/v2 v2.9.3 h1:5X2vl/isiKqkrOYjiaGgp3JQOcLV59g5o5SuTMqCcxU= +github.com/onsi/ginkgo/v2 v2.9.3/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -45,16 +45,16 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/exp v0.0.0-20230304125523-9ff063c70017 h1:3Ea9SZLCB0aRIhSEjM+iaGIlzzeDJdpi579El/YIhEE= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=