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
6 changes: 1 addition & 5 deletions src/browser/page.zig
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,7 @@ pub const Page = struct {
std.debug.assert(http_client.intercepted == 0);

const ms = ms_to_next_task orelse blk: {
// TODO: when jsRunner is fully replaced with the
// htmlRunner, we can remove the first part of this
// condition. jsRunner calls `page.wait` far too
// often to enforce this.
if (wait_ms > 100 and wait_ms - ms_remaining < 100) {
if (wait_ms - ms_remaining < 100) {
// Look, we want to exit ASAP, but we don't want
// to exit so fast that we've run none of the
// background jobs.
Expand Down
120 changes: 0 additions & 120 deletions src/testing.zig
Original file line number Diff line number Diff line change
Expand Up @@ -363,126 +363,6 @@ fn isJsonValue(a: std.json.Value, b: std.json.Value) bool {
}

pub const tracking_allocator = @import("root").tracking_allocator.allocator();
pub const JsRunner = struct {
const URL = @import("url.zig").URL;
const Page = @import("browser/page.zig").Page;

page: *Page,
browser: *Browser,
allocator: Allocator,

fn init(alloc: Allocator, opts: RunnerOpts) !JsRunner {
const browser = try alloc.create(Browser);
errdefer alloc.destroy(browser);

browser.* = try Browser.init(test_app);
errdefer browser.deinit();

var session = try browser.newSession();

var page = try session.createPage();

// a bit hacky, but since we aren't going through page.navigate, there's
// some minimum setup we need to do
page.url = try URL.parse(opts.url, null);
try page.window.replaceLocation(.{
.url = try page.url.toWebApi(page.arena),
});

const html_doc = try parser.documentHTMLParseFromStr(opts.html);
try page.setDocument(html_doc);
page.mode = .{ .parsed = {} };

return .{
.page = page,
.browser = browser,
.allocator = alloc,
};
}

pub fn deinit(self: *JsRunner) void {
self.browser.deinit();
self.allocator.destroy(self.browser);
}

const RunOpts = struct {};
pub const Case = std.meta.Tuple(&.{ []const u8, ?[]const u8 });
pub fn testCases(self: *JsRunner, cases: []const Case, _: RunOpts) !void {
const js_context = self.page.main_context;
const arena = self.page.arena;

const start = try std.time.Instant.now();

for (cases, 0..) |case, i| {
var try_catch: Env.TryCatch = undefined;
try_catch.init(js_context);
defer try_catch.deinit();

const value = js_context.exec(case.@"0", null) catch |err| {
if (try try_catch.err(arena)) |msg| {
std.debug.print("{s}\n\nCase: {d}\n{s}\n", .{ msg, i + 1, case.@"0" });
}
return err;
};
_ = self.page.session.wait(100);
@import("root").js_runner_duration += std.time.Instant.since(try std.time.Instant.now(), start);

if (case.@"1") |expected| {
const actual = try value.toString(arena);
if (std.mem.eql(u8, expected, actual) == false) {
std.debug.print("Expected:\n{s}\n\nGot:\n{s}\n\nCase: {d}\n{s}\n", .{ expected, actual, i + 1, case.@"0" });
return error.UnexpectedResult;
}
}
}
}

pub fn exec(self: *JsRunner, src: []const u8, name: ?[]const u8, err_msg: *?[]const u8) !void {
_ = try self.eval(src, name, err_msg);
}

pub fn eval(self: *JsRunner, src: []const u8, name: ?[]const u8, err_msg: *?[]const u8) !Env.Value {
const js_context = self.page.main_context;
const arena = self.page.arena;

var try_catch: Env.TryCatch = undefined;
try_catch.init(js_context);
defer try_catch.deinit();

return js_context.exec(src, name) catch |err| {
if (try try_catch.err(arena)) |msg| {
err_msg.* = msg;
std.debug.print("Error running script: {s}\n", .{msg});
}
return err;
};
}

pub fn dispatchDOMContentLoaded(self: *JsRunner) !void {
const HTMLDocument = @import("browser/html/document.zig").HTMLDocument;
const html_doc = self.page.window.document;
try HTMLDocument.documentIsLoaded(html_doc, self.page);
}
};

const RunnerOpts = struct {
url: []const u8 = "https://lightpanda.io/opensource-browser/",
html: []const u8 =
\\ <div id="content">
\\ <a id="link" href="foo" class="ok">OK</a>
\\ <p id="para-empty" class="ok empty">
\\ <span id="para-empty-child"></span>
\\ </p>
\\ <p id="para"> And</p>
\\ <!--comment-->
\\ </div>
\\
,
};

pub fn jsRunner(alloc: Allocator, opts: RunnerOpts) !JsRunner {
return JsRunner.init(alloc, opts);
}

var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
pub var test_app: *App = undefined;
Expand Down