--- a/devtools/client/inspector/markup/test/browser_markup_toggle_03.js
+++ b/devtools/client/inspector/markup/test/browser_markup_toggle_03.js
@@ -4,50 +4,50 @@
"use strict";
// Test toggling (expand/collapse) elements by alt-clicking on twisties, which
// should expand/collapse all the descendants
const TEST_URL = URL_ROOT + "doc_markup_toggle.html";
-add_task(function* () {
- let {inspector} = yield openInspectorForURL(TEST_URL);
+add_task(async function() {
+ let {inspector} = await openInspectorForURL(TEST_URL);
info("Getting the container for the UL parent element");
- let container = yield getContainerForSelector("ul", inspector);
+ let container = await getContainerForSelector("ul", inspector);
info("Alt-clicking on collapsed expander should expand all children");
let onUpdated = inspector.once("inspector-updated");
EventUtils.synthesizeMouseAtCenter(container.expander, {altKey: true},
inspector.markup.doc.defaultView);
- yield onUpdated;
- yield waitForMultipleChildrenUpdates(inspector);
+ await onUpdated;
+ await waitForMultipleChildrenUpdates(inspector);
info("Checking that all nodes exist and are expanded");
- let nodeFronts = yield getNodeFronts(inspector);
+ let nodeFronts = await getNodeFronts(inspector);
for (let nodeFront of nodeFronts) {
let nodeContainer = getContainerForNodeFront(nodeFront, inspector);
ok(nodeContainer, "Container for node " + nodeFront.tagName + " exists");
ok(nodeContainer.expanded,
"Container for node " + nodeFront.tagName + " is expanded");
}
info("Alt-clicking on expanded expander should collapse all children");
EventUtils.synthesizeMouseAtCenter(container.expander, {altKey: true},
inspector.markup.doc.defaultView);
- yield waitForMultipleChildrenUpdates(inspector);
+ await waitForMultipleChildrenUpdates(inspector);
// No need to wait for inspector-updated here since we are not retrieving new nodes.
info("Checking that all nodes are collapsed");
- nodeFronts = yield getNodeFronts(inspector);
+ nodeFronts = await getNodeFronts(inspector);
for (let nodeFront of nodeFronts) {
let nodeContainer = getContainerForNodeFront(nodeFront, inspector);
ok(!nodeContainer.expanded,
"Container for node " + nodeFront.tagName + " is collapsed");
}
});
-function* getNodeFronts(inspector) {
- let nodeList = yield inspector.walker.querySelectorAll(
+async function getNodeFronts(inspector) {
+ let nodeList = await inspector.walker.querySelectorAll(
inspector.walker.rootNode, "ul, li, span, em");
return nodeList.items();
}
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -361,16 +361,20 @@ function takeInstrumentation() {
}
scanWindow(win);
observeWindow(win);
}, { once: true });
});
}
+function isGenerator(value) {
+ return value && typeof value === "object" && typeof value.next === "function";
+}
+
function Tester(aTests, structuredLogger, aCallback) {
this.structuredLogger = structuredLogger;
this.tests = aTests;
this.callback = aCallback;
this._scriptLoader = Services.scriptloader;
this.EventUtils = {};
this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", this.EventUtils);
@@ -655,29 +659,32 @@ Tester.prototype = {
else
this.structuredLogger.info("TEST-INFO | (browser-test.js) | " + msg.replace(/\n$/, "") + "\n");
} catch (ex) {
// Swallow exception so we don't lead to another error being reported,
// throwing us into an infinite loop
}
},
- nextTest: Task.async(function*() {
+ async nextTest() {
if (this.currentTest) {
if (this._coverageCollector) {
this._coverageCollector.recordTestCoverage(this.currentTest.path);
}
// Run cleanup functions for the current test before moving on to the
// next one.
let testScope = this.currentTest.scope;
while (testScope.__cleanupFunctions.length > 0) {
let func = testScope.__cleanupFunctions.shift();
try {
- yield func.apply(testScope);
+ let result = await func.apply(testScope);
+ if (isGenerator(result)) {
+ this.SimpleTest.ok(false, "Cleanup function returned a generator");
+ }
}
catch (ex) {
this.currentTest.addResult(new testResult({
name: "Cleanup function threw an exception",
ex,
allowFailure: this.currentTest.allowFailure,
}));
}
@@ -733,17 +740,17 @@ Tester.prototype = {
}
}, this);
// Clear document.popupNode. The test could have set it to a custom value
// for its own purposes, nulling it out it will go back to the default
// behavior of returning the last opened popup.
document.popupNode = null;
- yield new Promise(resolve => SpecialPowers.flushPrefEnv(resolve));
+ await new Promise(resolve => SpecialPowers.flushPrefEnv(resolve));
if (gConfig.cleanupCrashes) {
let gdir = Services.dirsvc.get("UAppData", Ci.nsIFile);
gdir.append("Crash Reports");
gdir.append("pending");
if (gdir.exists()) {
let entries = gdir.directoryEntries;
while (entries.hasMoreElements()) {
@@ -962,17 +969,17 @@ Tester.prototype = {
this.execTest();
} else {
this.currentTestIndex++;
if (gConfig.repeat)
this.repeat = gConfig.repeat;
this.execTest();
}
});
- }),
+ },
execTest: function Tester_execTest() {
this.structuredLogger.testStart(this.currentTest.path);
this.SimpleTest.reset();
// Load the tests into a testscope
let currentScope = this.currentTest.scope = new testScope(this, this.currentTest, this.currentTest.expected);
@@ -1059,26 +1066,29 @@ Tester.prototype = {
let skipTask = (task) => {
let logger = this.structuredLogger;
logger.deactivateBuffering();
logger.testStatus(this.currentTest.path, task.name, "SKIP");
logger.warning("Skipping test " + task.name);
logger.activateBuffering();
};
- this.Task.spawn(function*() {
+ (async function() {
let task;
while ((task = this.__tasks.shift())) {
if (task.__skipMe || (this.__runOnlyThisTask && task != this.__runOnlyThisTask)) {
skipTask(task);
continue;
}
this.SimpleTest.info("Entering test " + task.name);
try {
- yield task();
+ let result = await task();
+ if (isGenerator(result)) {
+ this.SimpleTest.ok(false, "Task returned a generator");
+ }
} catch (ex) {
if (currentTest.timedOut) {
currentTest.addResult(new testResult({
name: "Uncaught exception received from previously timed out test",
pass: false,
ex,
stack: (typeof ex == "object" && "stack" in ex) ? ex.stack : null,
allowFailure: currentTest.allowFailure,
@@ -1094,17 +1104,17 @@ Tester.prototype = {
allowFailure: currentTest.allowFailure,
}));
}
}
PromiseTestUtils.assertNoUncaughtRejections();
this.SimpleTest.info("Leaving test " + task.name);
}
this.finish();
- }.bind(currentScope));
+ }).call(currentScope);
} else if (typeof scope.test == "function") {
scope.test();
} else {
throw "This test didn't call add_task, nor did it define a generatorTest() function, nor did it define a test() function, so we don't know how to run it.";
}
} catch (ex) {
if (!this.SimpleTest.isIgnoringAllUncaughtExceptions()) {
this.currentTest.addResult(new testResult({
@@ -1409,17 +1419,16 @@ testScope.prototype = {
__waitTimer: null,
__cleanupFunctions: [],
__timeoutFactor: 1,
__expectedMinAsserts: 0,
__expectedMaxAsserts: 0,
EventUtils: {},
SimpleTest: {},
- Task: null,
ContentTask: null,
BrowserTestUtils: null,
TestUtils: null,
ExtensionTestUtils: null,
Assert: null,
_createSandbox() {
let sandbox = Cu.Sandbox(window, {sandboxPrototype: window});
@@ -1440,41 +1449,37 @@ testScope.prototype = {
});
}
}
return sandbox;
},
/**
- * Add a test function which is a Task function.
- *
- * Task functions are functions fed into Task.jsm's Task.spawn(). They are
- * generators that emit promises.
+ * Add a function which returns a promise (usually an async function)
+ * as a test task.
*
- * If an exception is thrown, an assertion fails, or if a rejected
- * promise is yielded, the test function aborts immediately and the test is
- * reported as a failure. Execution continues with the next test function.
- *
- * To trigger premature (but successful) termination of the function, simply
- * return or throw a Task.Result instance.
+ * The task ends when the promise returned by the function resolves or
+ * rejects. If the test function throws, or the promise it returns
+ * rejects, the test is reported as a failure. Execution continues
+ * with the next test function.
*
* Example usage:
*
- * add_task(function test() {
+ * add_task(async function test() {
* let result = yield Promise.resolve(true);
*
* ok(result);
*
- * let secondary = yield someFunctionThatReturnsAPromise(result);
+ * let secondary = await someFunctionThatReturnsAPromise(result);
* is(secondary, "expected value");
* });
*
- * add_task(function test_early_return() {
- * let result = yield somethingThatReturnsAPromise();
+ * add_task(async function test_early_return() {
+ * let result = await somethingThatReturnsAPromise();
*
* if (!result) {
* // Test is ended immediately, with success.
* return;
* }
*
* is(result, "foo");
* });