/** * Copyright 2017 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const path = require('path'); const { TestRunner, Result, TestResult } = require('./TestRunner'); const { TestCollector, FocusedFilter, Repeater } = require('./TestCollector'); const Reporter = require('./Reporter'); const { Matchers } = require('./Matchers'); class DefaultTestRunner { constructor(options = {}) { const { // Our options. crashIfTestsAreFocusedOnCI = true, exit = true, reporter = true, // Collector options. timeout, // Runner options. parallel = 1, breakOnFailure, totalTimeout, hookTimeout = timeout, // Reporting options. showSlowTests, showMarkedAsFailingTests, verbose, summary, lineBreak, } = options; this._crashIfTestsAreFocusedOnCI = crashIfTestsAreFocusedOnCI; this._exit = exit; this._parallel = parallel; this._breakOnFailure = breakOnFailure; this._totalTimeout = totalTimeout; this._hookTimeout = hookTimeout; this._needReporter = reporter; this._showSlowTests = showSlowTests; this._showMarkedAsFailingTests = showMarkedAsFailingTests; this._verbose = verbose; this._summary = summary; this._lineBreak = lineBreak; this._filter = new FocusedFilter(); this._repeater = new Repeater(); this._collector = new TestCollector({ timeout }); this._api = { ...this._collector.api(), expect: new Matchers().expect, }; this._collector.addSuiteAttribute('only', s => this._filter.focusSuite(s)); this._collector.addSuiteAttribute('skip', s => s.setSkipped(true)); this._collector.addSuiteModifier('repeat', (s, count) => this._repeater.repeat(s, count)); this._collector.addTestAttribute('only', t => this._filter.focusTest(t)); this._collector.addTestAttribute('skip', t => t.setSkipped(true)); this._collector.addTestAttribute('todo', t => t.setSkipped(true)); this._collector.addTestAttribute('slow', t => t.setTimeout(t.timeout() * 3)); this._collector.addTestModifier('repeat', (t, count) => this._repeater.repeat(t, count)); this._api.fdescribe = this._api.describe.only; this._api.xdescribe = this._api.describe.skip; this._api.fit = this._api.it.only; this._api.xit = this._api.it.skip; } collector() { return this._collector; } api() { return this._api; } focusMatchingNameTests(fullNameRegex) { const focusedTests = []; for (const test of this._collector.tests()) { if (fullNameRegex.test(test.fullName())) { this._filter.focusTest(test); focusedTests.push(test); } } return focusedTests; } focusMatchingFileName(filenameRegex) { const focusedFilePaths = []; for (const filePath of this._collector.filePaths()) { if (filenameRegex.test(path.basename(filePath))) { this._filter.focusFilePath(filePath); focusedFilePaths.push(filePath); } } return focusedFilePaths; } repeatAll(repeatCount) { this._repeater.repeat(this._collector.rootSuite(), repeatCount); } async run() { let reporter = null; if (this._needReporter) { const reporterDelegate = { focusedSuites: () => this._filter.focusedSuites(this._collector.suites()), focusedTests: () => this._filter.focusedTests(this._collector.tests()), focusedFilePaths: () => this._filter.focusedFilePaths(this._collector.filePaths()), hasFocusedTestsOrSuitesOrFiles: () => this._filter.hasFocusedTestsOrSuitesOrFiles(), parallel: () => this._parallel, testCount: () => this._collector.tests().length, }; const reporterOptions = { showSlowTests: this._showSlowTests, showMarkedAsFailingTests: this._showMarkedAsFailingTests, verbose: this._verbose, summary: this._summary, lineBreak: this._lineBreak, }; reporter = new Reporter(reporterDelegate, reporterOptions); } if (this._crashIfTestsAreFocusedOnCI && process.env.CI && this._filter.hasFocusedTestsOrSuitesOrFiles()) { if (reporter) await reporter.onStarted([]); const result = new Result(); result.setResult(TestResult.Crashed, '"focused" tests or suites are probitted on CI'); if (reporter) await reporter.onFinished(result); if (this._exit) process.exit(result.exitCode); return result; } const testRuns = this._repeater.createTestRuns(this._filter.filter(this._collector.tests())); const testRunner = new TestRunner(); const result = await testRunner.run(testRuns, { parallel: this._parallel, breakOnFailure: this._breakOnFailure, totalTimeout: this._totalTimeout, hookTimeout: this._hookTimeout, onStarted: (...args) => reporter && reporter.onStarted(...args), onFinished: (...args) => reporter && reporter.onFinished(...args), onTestRunStarted: (...args) => reporter && reporter.onTestRunStarted(...args), onTestRunFinished: (...args) => reporter && reporter.onTestRunFinished(...args), }); if (this._exit) process.exit(result.exitCode); return result; } } module.exports = DefaultTestRunner;