diff --git a/testing/mochitest/browser-test.js b/testing/mochitest/browser-test.js index d50e8d4a66a..62e8125f47b 100644 --- a/testing/mochitest/browser-test.js +++ b/testing/mochitest/browser-test.js @@ -242,10 +242,21 @@ Tester.prototype = { // Run the test this.lastStartTime = Date.now(); - this.currentTest.scope.test(); + if ("generatorTest" in this.currentTest.scope) { + if ("test" in this.currentTest.scope) + throw "Cannot run both a generator test and a normal test at the same time."; + + // This test is a generator. It will not finish immediately. + this.currentTest.scope.waitForExplicitFinish(); + var result = this.currentTest.scope.generatorTest(); + this.currentTest.scope.__generator = result; + result.next(); + } else { + this.currentTest.scope.test(); + } } catch (ex) { this.currentTest.addResult(new testResult(false, "Exception thrown", ex, false)); - this.currentTest.scope.__done = true; + this.currentTest.scope.finish(); } // If the test ran synchronously, move to the next test, otherwise the test @@ -354,6 +365,29 @@ function testScope(aTester, aTest) { }, Ci.nsIThread.DISPATCH_NORMAL); }; + this.nextStep = function test_nextStep(arg) { + if (self.__done) { + aTest.addResult(new testResult(false, "nextStep was called too many times", "", false)); + return; + } + + if (!self.__generator) { + aTest.addResult(new testResult(false, "nextStep called with no generator", "", false)); + self.finish(); + return; + } + + try { + self.__generator.send(arg); + } catch (ex if ex instanceof StopIteration) { + // StopIteration means test is finished. + self.finish(); + } catch (ex) { + aTest.addResult(new testResult(false, "Exception thrown", ex, false)); + self.finish(); + } + }; + this.waitForExplicitFinish = function test_waitForExplicitFinish() { self.__done = false; }; @@ -393,6 +427,7 @@ function testScope(aTester, aTest) { } testScope.prototype = { __done: true, + __generator: null, __waitTimer: null, __cleanupFunctions: [], __timeoutFactor: 1,