From a6b3ccee58014b7d6c3c70ede703593e5ed968b4 Mon Sep 17 00:00:00 2001 From: PJ Date: Sun, 16 Aug 2026 01:42:50 +0530 Subject: [PATCH] test(browser): drive console.error through to a fired property Claude-Session: https://claude.ai/code/session_01ShuAy8q8ZfPi8KHxwc8JpQ --- test/browser/console_levels_test.go | 27 +++++++++++++++++++ .../browser/testdata/console-quiet/index.html | 23 ++++++++++++++++ test/browser/testdata/console-quiet/spec.ts | 15 +++++++++++ 3 files changed, 65 insertions(+) create mode 100644 test/browser/testdata/console-quiet/index.html create mode 100644 test/browser/testdata/console-quiet/spec.ts diff --git a/test/browser/console_levels_test.go b/test/browser/console_levels_test.go index a1b81de..f977dc9 100644 --- a/test/browser/console_levels_test.go +++ b/test/browser/console_levels_test.go @@ -81,6 +81,33 @@ func TestBrowserConsoleErrorReachesTheSpec(t *testing.T) { } } +// TestBrowserConsoleErrorFiresTheLogProperty drives the same page through the +// whole bundle -> run -> verify pipeline instead of hand-assembling a snapshot. +// The driver holding the entry is not enough on web: every extractor reading is +// replaced by the one the page computed, so state.logs is whatever the page +// says it is, and a page that answers "no logs" leaves noLogcatErrors green on +// a run whose console was full of errors. +func TestBrowserConsoleErrorFiresTheLogProperty(t *testing.T) { + violations := runFixture(t, "console-levels") + if !slices.Contains(violations, "noLogcatErrors") { + t.Fatalf("a page calling console.error ran a whole run without noLogcatErrors firing; violations=%v", violations) + } +} + +// TestBrowserQuietPageKeepsTheLogPropertySatisfied is the other half: a page +// whose console never reaches the error level must leave noLogcatErrors alone, +// so the property is reporting what the page logged rather than being on +// whenever the run is web. +func TestBrowserQuietPageKeepsTheLogPropertySatisfied(t *testing.T) { + violations := runFixture(t, "console-quiet") + if slices.Contains(violations, "noLogcatErrors") { + t.Errorf("noLogcatErrors fired on a page that logged nothing at error level; violations=%v", violations) + } + if !slices.Contains(violations, "counterNeverMoves") { + t.Fatalf("nothing was ever pressed, so the run proves nothing about a property that can fire; violations=%v", violations) + } +} + // TestBrowserConsoleLevelsMapToTheLogcatScale pins what each console verb // becomes once it crosses the driver. driver.LogEntry.Level is the single-letter // logcat scale on every platform, so a spec asking for warnings or debug lines diff --git a/test/browser/testdata/console-quiet/index.html b/test/browser/testdata/console-quiet/index.html new file mode 100644 index 0000000..2020cf6 --- /dev/null +++ b/test/browser/testdata/console-quiet/index.html @@ -0,0 +1,23 @@ + + + + + console-quiet + + + +
0
+ + + diff --git a/test/browser/testdata/console-quiet/spec.ts b/test/browser/testdata/console-quiet/spec.ts new file mode 100644 index 0000000..842a8f4 --- /dev/null +++ b/test/browser/testdata/console-quiet/spec.ts @@ -0,0 +1,15 @@ +import { always, extract, taps } from "@sanderling/spec"; +import { noLogcatErrors } from "@sanderling/spec/defaults/properties"; + +const presses = extract((s) => { + const el = s.ax.find({ id: "count" }); + return el ? parseInt(el.text, 10) || 0 : 0; +}).named("presses"); + +// The run has to actually be driving the page, or noLogcatErrors staying +// satisfied says nothing about whether it can fire at all. +const counterNeverMoves = always(() => presses.current === 0); + +export const properties = { noLogcatErrors, counterNeverMoves }; + +export const actionsRoot = taps;