From f3f65ff0dbb8e52c847c589fdd939176ca7dfb38 Mon Sep 17 00:00:00 2001 From: Sammy Jelin Date: Thu, 18 Aug 2016 00:35:06 -0700 Subject: [PATCH] feat(plugins): support onPrepare in plugins --- docs/plugins.md | 16 +++++++++++++ lib/plugins.ts | 34 +++++++++++++++++++++------- lib/runner.ts | 7 ++++-- spec/plugins/plugins/basic_plugin.js | 5 +++- spec/plugins/specs/smoke_spec.js | 5 ++-- 5 files changed, 54 insertions(+), 13 deletions(-) diff --git a/docs/plugins.md b/docs/plugins.md index 2a22236c4..49d55c0ed 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -94,6 +94,22 @@ Plugins are node modules which export an object with the following API: */ exports.setup = function() {}; +/** + * This is called before the test have been run but after the test framework has + * been set up. Analogous to a config file's `onPreare`. + * + * Very similar to using `setup`, but allows you to access framework-specific + * variables/funtions (e.g. `jasmine.getEnv().addReporter()`) + * + * @throws {*} If this function throws an error, a failed assertion is added to + * the test results. + * + * @return {Q.Promise=} Can return a promise, in which case protractor will wait + * for the promise to resolve before continuing. If the promise is + * rejected, a failed assertion is added to the test results. + */ +explorts.onPrepare = function() {}; + /** * This is called after the tests have been run, but before the WebDriver * session has been terminated. diff --git a/lib/plugins.ts b/lib/plugins.ts index d03494fc0..720bb722b 100644 --- a/lib/plugins.ts +++ b/lib/plugins.ts @@ -1,6 +1,7 @@ var webdriver = require('selenium-webdriver'); import {Logger} from './logger'; import * as Q from 'q'; +import {Promise as Q_Promise} from 'q'; import {ConfigParser} from './configParser'; let logger = new Logger('plugins'); @@ -32,7 +33,23 @@ export interface ProtractorPlugin { * for the promise to resolve before continuing. If the promise is * rejected, a failed assertion is added to the test results. */ - setup?: () => Q.Promise; + setup?: () => Q_Promise; + + /** + * This is called before the test have been run but after the test framework has + * been set up. Analogous to a config file's `onPreare`. + * + * Very similar to using `setup`, but allows you to access framework-specific + * variables/funtions (e.g. `jasmine.getEnv().addReporter()`) + * + * @throws {*} If this function throws an error, a failed assertion is added to + * the test results. + * + * @return {Q.Promise=} Can return a promise, in which case protractor will wait + * for the promise to resolve before continuing. If the promise is + * rejected, a failed assertion is added to the test results. + */ + onPrepare?: () => Q_Promise; /** * This is called after the tests have been run, but before the WebDriver @@ -47,7 +64,7 @@ export interface ProtractorPlugin { * for the promise to resolve before continuing. If the promise is * rejected, a failed assertion is added to the test results. */ - teardown?: () => Q.Promise; + teardown?: () => Q_Promise; /** * Called after the test results have been finalized and any jobs have been @@ -61,7 +78,7 @@ export interface ProtractorPlugin { * for the promise to resolve before continuing. If the promise is * rejected, an error is logged to the console. */ - postResults?: () => Q.Promise; + postResults?: () => Q_Promise; /** * Called after each test block (in Jasmine, this means an `it` block) @@ -80,7 +97,7 @@ export interface ProtractorPlugin { * will *not* wait before executing the next test, however. If the promise * is rejected, a failed assertion is added to the test results. */ - postTest?: (passed: boolean, testInfo: any) => Q.Promise; + postTest?: (passed: boolean, testInfo: any) => Q_Promise; /** * This is called inside browser.get() directly after the page loads, and before @@ -95,7 +112,7 @@ export interface ProtractorPlugin { * for the promise to resolve before continuing. If the promise is * rejected, a failed assertion is added to the test results. */ - onPageLoad?: () => Q.Promise; + onPageLoad?: () => Q_Promise; /** * This is called inside browser.get() directly after angular is done @@ -111,7 +128,7 @@ export interface ProtractorPlugin { * for the promise to resolve before continuing. If the promise is * rejected, a failed assertion is added to the test results. */ - onPageStable?: () => Q.Promise; + onPageStable?: () => Q_Promise; /** * Between every webdriver action, Protractor calls browser.waitForAngular() to @@ -131,7 +148,7 @@ export interface ProtractorPlugin { * other than a promise is returned, protractor will continue onto the next * command. */ - waitForPromise?: () => Q.Promise; + waitForPromise?: () => Q_Promise; /** * Between every webdriver action, Protractor calls browser.waitForAngular() to @@ -150,7 +167,7 @@ export interface ProtractorPlugin { * assertion is added to the test results, and protractor will continue onto * the next command. */ - waitForCondition?: () => Q.Promise; + waitForCondition?: () => Q_Promise; /** * Used to turn off default checks for angular stability @@ -396,6 +413,7 @@ export class Plugins { * @see docs/plugins.md#writing-plugins for information on these functions */ setup: Function = pluginFunFactory('setup', PromiseType.Q); + onPrepare: Function = pluginFunFactory('onPrepare', PromiseType.Q); teardown: Function = pluginFunFactory('teardown', PromiseType.Q); postResults: Function = pluginFunFactory('postResults', PromiseType.Q); postTest: Function = pluginFunFactory('postTest', PromiseType.Q); diff --git a/lib/runner.ts b/lib/runner.ts index ac040c341..be67cf4ee 100644 --- a/lib/runner.ts +++ b/lib/runner.ts @@ -31,6 +31,7 @@ export class Runner extends EventEmitter { preparer_: any; driverprovider_: DriverProvider; o: any; + plugins_: Plugins; constructor(config: Config) { super(); @@ -76,7 +77,9 @@ export class Runner extends EventEmitter { * are finished. */ runTestPreparer(): q.Promise { - return helper.runFilenameOrFn_(this.config_.configDir, this.preparer_); + return this.plugins_.onPrepare().then(() => { + return helper.runFilenameOrFn_(this.config_.configDir, this.preparer_); + }); } /** @@ -268,7 +271,7 @@ export class Runner extends EventEmitter { */ run(): q.Promise { let testPassed: boolean; - let plugins = new Plugins(this.config_); + let plugins = this.plugins_ = new Plugins(this.config_); let pluginPostTestPromises: any; let browser_: any; let results: any; diff --git a/spec/plugins/plugins/basic_plugin.js b/spec/plugins/plugins/basic_plugin.js index e7d6f66a5..e9275155b 100644 --- a/spec/plugins/plugins/basic_plugin.js +++ b/spec/plugins/plugins/basic_plugin.js @@ -1,5 +1,8 @@ module.exports = { setup: function() { - protractor.__BASIC_PLUGIN_RAN = true; + protractor.__BASIC_PLUGIN_RAN_SETUP = true; + }, + onPrepare: function() { + protractor.__BASIC_PLUGIN_RAN_ON_PREPARE = true; } }; diff --git a/spec/plugins/specs/smoke_spec.js b/spec/plugins/specs/smoke_spec.js index d7cc1d1d0..bc7f67f1b 100644 --- a/spec/plugins/specs/smoke_spec.js +++ b/spec/plugins/specs/smoke_spec.js @@ -1,5 +1,6 @@ describe('check if plugin setup ran', function() { - it('should have set protractor.__BASIC_PLUGIN_RAN', function() { - expect(protractor.__BASIC_PLUGIN_RAN).toBe(true); + it('should have set protractor.__BASIC_PLUGIN_RAN_*', function() { + expect(protractor.__BASIC_PLUGIN_RAN_SETUP).toBe(true); + expect(protractor.__BASIC_PLUGIN_RAN_ON_PREPARE).toBe(true); }); });