Merge pull request #1980 from lightpanda-io/frames_test

Improve async tests
This commit is contained in:
Karl Seguin
2026-03-26 07:41:05 +08:00
committed by GitHub
6 changed files with 80 additions and 36 deletions

View File

@@ -3587,12 +3587,7 @@ test "WebApi: Page" {
}
test "WebApi: Frames" {
// TOO FLAKY, disabled for now
// const filter: testing.LogFilter = .init(&.{.js});
// defer filter.deinit();
// try testing.htmlRunner("frames", .{});
try testing.htmlRunner("frames", .{});
}
test "WebApi: Integration" {

View File

@@ -118,24 +118,24 @@
}
</script>
<script id=link_click>
testing.async(async (restore) => {
let f6;
await new Promise((resolve) => {
let count = 0;
f6 = document.createElement('iframe');
f6.id = 'f6';
f6.addEventListener('load', () => {
if (++count == 2) {
resolve();
return;
}
f6.contentDocument.querySelector('#link').click();
});
f6.src = "support/with_link.html";
document.documentElement.appendChild(f6);
});
restore();
<script id=link_click type=module>
const state = await testing.async();
let count = 0;
let f6 = document.createElement('iframe');
f6.id = 'f6';
f6.addEventListener('load', () => {
if (++count == 2) {
state.resolve();
return;
}
f6.contentDocument.querySelector('#link').click();
});
f6.src = 'support/with_link.html';
document.documentElement.appendChild(f6);
await state.done(() => {
testing.expectEqual("<html><head></head><body>It was clicked!\n</body></html>", f6.contentDocument.documentElement.outerHTML);
});
</script>

View File

@@ -7,7 +7,6 @@
{
let reply = null;
window.addEventListener('message', (e) => {
console.warn('reply')
reply = e.data;
});

View File

@@ -1,7 +1,6 @@
<!DOCTYPE html>
<script>
window.addEventListener('message', (e) => {
console.warn('Frame Message', e.data);
if (e.data === 'ping') {
window.top.postMessage({data: 'pong', origin: e.origin}, '*');
}

View File

@@ -4,6 +4,7 @@
let eventuallies = [];
let async_capture = null;
let current_script_id = null;
let async_pending = 0;
function expectTrue(actual) {
expectEqual(true, actual);
@@ -64,6 +65,25 @@
}
async function async(cb) {
if (cb == undefined) {
let resolve = null
const promise = new Promise((r) => { resolve = r});
async_pending += 1;
return {
promise: promise,
resolve: resolve,
capture: {script_id: document.currentScript.id, stack: new Error().stack},
done: async function(cb) {
await this.promise;
async_pending -= 1;
async_capture = this.capture;
cb();
async_capture = false;
}
};
}
let capture = {script_id: document.currentScript.id, stack: new Error().stack};
await cb(() => { async_capture = capture; });
async_capture = null;
@@ -74,6 +94,10 @@
throw new Error('Failed');
}
if (async_pending > 0) {
return false;
}
for (let e of eventuallies) {
current_script_id = e.script_id;
e.callback();
@@ -97,6 +121,8 @@
throw new Error(`script id: '${script_id}' failed: ${status || 'no assertions'}`);
}
}
return true;
}
const IS_TEST_RUNNER = window.navigator.userAgent.startsWith("Lightpanda/");

View File

@@ -410,21 +410,46 @@ fn runWebApiTest(test_file: [:0]const u8) !void {
page.js.localScope(&ls);
defer ls.deinit();
var try_catch: js.TryCatch = undefined;
try_catch.init(&ls.local);
defer try_catch.deinit();
{
var try_catch: js.TryCatch = undefined;
try_catch.init(&ls.local);
defer try_catch.deinit();
try page.navigate(url, .{});
}
try page.navigate(url, .{});
var runner = try test_session.runner(.{});
try runner.wait(.{ .ms = 2000 });
test_browser.runMicrotasks();
var wait_ms: u32 = 2000;
var timer = try std.time.Timer.start();
while (true) {
var try_catch: js.TryCatch = undefined;
try_catch.init(&ls.local);
defer try_catch.deinit();
ls.local.eval("testing.assertOk()", "testing.assertOk()") catch |err| {
const caught = try_catch.caughtOrError(arena_allocator, err);
std.debug.print("{s}: test failure\nError: {f}\n", .{ test_file, caught });
return err;
};
const js_val = ls.local.exec("testing.assertOk()", "testing.assertOk()") catch |err| {
const caught = try_catch.caughtOrError(arena_allocator, err);
std.debug.print("{s}: test failure\nError: {f}\n", .{ test_file, caught });
return err;
};
if (js_val.isTrue()) {
return;
}
switch (try runner.tick(.{ .ms = 20 })) {
.done => return error.TestNeverSignaledCompletion,
.ok => |next_ms| {
const ms_elapsed = timer.lap() / 1_000_000;
if (ms_elapsed >= wait_ms) {
return error.TestTimedOut;
}
wait_ms -= @intCast(ms_elapsed);
if (next_ms > 0) {
std.Thread.sleep(std.time.ns_per_ms * next_ms);
}
},
}
}
}
// Used by a few CDP tests - wouldn't be sad to see this go.