diff --git a/src/Config.zig b/src/Config.zig index 2fb59dfc..1e5cc9ab 100644 --- a/src/Config.zig +++ b/src/Config.zig @@ -185,6 +185,7 @@ pub const Serve = struct { pub const DumpFormat = enum { html, markdown, + wpt, }; pub const Fetch = struct { diff --git a/src/lightpanda.zig b/src/lightpanda.zig index ca105ce5..5a30c5ff 100644 --- a/src/lightpanda.zig +++ b/src/lightpanda.zig @@ -105,11 +105,62 @@ pub fn fetch(app: *App, url: [:0]const u8, opts: FetchOpts) !void { switch (mode) { .html => try dump.root(page.window._document, opts.dump, writer, page), .markdown => try markdown.dump(page.window._document.asNode(), .{}, writer, page), + .wpt => try dumpWPT(page, writer), } } try writer.flush(); } +fn dumpWPT(page: *Page, writer: *std.Io.Writer) !void { + var ls: js.Local.Scope = undefined; + page.js.localScope(&ls); + defer ls.deinit(); + + var try_catch: js.TryCatch = undefined; + try_catch.init(&ls.local); + defer try_catch.deinit(); + + // return the detailed result. + const dump_script = + \\ JSON.stringify((() => { + \\ const statuses = ['Pass', 'Fail', 'Timeout', 'Not Run', 'Optional Feature Unsupported']; + \\ const parse = (raw) => { + \\ for (const status of statuses) { + \\ const idx = raw.indexOf('|' + status); + \\ if (idx !== -1) { + \\ const name = raw.slice(0, idx); + \\ const rest = raw.slice(idx + status.length + 1); + \\ const message = rest.length > 0 && rest[0] === '|' ? rest.slice(1) : null; + \\ return { name, status, message }; + \\ } + \\ } + \\ return { name: raw, status: 'Unknown', message: null }; + \\ }; + \\ const cases = Object.values(report.cases).map(parse); + \\ return { + \\ url: window.location.href, + \\ status: report.status, + \\ message: report.message, + \\ summary: { + \\ total: cases.length, + \\ passed: cases.filter(c => c.status === 'Pass').length, + \\ failed: cases.filter(c => c.status === 'Fail').length, + \\ timeout: cases.filter(c => c.status === 'Timeout').length, + \\ notrun: cases.filter(c => c.status === 'Not Run').length, + \\ unsupported: cases.filter(c => c.status === 'Optional Feature Unsupported').length + \\ }, + \\ cases + \\ }; + \\ })(), null, 2) + ; + const value = ls.local.exec(dump_script, "dump_script") catch |err| { + const caught = try_catch.caughtOrError(page.call_arena, err); + return writer.print("Caught error trying to access WPT's report: {f}\n", .{caught}); + }; + try writer.writeAll("== WPT Results==\n"); + try writer.writeAll(try value.toStringSliceWithAlloc(page.call_arena)); +} + pub inline fn assert(ok: bool, comptime ctx: []const u8, args: anytype) void { if (!ok) { if (comptime IS_DEBUG) {