mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-07-30 09:16:07 -04:00
script: route console output through an optional sink
Since the Zig 0.16 merge, console.log and completion echoes from the agent runtime tests reach the real stdout (0.15 silently swallowed them), polluting the bench.json that CI captures from 'zig build test' and breaking the perf-fmt job's JSON decoding. Add Runtime.console_sink: when set, console lines write there instead of stdout/stderr. The three printing tests now capture their output and assert it, covering console argument joining and the top-level return echo.
This commit is contained in:
@@ -42,6 +42,8 @@ console_data: [std.enums.values(ConsoleMethod).len]ConsoleData,
|
||||
/// clear the live spinner so script output starts on a clean line instead
|
||||
/// of colliding with the indicator; the line still goes to stdout/stderr.
|
||||
console_observer: ?ConsoleObserver = null,
|
||||
/// When set, every console line writes here — stderr-bound methods included.
|
||||
console_sink: ?*std.Io.Writer = null,
|
||||
/// In-flight async `goto`s; emptied before each `runSource` returns.
|
||||
pending_gotos: std.ArrayList(PendingGoto),
|
||||
/// Restarted per `runSource`; backs `PendingGoto.deadline_ms`.
|
||||
@@ -685,6 +687,10 @@ fn invokeConsole(self: *Runtime, method: ConsoleMethod, info: *const v8.Function
|
||||
|
||||
fn writeConsoleLine(self: *Runtime, method: ConsoleMethod, line: []const u8) void {
|
||||
if (self.console_observer) |obs| obs.notify(obs.context);
|
||||
if (self.console_sink) |sink| {
|
||||
sink.print("{s}\n", .{line}) catch {};
|
||||
return;
|
||||
}
|
||||
var buf: [4096]u8 = undefined;
|
||||
const file = if (method.writesStderr()) std.Io.File.stderr() else std.Io.File.stdout();
|
||||
var writer = file.writerStreaming(lp.io, &buf);
|
||||
@@ -1329,6 +1335,10 @@ test "agent script runtime: primitives re-entered from argument callbacks stay i
|
||||
const runtime = try Runtime.init(testing.allocator, testing.test_app, testing.test_session, ®istry);
|
||||
defer runtime.deinit();
|
||||
|
||||
var sink: std.Io.Writer.Allocating = .init(testing.allocator);
|
||||
defer sink.deinit();
|
||||
runtime.console_sink = &sink.writer;
|
||||
|
||||
try runTestScript(runtime,
|
||||
\\const page = new Page();
|
||||
\\await page.goto("http://localhost:9582/src/browser/tests/mcp_actions.html");
|
||||
@@ -1340,6 +1350,7 @@ test "agent script runtime: primitives re-entered from argument callbacks stay i
|
||||
\\console.log("value", { toString() { probed += 1; return page.evaluate("'ok'"); } }, "tail");
|
||||
\\if (probed !== 1) throw new Error("console toString re-entry not exercised");
|
||||
);
|
||||
try testing.expectString("value ok tail\n", sink.written());
|
||||
}
|
||||
|
||||
test "agent script runtime: terminate interrupts local JavaScript" {
|
||||
@@ -1414,11 +1425,16 @@ test "agent script runtime: console is available in agent context" {
|
||||
const runtime = try Runtime.init(testing.allocator, testing.test_app, testing.test_session, ®istry);
|
||||
defer runtime.deinit();
|
||||
|
||||
var sink: std.Io.Writer.Allocating = .init(testing.allocator);
|
||||
defer sink.deinit();
|
||||
runtime.console_sink = &sink.writer;
|
||||
|
||||
try runTestScript(runtime,
|
||||
\\if (typeof console !== "object") throw new Error("missing console");
|
||||
\\if (typeof console.log !== "function") throw new Error("missing console.log");
|
||||
\\console.log("agent console ready");
|
||||
);
|
||||
try testing.expectString("agent console ready\n", sink.written());
|
||||
}
|
||||
|
||||
test "agent script runtime: tool errors throw and stop execution" {
|
||||
@@ -1516,6 +1532,10 @@ test "agent script runtime: top-level await runs in an async wrapper" {
|
||||
const runtime = try Runtime.init(testing.allocator, testing.test_app, testing.test_session, ®istry);
|
||||
defer runtime.deinit();
|
||||
|
||||
var sink: std.Io.Writer.Allocating = .init(testing.allocator);
|
||||
defer sink.deinit();
|
||||
runtime.console_sink = &sink.writer;
|
||||
|
||||
// `await` on a non-goto promise resolves without touching the browser, and
|
||||
// a top-level `return` surfaces as the (otherwise un-echoed) result.
|
||||
try runTestScript(runtime,
|
||||
@@ -1523,4 +1543,5 @@ test "agent script runtime: top-level await runs in an async wrapper" {
|
||||
\\if (x + 2 !== 42) throw new Error("top-level await did not resolve: " + x);
|
||||
\\return x + 2;
|
||||
);
|
||||
try testing.expectString("42\n", sink.written());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user