diff --git a/utils/testrunner/TestCollector.js b/utils/testrunner/TestCollector.js index 784a00213e..434d8cb5ff 100644 --- a/utils/testrunner/TestCollector.js +++ b/utils/testrunner/TestCollector.js @@ -92,15 +92,48 @@ class Repeater { } createTestRuns(tests) { - const testRuns = []; + const suiteToChildren = new Map(); + const rootSuites = new Set(); for (const test of tests) { - let repeat = this._get(test); - for (let suite = test.suite(); suite; suite = suite.parentSuite()) - repeat *= this._get(suite); - for (let i = 0; i < repeat; i++) - testRuns.push(new TestRun(test)); + let children = suiteToChildren.get(test.suite()); + if (!children) { + children = new Set(); + suiteToChildren.set(test.suite(), children); + } + children.add(test); + for (let suite = test.suite(); suite; suite = suite.parentSuite()) { + let children = suiteToChildren.get(suite.parentSuite()); + if (!children) { + children = new Set(); + suiteToChildren.set(suite.parentSuite(), children); + } + children.add(suite); + // Add root suites. + if (!suite.parentSuite()) + rootSuites.add(suite); + } } - return testRuns; + + const collectTests = (testOrSuite) => { + const testOrder = []; + if (testOrSuite instanceof Test) { + testOrder.push(testOrSuite); + } else { + for (const child of suiteToChildren.get(testOrSuite)) + testOrder.push(...collectTests(child)); + } + const repeat = this._repeatCount.has(testOrSuite) ? this._repeatCount.get(testOrSuite) : 1; + const result = []; + for (let i = 0; i < repeat; ++i) + result.push(...testOrder); + return result; + } + + const testOrder = []; + for (const rootSuite of rootSuites) + testOrder.push(...collectTests(rootSuite)); + return testOrder.map(test => new TestRun(test)); + } } diff --git a/utils/testrunner/test/testrunner.spec.js b/utils/testrunner/test/testrunner.spec.js index fda5fe89c8..9515b66e5e 100644 --- a/utils/testrunner/test/testrunner.spec.js +++ b/utils/testrunner/test/testrunner.spec.js @@ -516,6 +516,17 @@ module.exports.addTests = function({describe, fdescribe, xdescribe, it, xit, fit expect(beforeEach).toBe(6); expect(test).toBe(6); }); + it('should repeat without breaking test order', async() => { + const t = new Runner(); + const log = []; + t.describe.repeat(2)('suite', () => { + t.it('uno', () => log.push(1)); + t.it.repeat(2)('dos', () => log.push(2)); + }); + t.it('tres', () => log.push(3)); + await t.run(); + expect(log.join()).toBe('1,2,2,1,2,2,3'); + }); it('should run tests if some fail', async() => { const t = new Runner(); const log = [];