diff --git a/src/cdp/runtime.zig b/src/cdp/runtime.zig index 722f9332..857a1f72 100644 --- a/src/cdp/runtime.zig +++ b/src/cdp/runtime.zig @@ -1,5 +1,7 @@ const std = @import("std"); +const jsruntime = @import("jsruntime"); + const server = @import("../server.zig"); const Ctx = server.Cmd; const cdp = @import("cdp.zig"); @@ -108,11 +110,14 @@ fn runIfWaitingForDebugger( fn evaluate( alloc: std.mem.Allocator, - _: u64, + id: u64, scanner: *std.json.Scanner, - _: *Ctx, + ctx: *Ctx, ) ![]const u8 { + // ensure a page has been previously created + if (ctx.browser.currentSession().page == null) return error.CDPNoPage; + // input const Params = struct { expression: []const u8, @@ -123,7 +128,45 @@ fn evaluate( const sessionID = input.sessionID; std.debug.assert(sessionID != null); - std.log.debug("expr: len {d}", .{input.params.expression.len}); + // save script in file at debug mode + std.log.debug("script {d} length: {d}", .{ id, input.params.expression.len }); + if (std.log.defaultLogEnabled(.debug)) { + const name = try std.fmt.allocPrint(alloc, "id_{d}.js", .{id}); + defer alloc.free(name); + const dir = try std.fs.cwd().makeOpenPath("zig-cache/tmp", .{}); + const f = try dir.createFile(name, .{}); + defer f.close(); + const nb = try f.write(input.params.expression); + std.debug.assert(nb == input.params.expression.len); + const p = try dir.realpathAlloc(alloc, name); + defer alloc.free(p); + std.log.debug("Script {d} saved at {s}", .{ id, p }); + } - return error.CDPNormal; + // evaluate the script in the context of the current page + // TODO: should we use instead the allocator of the page? + // the following code does not work + // const page_alloc = ctx.browser.currentSession().page.?.arena.allocator(); + const session_alloc = ctx.browser.currentSession().alloc; + var res = jsruntime.JSResult{}; + try ctx.browser.currentSession().env.run(session_alloc, input.params.expression, "cdp", &res, null); + defer res.deinit(session_alloc); + + if (!res.success) { + std.log.err("script {d} result: {s}", .{ id, res.result }); + if (res.stack) |stack| { + std.log.err("script {d} stack: {s}", .{ id, stack }); + } + return error.CDPRuntimeEvaluate; + } + std.log.debug("script {d} result: {s}", .{ id, res.result }); + + // TODO: Resp should depends on JS result returned by the JS engine + const Resp = struct { + type: []const u8 = "object", + className: []const u8 = "UtilityScript", + description: []const u8 = "UtilityScript", + objectId: []const u8 = "7481631759780215274.3.2", + }; + return result(alloc, id, Resp, Resp{}, sessionID); } diff --git a/src/server.zig b/src/server.zig index 0170d7d1..2943128b 100644 --- a/src/server.zig +++ b/src/server.zig @@ -19,6 +19,7 @@ const Error = IOError || std.fmt.ParseIntError || cdp.Error || NoError; // -------- const BufReadSize = 1024; // 1KB +const MaxStdOutSize = 512; // ensure debug msg are not too long pub const Cmd = struct { @@ -51,7 +52,8 @@ pub const Cmd = struct { // input const input = self.buf[0..size]; if (std.log.defaultLogEnabled(.debug)) { - std.debug.print("\ninput size: {d}, content: {s}\n", .{ size, input }); + const content = input[0..@min(MaxStdOutSize, size)]; + std.debug.print("\ninput size: {d}, content: {s}\n", .{ size, content }); } // close on exit command @@ -188,7 +190,7 @@ const MsgBuffer = struct { // handle several JSON msg in 1 read const is_combined = _input.len > msg_size; msg = _input[0..msg_size]; - std.log.debug("msg: {s}", .{msg[0..@min(BufReadSize, msg_size)]}); + std.log.debug("msg: {s}", .{msg[0..@min(MaxStdOutSize, msg_size)]}); if (is_combined) { _input = _input[msg_size..]; }