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) + } +}