mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 23:23:28 +00:00
Start unifying test and code
Depends on https://github.com/lightpanda-io/browser/pull/993 There's currently 3 ways to execute a page: 1 - page.navigate (as used in both the 'fetch' and 'serve' commands) 2 - jsRunner as used in unit tests 3 - main_wpt as used in the WPT runner Both jsRunner and main_wpt replicate the page.navigate code, but in their own hack-ish way. main_wpt re-implements the DOM walking in order to extract and execute <script> tags, as well as the needed page lifecycle events. This PR replaces the existing main_wpt loader with a call to page.navigate. To support this, a test HTTP server was added. (The test HTTP server is extracted from the existing unit test test server, and re-used between the two). There are benefits to this approach: 1 - The code is simpler 2 - More of the actual code and flow is tested 3 - There's 1 way to do things (page.navigate) 4 - Having an HTTP server might unlock some WPT tests Technically, we're replacing file IO with network IO i.e. http requests). This has potential downsides: 1 - The tests might be more brittle 2 - The tests might be slower I think we need to run it for a while to see if we get flaky behavior. The goal for following PRs is to bring this unification to the jsRunner.
This commit is contained in:
94
src/main.zig
94
src/main.zig
@@ -719,23 +719,26 @@ test {
|
||||
std.testing.refAllDecls(@This());
|
||||
}
|
||||
|
||||
const TestHTTPServer = @import("TestHTTPServer.zig");
|
||||
|
||||
var test_cdp_server: ?Server = null;
|
||||
var test_http_server: ?TestHTTPServer = null;
|
||||
|
||||
test "tests:beforeAll" {
|
||||
log.opts.level = .err;
|
||||
log.opts.format = .logfmt;
|
||||
|
||||
try testing.setup();
|
||||
|
||||
var wg: std.Thread.WaitGroup = .{};
|
||||
wg.startMany(2);
|
||||
|
||||
{
|
||||
const thread = try std.Thread.spawn(.{}, serveHTTP, .{&wg});
|
||||
const thread = try std.Thread.spawn(.{}, serveCDP, .{&wg});
|
||||
thread.detach();
|
||||
}
|
||||
|
||||
test_http_server = TestHTTPServer.init(testHTTPHandler);
|
||||
{
|
||||
const thread = try std.Thread.spawn(.{}, serveCDP, .{&wg});
|
||||
const thread = try std.Thread.spawn(.{}, TestHTTPServer.run, .{ &test_http_server.?, &wg });
|
||||
thread.detach();
|
||||
}
|
||||
|
||||
@@ -748,59 +751,10 @@ test "tests:afterAll" {
|
||||
if (test_cdp_server) |*server| {
|
||||
server.deinit();
|
||||
}
|
||||
testing.shutdown();
|
||||
}
|
||||
|
||||
fn serveHTTP(wg: *std.Thread.WaitGroup) !void {
|
||||
const address = try std.net.Address.parseIp("127.0.0.1", 9582);
|
||||
|
||||
var listener = try address.listen(.{ .reuse_address = true });
|
||||
defer listener.deinit();
|
||||
|
||||
wg.finish();
|
||||
|
||||
var buf: [1024]u8 = undefined;
|
||||
while (true) {
|
||||
var conn = try listener.accept();
|
||||
defer conn.stream.close();
|
||||
var conn_reader = conn.stream.reader(&buf);
|
||||
var conn_writer = conn.stream.writer(&buf);
|
||||
|
||||
var http_server = std.http.Server.init(conn_reader.interface(), &conn_writer.interface);
|
||||
|
||||
var request = http_server.receiveHead() catch |err| switch (err) {
|
||||
error.HttpConnectionClosing => continue,
|
||||
else => {
|
||||
std.debug.print("Test HTTP Server error: {}\n", .{err});
|
||||
return err;
|
||||
},
|
||||
};
|
||||
|
||||
const path = request.head.target;
|
||||
|
||||
if (std.mem.eql(u8, path, "/loader")) {
|
||||
try request.respond("Hello!", .{
|
||||
.extra_headers = &.{.{ .name = "Connection", .value = "close" }},
|
||||
});
|
||||
} else if (std.mem.eql(u8, path, "/xhr")) {
|
||||
try request.respond("1234567890" ** 10, .{
|
||||
.extra_headers = &.{
|
||||
.{ .name = "Content-Type", .value = "text/html; charset=utf-8" },
|
||||
.{ .name = "Connection", .value = "Close" },
|
||||
},
|
||||
});
|
||||
} else if (std.mem.eql(u8, path, "/xhr/json")) {
|
||||
try request.respond("{\"over\":\"9000!!!\"}", .{
|
||||
.extra_headers = &.{
|
||||
.{ .name = "Content-Type", .value = "application/json" },
|
||||
.{ .name = "Connection", .value = "Close" },
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// should not have an unknown path
|
||||
unreachable;
|
||||
}
|
||||
if (test_http_server) |*server| {
|
||||
server.deinit();
|
||||
}
|
||||
testing.shutdown();
|
||||
}
|
||||
|
||||
fn serveCDP(wg: *std.Thread.WaitGroup) !void {
|
||||
@@ -816,3 +770,31 @@ fn serveCDP(wg: *std.Thread.WaitGroup) !void {
|
||||
return err;
|
||||
};
|
||||
}
|
||||
|
||||
fn testHTTPHandler(req: *std.http.Server.Request) !void {
|
||||
const path = req.head.target;
|
||||
|
||||
if (std.mem.eql(u8, path, "/loader")) {
|
||||
return req.respond("Hello!", .{
|
||||
.extra_headers = &.{.{ .name = "Connection", .value = "close" }},
|
||||
});
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, path, "/xhr")) {
|
||||
return req.respond("1234567890" ** 10, .{
|
||||
.extra_headers = &.{
|
||||
.{ .name = "Content-Type", .value = "text/html; charset=utf-8" },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, path, "/xhr/json")) {
|
||||
return req.respond("{\"over\":\"9000!!!\"}", .{
|
||||
.extra_headers = &.{
|
||||
.{ .name = "Content-Type", .value = "application/json" },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user