in lib/runner.ts [314:426]
async run(): Promise<number> {
let testPassed: boolean;
let plugins = this.plugins_ = new Plugins(this.config_);
let pluginPostTestPromises: any;
let browser_: any;
let results: any;
if (this.config_.framework !== 'explorer' && !this.config_.specs.length) {
throw new Error('Spec patterns did not match any files.');
}
if (this.config_.webDriverLogDir || this.config_.highlightDelay) {
this.config_.useBlockingProxy = true;
}
// 1) Setup environment
// noinspection JSValidateTypes
await this.driverprovider_.setupEnv();
// 2) Create a browser and setup globals
browser_ = await this.createBrowser(plugins);
this.setupGlobals_(browser_);
try {
const session = await browser_.getSession();
logger.debug(
'WebDriver session successfully started with capabilities ' +
util.inspect(session.getCapabilities()));
} catch (err) {
logger.error('Unable to start a WebDriver session.');
throw err;
}
// 3) Setup plugins
await plugins.setup();
// 4) Execute test cases
// Do the framework setup here so that jasmine and mocha globals are
// available to the onPrepare function.
let frameworkPath = '';
if (this.config_.framework === 'jasmine' || this.config_.framework === 'jasmine2') {
frameworkPath = './frameworks/jasmine.js';
} else if (this.config_.framework === 'mocha') {
frameworkPath = './frameworks/mocha.js';
} else if (this.config_.framework === 'debugprint') {
// Private framework. Do not use.
frameworkPath = './frameworks/debugprint.js';
} else if (this.config_.framework === 'explorer') {
// Private framework. Do not use.
frameworkPath = './frameworks/explorer.js';
} else if (this.config_.framework === 'custom') {
if (!this.config_.frameworkPath) {
throw new Error(
'When config.framework is custom, ' +
'config.frameworkPath is required.');
}
frameworkPath = this.config_.frameworkPath;
} else {
throw new Error(
'config.framework (' + this.config_.framework + ') is not a valid framework.');
}
if (this.config_.restartBrowserBetweenTests) {
// TODO(sjelin): replace with warnings once `afterEach` support is required
let restartDriver = async () => {
if (!this.frameworkUsesAfterEach) {
this.restartPromise = await browser_.restart();
}
};
this.on('testPass', restartDriver);
this.on('testFail', restartDriver);
}
// We need to save these promises to make sure they're run, but we
// don't
// want to delay starting the next test (because we can't, it's just
// an event emitter).
pluginPostTestPromises = [];
this.on('testPass', (testInfo: any) => {
pluginPostTestPromises.push(plugins.postTest(true, testInfo));
});
this.on('testFail', (testInfo: any) => {
pluginPostTestPromises.push(plugins.postTest(false, testInfo));
});
logger.debug('Running with spec files ' + this.config_.specs);
let testResults = await require(frameworkPath).run(this, this.config_.specs);
// 5) Wait for postTest plugins to finish
results = testResults;
await Promise.all(pluginPostTestPromises);
// 6) Teardown plugins
await plugins.teardown();
// 7) Teardown
results = joinTestLogs(results, plugins.getResults());
this.emit('testsDone', results);
testPassed = results.failedCount === 0;
if (this.driverprovider_.updateJob) {
await this.driverprovider_.updateJob({'passed': testPassed});
}
await this.driverprovider_.teardownEnv();
// 8) Let plugins do final cleanup
await plugins.postResults();
// 9) Exit process
const exitCode = testPassed ? 0 : 1;
await this.shutdown_();
return this.exit_(exitCode);
}