Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 42 additions & 34 deletions src/browser/browser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -198,21 +198,21 @@ pub const Page = struct {
}

pub fn wait(self: *Page) !void {
const alloc = self.arena.allocator();
var res = try self.session.env.waitTryCatch(alloc);
defer res.deinit(alloc);

if (res.success) {
log.debug("wait: {s}", .{res.result});
} else {
if (builtin.mode == .Debug and res.stack != null) {
log.info("wait: {s}", .{res.stack.?});
} else {
log.info("wait: {s}", .{res.result});
// try catch
var try_catch: jsruntime.TryCatch = undefined;
try_catch.init(self.session.env);
defer try_catch.deinit();

self.session.env.wait() catch {
const alloc = self.arena.allocator();
if (try try_catch.err(alloc, self.session.env)) |msg| {
defer alloc.free(msg);
log.info("wait error: {s}", .{msg});
return;
}
}

return;
};
log.debug("wait: OK", .{});
}

// spec reference: https://html.spec.whatwg.org/#document-lifecycle
Expand Down Expand Up @@ -322,7 +322,7 @@ pub const Page = struct {
// start JS env
// TODO load the js env concurrently with the HTML parsing.
log.debug("start js env", .{});
try self.session.env.start(alloc);
try self.session.env.start();

// replace the user context document with the new one.
try self.session.env.setUserContext(.{
Expand Down Expand Up @@ -473,22 +473,26 @@ pub const Page = struct {
return;
}

var try_catch: jsruntime.TryCatch = undefined;
try_catch.init(self.session.env);
defer try_catch.deinit();

const opt_text = try parser.nodeTextContent(parser.elementToNode(e));
if (opt_text) |text| {
// TODO handle charset attribute
var res = try self.session.env.execTryCatch(alloc, text, "");
defer res.deinit(alloc);

if (res.success) {
log.debug("eval inline: {s}", .{res.result});
} else {
if (builtin.mode == .Debug and res.stack != null) {
log.info("eval inline: {s}", .{res.stack.?});
} else {
log.info("eval inline: {s}", .{res.result});
const res = self.session.env.exec(text, "") catch {
if (try try_catch.err(alloc, self.session.env)) |msg| {
defer alloc.free(msg);
log.info("eval inline {s}: {s}", .{ text, msg });
}
}
return;
};

if (builtin.mode == .Debug) {
const msg = try res.toString(alloc, self.session.env);
defer alloc.free(msg);
log.debug("eval inline {s}", .{msg});
}
return;
}

Expand Down Expand Up @@ -530,18 +534,22 @@ pub const Page = struct {
// check no body
if (body.len == 0) return FetchError.NoBody;

var res = try self.session.env.execTryCatch(alloc, body, src);
defer res.deinit(alloc);
var try_catch: jsruntime.TryCatch = undefined;
try_catch.init(self.session.env);
defer try_catch.deinit();

if (res.success) {
log.debug("eval remote {s}: {s}", .{ src, res.result });
} else {
if (builtin.mode == .Debug and res.stack != null) {
log.info("eval remote {s}: {s}", .{ src, res.stack.? });
} else {
log.info("eval remote {s}: {s}", .{ src, res.result });
const res = self.session.env.exec(body, src) catch {
if (try try_catch.err(alloc, self.session.env)) |msg| {
defer alloc.free(msg);
log.info("eval remote {s}: {s}", .{ src, msg });
}
return FetchError.JsErr;
};

if (builtin.mode == .Debug) {
const msg = try res.toString(alloc, self.session.env);
defer alloc.free(msg);
log.debug("eval remote {s}: {s}", .{ src, msg });
}
}

Expand Down
18 changes: 12 additions & 6 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,19 @@ fn execJS(
js_env: *jsruntime.Env,
) anyerror!void {
// start JS env
try js_env.start(alloc);
try js_env.start();
defer js_env.stop();

// alias global as self and window
var window = Window.create(null);
window.replaceDocument(doc);
try js_env.bindGlobal(window);

// try catch
var try_catch: jsruntime.TryCatch = undefined;
try_catch.init(js_env.*);
defer try_catch.deinit();

while (true) {

// read cmd
Expand All @@ -57,11 +62,12 @@ fn execJS(
break;
}

const res = try js_env.execTryCatch(alloc, cmd, "cdp");
if (res.success) {
std.debug.print("-> {s}\n", .{res.result});
}
_ = try conn.stream.write(res.result);
const res = try js_env.exec(cmd, "cdp");
const res_str = try res.toString(alloc, js_env.*);
defer alloc.free(res_str);
std.debug.print("-> {s}\n", .{res_str});

_ = try conn.stream.write(res_str);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/main_shell.zig
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fn execJS(
js_env: *jsruntime.Env,
) anyerror!void {
// start JS env
try js_env.start(alloc);
try js_env.start();
defer js_env.stop();

var cli = Client{ .allocator = alloc, .loop = js_env.nat_ctx.loop };
Expand Down
8 changes: 4 additions & 4 deletions src/main_wpt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ pub fn main() !void {
defer arena.deinit();

const res = wpt.run(&arena, wpt_dir, tc, &loader) catch |err| {
const suite = try Suite.init(alloc, tc, false, @errorName(err), null);
const suite = try Suite.init(alloc, tc, false, @errorName(err));
try results.append(suite);

if (out == .text) {
Expand All @@ -151,9 +151,9 @@ pub fn main() !void {
failures += 1;
continue;
};
// no need to call res.deinit() thanks to the arena allocator.
defer res.deinit(arena.allocator());

const suite = try Suite.init(alloc, tc, res.success, res.result, res.stack);
const suite = try Suite.init(alloc, tc, res.ok, res.msg orelse "");
try results.append(suite);

if (out == .json) {
Expand Down Expand Up @@ -196,7 +196,7 @@ pub fn main() !void {
try cases.append(Case{
.pass = suite.pass,
.name = suite.name,
.message = suite.stack orelse suite.message,
.message = suite.message,
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/run_tests.zig
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ fn testExecFn(
defer parser.deinit();

// start JS env
try js_env.start(alloc);
try js_env.start();
defer js_env.stop();

var storageShelf = storage.Shelf.init(alloc);
Expand Down
77 changes: 47 additions & 30 deletions src/wpt/run.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const Client = @import("../async/Client.zig");
// runWPT parses the given HTML file, starts a js env and run the first script
// tags containing javascript sources.
// It loads first the js libs files.
pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const u8, loader: *FileLoader) !jsruntime.JSResult {
pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const u8, loader: *FileLoader) !Res {
const alloc = arena.allocator();
try parser.init();
defer parser.deinit();
Expand Down Expand Up @@ -70,15 +70,16 @@ pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const
try js_env.load(&js_types);

// start JS env
try js_env.start(alloc);
try js_env.start();
defer js_env.stop();

// display console logs
defer {
var res = evalJS(js_env, alloc, "console.join('\\n');", "console") catch unreachable;
const res = evalJS(js_env, alloc, "console.join('\\n');", "console") catch unreachable;
defer res.deinit(alloc);
if (res.result.len > 0) {
std.debug.print("-- CONSOLE LOG\n{s}\n--\n", .{res.result});

if (res.msg != null and res.msg.?.len > 0) {
std.debug.print("-- CONSOLE LOG\n{s}\n--\n", .{res.msg.?});
}
}

Expand All @@ -88,9 +89,6 @@ pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const
window.setStorageShelf(&storageShelf);
try js_env.bindGlobal(&window);

// thanks to the arena, we don't need to deinit res.
var res: jsruntime.JSResult = undefined;

const init =
\\console = [];
\\console.log = function () {
Expand All @@ -100,10 +98,8 @@ pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const
\\ console.push("debug", ...arguments);
\\};
;
res = try evalJS(js_env, alloc, init, "init");
if (!res.success) {
return res;
}
var res = try evalJS(js_env, alloc, init, "init");
if (!res.ok) return res;
res.deinit(alloc);

// loop hover the scripts.
Expand All @@ -122,20 +118,14 @@ pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const
}

res = try evalJS(js_env, alloc, try loader.get(path), src);
if (!res.success) {
return res;
}
if (!res.ok) return res;
res.deinit(alloc);
}

// If the script as a source text, execute it.
const src = try parser.nodeTextContent(s) orelse continue;
res = try evalJS(js_env, alloc, src, "");

// return the first failure.
if (!res.success) {
return res;
}
if (!res.ok) return res;
res.deinit(alloc);
}

Expand All @@ -150,25 +140,52 @@ pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const
);

// wait for all async executions
res = try js_env.waitTryCatch(alloc);
if (!res.success) {
return res;
}
res.deinit(alloc);
var try_catch: jsruntime.TryCatch = undefined;
try_catch.init(js_env);
defer try_catch.deinit();
js_env.wait() catch {
return .{
.ok = false,
.msg = try try_catch.err(alloc, js_env),
};
};

// Check the final test status.
res = try evalJS(js_env, alloc, "report.status;", "teststatus");
if (!res.success) {
return res;
}
if (!res.ok) return res;
res.deinit(alloc);

// return the detailed result.
return try evalJS(js_env, alloc, "report.log", "teststatus");
}

fn evalJS(env: jsruntime.Env, alloc: std.mem.Allocator, script: []const u8, name: ?[]const u8) !jsruntime.JSResult {
return try env.execTryCatch(alloc, script, name);
pub const Res = struct {
ok: bool,
msg: ?[]const u8,

pub fn deinit(res: Res, alloc: std.mem.Allocator) void {
if (res.msg) |msg| {
alloc.free(msg);
}
}
};

fn evalJS(env: jsruntime.Env, alloc: std.mem.Allocator, script: []const u8, name: ?[]const u8) !Res {
var try_catch: jsruntime.TryCatch = undefined;
try_catch.init(env);
defer try_catch.deinit();

const v = env.exec(script, name) catch {
return .{
.ok = false,
.msg = try try_catch.err(alloc, env),
};
};

return .{
.ok = true,
.msg = try v.toString(alloc, env),
};
}

// browse the path to find the tests list.
Expand Down
Loading