From dbd57ef989d12b8d20649b858def000411e0e0ac Mon Sep 17 00:00:00 2001 From: PJ Date: Sat, 22 Aug 2026 21:07:15 +0530 Subject: [PATCH] fix(chrome): a failed metrics round trip is an error, not zero bytes performance.memory is absent on plenty of pages and zero is the honest answer there. Swallowing the evaluate error gave that same answer when the round trip never happened, so a run recorded a memory reading it never took. --- internal/driver/chrome/driver.go | 6 +++++- internal/driver/chrome/driver_test.go | 31 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/internal/driver/chrome/driver.go b/internal/driver/chrome/driver.go index 220e7a6..4fcb288 100644 --- a/internal/driver/chrome/driver.go +++ b/internal/driver/chrome/driver.go @@ -971,6 +971,10 @@ func (d *Driver) Health(_ context.Context) (driver.Health, error) { } } +// Metrics reports zero with a nil error on a page that does not expose +// performance.memory, so a failed round trip has to be an error: the two are +// otherwise the same answer, and a run would record a memory reading it never +// took. func (d *Driver) Metrics(ctx context.Context, _ string) (driver.Metrics, error) { runCtx, cancel := d.runCtx(ctx) defer cancel() @@ -981,7 +985,7 @@ func (d *Driver) Metrics(ctx context.Context, _ string) (driver.Metrics, error) return {heap: mem.usedJSHeapSize || 0, totalMem: mem.totalJSHeapSize || 0}; })()` if err := chromedp.Run(runCtx, chromedp.Evaluate(script, &result)); err != nil { - return driver.Metrics{}, nil + return driver.Metrics{}, fmt.Errorf("read performance.memory: %w", err) } heap, _ := result["heap"].(float64) total, _ := result["totalMem"].(float64) diff --git a/internal/driver/chrome/driver_test.go b/internal/driver/chrome/driver_test.go index f612010..103a8b8 100644 --- a/internal/driver/chrome/driver_test.go +++ b/internal/driver/chrome/driver_test.go @@ -1686,3 +1686,34 @@ func TestInstallBundle_AcceptsAPageThatInstallsNoPicker(t *testing.T) { t.Fatalf("InstallBundle refused a bundle that generates no actions: %v", err) } } + +// TestMetrics_AFailedRoundTripIsNotAPageWithoutTheAPI pins the distinction the +// zero-and-nil return erased. performance.memory is absent on plenty of pages +// and zero is the honest answer there, so a round trip that never happened has +// to be an error or a run records a memory reading it never took. +func TestMetrics_AFailedRoundTripIsNotAPageWithoutTheAPI(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "text/html") + _, _ = w.Write([]byte(`
app
`)) + })) + defer server.Close() + + d := New() + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + if err := d.Launch(ctx, server.URL, false, nil); err != nil { + t.Fatalf("Launch: %v", err) + } + if _, err := d.Metrics(ctx, ""); err != nil { + t.Fatalf("Metrics on a live page: %v", err) + } + + if err := d.Terminate(context.Background()); err != nil { + t.Fatalf("Terminate: %v", err) + } + metrics, err := d.Metrics(ctx, "") + if err == nil { + t.Errorf("Metrics returned %+v and a nil error after the tab was gone; "+ + "the run cannot tell that from a page with no performance.memory", metrics) + } +}