Bug 1775725: Make browser_minimize.js test not depend on the timing of the occlusionstatechange event listeners. r=smaug

The 3 signifiers of the minimization being complete are:
1) The sizemodechange event
2) The occlusionstatechange event (on some platforms)
3) The browsing context becoming inactive

Ideally these would happen in 1-2-3 order, but they aren't consistent.
Specifically, since the browsing context is updated by an
occlusionstatechange event listener, tests that add a
occlusionstatechange event listener will fire before the browsing
context has been updated (since they fire in LIFO order). That makes it
very timing dependent on whether or not a check for browsing context
inactive will succeed, and that's the source of the intermittent
failures here. The safest thing to do is to turn the browsing context
active check into another promise and await the sizemodechange and the
active promise together, and that's what this patch does.

Differential Revision: https://phabricator.services.mozilla.com/D202609
This commit is contained in:
Brad Werth 2024-02-29 16:30:13 +00:00
parent ed1a3b2897
commit 5cf0c11410

View file

@ -12,26 +12,57 @@ add_task(async function () {
ok(isActive(), "Docshell should be active when starting the test");
ok(!document.hidden, "Top level window should be visible");
// When we show or hide the window (including by minimization),
// there are 2 signifiers that the process is complete: the
// sizemodechange event, and the browsing context becoming active
// or inactive. There is another signifier, the
// occlusionstatechange event, but whether or not that event
// is sent is platform-dependent, so it's not very useful. The
// safest way to check for stable state is to build promises
// around sizemodechange and browsing context active and then
// wait for them all to complete, and that's what we do here.
info("Calling window.minimize");
let promiseSizeModeChange = BrowserTestUtils.waitForEvent(
window,
"sizemodechange"
).then(
() => ok(true, "Got sizemodechange."),
() => ok(false, "Rejected sizemodechange.")
);
let promiseBrowserInactive = BrowserTestUtils.waitForCondition(
() => !isActive(),
"Docshell should be inactive."
).then(
() => ok(true, "Got inactive."),
() => ok(false, "Rejected inactive.")
);
window.minimize();
await promiseSizeModeChange;
ok(!isActive(), "Docshell should be Inactive");
await Promise.all([promiseSizeModeChange, promiseBrowserInactive]);
ok(document.hidden, "Top level window should be hidden");
// When we restore the window from minimization, we have the
// same concerns as above, so prepare our promises.
info("Calling window.restore");
promiseSizeModeChange = BrowserTestUtils.waitForEvent(
window,
"sizemodechange"
).then(
() => ok(true, "Got sizemodechange."),
() => ok(false, "Rejected sizemodechange.")
);
let promiseBrowserActive = BrowserTestUtils.waitForCondition(
() => isActive(),
"Docshell should be active."
).then(
() => ok(true, "Got active."),
() => ok(false, "Rejected active.")
);
window.restore();
// On Ubuntu `window.restore` doesn't seem to work, use a timer to make the
// test fail faster and more cleanly than with a test timeout.
await Promise.race([
promiseSizeModeChange,
Promise.all([promiseSizeModeChange, promiseBrowserActive]),
new Promise((resolve, reject) =>
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
setTimeout(() => {
@ -39,11 +70,5 @@ add_task(async function () {
}, 5000)
),
]);
// The sizemodechange event can sometimes be fired before the
// occlusionstatechange event, especially in chaos mode.
if (window.isFullyOccluded) {
await BrowserTestUtils.waitForEvent(window, "occlusionstatechange");
}
ok(isActive(), "Docshell should be active again");
ok(!document.hidden, "Top level window should be visible");
});