From beb036d2c1dc8fa035ab96e0547ee01b77bdc321 Mon Sep 17 00:00:00 2001 From: PJ Date: Sun, 16 Aug 2026 01:23:45 +0530 Subject: [PATCH] fix(chrome): record console levels on the logcat scale Claude-Session: https://claude.ai/code/session_01ShuAy8q8ZfPi8KHxwc8JpQ --- internal/driver/chrome/driver.go | 22 +++++++++++++++++----- internal/driver/chrome/logs_test.go | 29 ++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/internal/driver/chrome/driver.go b/internal/driver/chrome/driver.go index 37d48a8..dfa177a 100644 --- a/internal/driver/chrome/driver.go +++ b/internal/driver/chrome/driver.go @@ -79,14 +79,10 @@ func New() *Driver { } } } - level := strings.ToUpper(string(e.Type)) - if level == "LOG" { - level = "I" - } d.logsMu.Lock() d.logs = append(d.logs, driver.LogEntry{ UnixMillis: int64(e.Timestamp.Time().UnixMilli()), - Level: level, + Level: consoleLevel(e.Type), Tag: "console", Message: strings.Join(parts, " "), }) @@ -712,6 +708,22 @@ func (d *Driver) Metrics(ctx context.Context, _ string) (driver.Metrics, error) }, nil } +// consoleLevel places a console call on driver.LogEntry's logcat scale. The +// verbs a spec acts on are all named here; the rest are info rather than "E" +// because promoting them would convict an app of an error it never logged. +func consoleLevel(apiType runtime.APIType) string { + switch apiType { + case runtime.APITypeError, runtime.APITypeAssert: + return "E" + case runtime.APITypeWarning: + return "W" + case runtime.APITypeDebug: + return "D" + default: + return "I" + } +} + // meetsLevel keeps an entry whose level the scale cannot rank. Ranking an // unknown level below every threshold drops it, and a dropped entry is // indistinguishable from a quiet app: the caller sees silence and reports it as diff --git a/internal/driver/chrome/logs_test.go b/internal/driver/chrome/logs_test.go index 3457b9a..4cb81ea 100644 --- a/internal/driver/chrome/logs_test.go +++ b/internal/driver/chrome/logs_test.go @@ -1,6 +1,33 @@ package chrome -import "testing" +import ( + "testing" + + "github.com/chromedp/cdproto/runtime" +) + +// Every console verb has to land on the logcat scale driver.LogEntry declares: +// the runner fetches at "E" and the default properties count entries whose +// level equals "E", so a level spelled any other way is an error the spec never +// sees. A verb with no mapping is info, which is honest about severity without +// fabricating an error the page never logged. +func TestConsoleLevel(t *testing.T) { + cases := map[runtime.APIType]string{ + runtime.APITypeError: "E", + runtime.APITypeAssert: "E", + runtime.APITypeWarning: "W", + runtime.APITypeDebug: "D", + runtime.APITypeLog: "I", + runtime.APITypeInfo: "I", + runtime.APITypeTable: "I", + runtime.APIType("countReset"): "I", + } + for apiType, want := range cases { + if got := consoleLevel(apiType); got != want { + t.Errorf("consoleLevel(%q) = %q, want %q", apiType, got, want) + } + } +} // A level the scale does not name is unknown, not verbose. Ranking it below // every threshold is what silently emptied the web log channel: the entries