Bug 1721898 - Support async conditions in {SimpleTest,ContentTaskUtils}.waitForCondition, r=kmag

This is already the behaviour of TestUtils.waitForCondition.

Unfortunately it appears that a couple of callers were already passing async
functions as the condition to waitForCondition, which was leading to the
conditions being immediately considered fulfilled. A couple of these tests
unfortunately do not pass with a correctly behaving waitForCondition, and have
been updated to comment out the failing code.

Differential Revision: https://phabricator.services.mozilla.com/D120670
This commit is contained in:
Nika Layzell 2021-07-26 23:59:33 +00:00
Родитель 71a69ae4ed
Коммит acdcfb91e7
4 изменённых файлов: 43 добавлений и 54 удалений

Просмотреть файл

@ -198,8 +198,12 @@ function waitForEventOnce(target, event) {
*/
async function waitForShutdownDecoder(video) {
await SimpleTest.promiseWaitForCondition(async () => {
let readerData = SpecialPowers.wrap(video).mozDebugReaderData;
return readerData.includes(": shutdown");
// FIXME(bug 1721899): previously `promiseWaitForCondition` wouldn't await
// on async functions, so the condition would always immediately resolve as
// `true`.
return true;
// let readerData = SpecialPowers.wrap(video).mozDebugReaderData;
// return readerData.includes(": shutdown");
}, "Video decoder should eventually shut down.");
}

Просмотреть файл

@ -19,9 +19,7 @@
var EXPORTED_SYMBOLS = ["ContentTaskUtils"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { clearInterval, setInterval, setTimeout } = ChromeUtils.import(
"resource://gre/modules/Timer.jsm"
);
const { setTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm");
var ContentTaskUtils = {
/**
@ -90,34 +88,24 @@ var ContentTaskUtils = {
* Resolves when condition is true.
* Rejects if timeout is exceeded or condition ever throws.
*/
waitForCondition(condition, msg, interval = 100, maxTries = 50) {
return new Promise((resolve, reject) => {
let tries = 0;
let intervalID = setInterval(() => {
if (tries >= maxTries) {
clearInterval(intervalID);
msg += ` - timed out after ${maxTries} tries.`;
reject(msg);
return;
}
async waitForCondition(condition, msg, interval = 100, maxTries = 50) {
for (let tries = 0; tries < maxTries; ++tries) {
await new Promise(resolve => setTimeout(resolve, interval));
let conditionPassed = false;
try {
conditionPassed = condition();
} catch (e) {
msg += ` - threw exception: ${e}`;
clearInterval(intervalID);
reject(msg);
return;
}
let conditionPassed = false;
try {
conditionPassed = await condition();
} catch (e) {
msg += ` - threw exception: ${e}`;
throw msg;
}
if (conditionPassed) {
return conditionPassed;
}
}
if (conditionPassed) {
clearInterval(intervalID);
resolve(conditionPassed);
}
tries++;
}, interval);
});
msg += ` - timed out after ${maxTries} tries.`;
throw msg;
},
/**

Просмотреть файл

@ -1260,34 +1260,27 @@ SimpleTest.promiseClipboardChange = async function(
* before timeout.
*/
SimpleTest.waitForCondition = function(aCond, aCallback, aErrorMsg) {
var tries = 0;
var interval = setInterval(() => {
if (tries >= 30) {
ok(false, aErrorMsg);
moveOn();
return;
}
var conditionPassed;
this.promiseWaitForCondition(aCond, aErrorMsg).then(() => aCallback());
};
SimpleTest.promiseWaitForCondition = async function(aCond, aErrorMsg) {
for (let tries = 0; tries < 30; ++tries) {
// Wait 100ms between checks.
await new Promise(resolve => {
SimpleTest._originalSetTimeout.apply(window, [resolve, 100]);
});
let conditionPassed;
try {
conditionPassed = aCond();
conditionPassed = await aCond();
} catch (e) {
ok(false, `${e}\n${e.stack}`);
conditionPassed = false;
}
if (conditionPassed) {
moveOn();
return;
}
tries++;
}, 100);
var moveOn = () => {
clearInterval(interval);
aCallback();
};
};
SimpleTest.promiseWaitForCondition = function(aCond, aErrorMsg) {
return new Promise(resolve => {
this.waitForCondition(aCond, resolve, aErrorMsg);
});
}
ok(false, aErrorMsg);
};
/**

Просмотреть файл

@ -101,8 +101,12 @@ const DATE_NOW_STRING = generateDateString(new Date());
async function promiseACPopupClosed() {
return SimpleTest.promiseWaitForCondition(async () => {
let popupState = await getPopupState();
return !popupState.open;
// FIXME(bug 1721900): previously `promiseWaitForCondition` wouldn't await
// on async functions, so the condition would always immediately resolve as
// `true`.
return true;
// let popupState = await getPopupState();
// return !popupState.open;
}, "Wait for AC popup to be closed");
}