diff --git a/docs/plugins.md b/docs/plugins.md index df02478c6..0b47c26e4 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -38,14 +38,6 @@ exports.config = { }; ``` -An example of using the 'ngHint' plugin is shown below. - -```javascript - plugins: [{ - path: 'node_modules/protractor/plugins/ngHint', - }] -``` - If your plugin is a node module, you may use it with the `package` option. For example, if you did `npm install example-protractor-plugin` your config would look like: @@ -56,8 +48,8 @@ look like: }] ``` -Finally, if you are writing a small plugin which will only be used by one config -file, you can write the plugin inline into the config: +If you are writing a small plugin which will only be used by one config file, +you can write the plugin inline into the config: ```javascript plugins: [{ @@ -69,6 +61,9 @@ file, you can write the plugin inline into the config: }] ``` +When using plugins, you should specify exactly one of `path`, `package`, or +`inline`. + Writing Plugins --------------- @@ -76,246 +71,15 @@ Plugins are designed to work with any test framework (Jasmine, Mocha, etc), so they use generic hooks which Protractor provides. Plugins may change the output of Protractor by returning a results object. -Plugins are node modules which export an object with the following API: - -```js -/** - * Sets up plugins before tests are run. This is called after the WebDriver - * session has been started, but before the test framework has been set up. - * - * @this {Object} bound to module.exports - * - * @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. - */ -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. - */ -exports.onPrepare = function() {}; - -/** - * This is called after the tests have been run, but before the WebDriver - * session has been terminated. - * - * @this {Object} bound to module.exports - * - * @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. - */ -exports.teardown = function() {}; - -/** - * Called after the test results have been finalized and any jobs have been - * updated (if applicable). - * - * @this {Object} bound to module.exports - * - * @throws {*} If this function throws an error, it is outputted to the console - * - * @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, an error is logged to the console. - */ -exports.postResults = function() {}; - -/** - * Called after each test block (in Jasmine, this means an `it` block) - * completes. - * - * @param {boolean} passed True if the test passed. - * @param {Object} testInfo information about the test which just ran. - * - * @this {Object} bound to module.exports - * - * @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 outputting test results. Protractor - * will *not* wait before executing the next test, however. If the promise - * is rejected, a failed assertion is added to the test results. - */ -exports.postTest = function(passed, testInfo) {}; - -/** - * This is called inside browser.get() directly after the page loads, and before - * angular bootstraps. - * - * @this {Object} bound to module.exports - * - * @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. - */ -exports.onPageLoad = function() {}; - -/** - * This is called inside browser.get() directly after angular is done - * bootstrapping/synchronizing. If browser.ignoreSynchronization is true, this - * will not be called. - * - * @this {Object} bound to module.exports - * - * @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. - */ -exports.onPageStable = function() {}; - -/** - * Between every webdriver action, Protractor calls browser.waitForAngular() to - * make sure that Angular has no outstanding $http or $timeout calls. - * You can use waitForPromise() to have Protractor additionally wait for your - * custom promise to be resolved inside of browser.waitForAngular(). - * - * @this {Object} bound to module.exports - * - * @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, and protractor - * will continue onto the next command. If nothing is returned or something - * other than a promise is returned, protractor will continue onto the next - * command. - */ -exports.waitForPromise = function() {}; - -/** - * Between every webdriver action, Protractor calls browser.waitForAngular() to - * make sure that Angular has no outstanding $http or $timeout calls. - * You can use waitForCondition() to have Protractor additionally wait for your - * custom condition to be truthy. - * - * @this {Object} bound to module.exports - * - * @throws {*} If this function throws an error, a failed assertion is added to - * the test results. - * - * @return {q.Promise|boolean} If truthy, Protractor will continue onto - * the next command. If falsy, webdriver will continuously re-run this - * function until it is truthy. If a rejected promise is returned, a failed - * assertion is added to the test results, and protractor will continue onto - * the next command. - */ -exports.waitForCondition = function() {}; - -/** - * Used when reporting results. - * - * If you do not specify this property, it will be filled in with something - * reasonable (e.g. the plugin's path) - * - * @type {string} - */ -exports.name = ''; - - -/** - * Used to turn off default checks for angular stability - * - * Normally Protractor waits for all $timeout and $http calls to be processed - * before executing the next command. This can be disabled using - * browser.ignoreSynchronization, but that will also disable any - * .waitForPromise or .waitForCondition checks. If you want to - * disable synchronization with angular, but leave in tact any custom plugin - * synchronization, this is the option for you. - * - * This is used by users who want to replace Protractor's synchronization code - * with their own. - * - * @type {boolean} - */ -exports.skipAngularStability -``` - -Each of these exported properties are optional. +Plugins are node modules that export an object implementing the +`ProtractorPlugin` interface. Please see [`/lib/plugins.ts`]( +/lib/plugins.ts#L25) for a list of hooks that are available to plugins. -### Provided properties and functions +##### Provided properties and functions Extra properties are added to your `module.exports` when Protractor loads your plugin. These allow your plugin to do things like access its configuration -block or add test results. They are as follows: - -```js -/** - * The plugin configuration object. Note that this is not the entire - * Protractor config object, just the entry in the plugins array for this - * plugin. - * - * @type {Object} - */ -exports.config; - -/** - * Adds a failed assertion to the test's results. - * - * @param {string} message The error message for the failed assertion - * @param {specName: string, stackTrace: string} options Some optional extra - * information about the assertion: - * - specName The name of the spec which this assertion belongs to. - * Defaults to `PLUGIN_NAME + ' Plugin Tests'`. - * - stackTrace The stack trace for the failure. Defaults to undefined. - * Defaults to `{}`. - * - * @throws {Error} Throws an error if called after results have been reported - */ -exports.addFailure(message, options); - -/** - * Adds a passed assertion to the test's results. - * - * @param {specName: string} options Extra information about the assertion: - * - specName The name of the spec which this assertion belongs to. - * Defaults to `PLUGIN_NAME + ' Plugin Tests'`. - * Defaults to `{}`. - * - * @throws {Error} Throws an error if called after results have been reported - */ -exports.addSuccess(options); - -/** - * Warns the user that something is problematic. - * - * @param {string} message The message to warn the user about - * @param {specName: string} options Extra information about the assertion: - * - specName The name of the spec which this assertion belongs to. - * Defaults to `PLUGIN_NAME + ' Plugin Tests'`. - * Defaults to `{}`. - */ -exports.addWarning(message, options); -``` - -If you specify any of these properties in your plugin file, they will be -overwritten. +block or add test results. See `/lib/plugins.ts` for the full list. ### Writing Plugins in TypeScript @@ -372,15 +136,6 @@ First Party Plugins github repo [angular/protractor-timeline-plugin] (https://github.com/angular/protractor-timeline-plugin). -* ngHint Plugin - - The ngHint plugin uses [Angular Hint](https://github.com/angular/angular-hint) - to generate run-time hinting and then turns these hints into Protractor tests. - It is published at the npm module [`protractor-ng-hint-plugin`] - (https://www.npmjs.com/package/protractor-ng-hint-plugin) and stored at the - github repo [angular/protractor-ng-hint-plugin] - (https://github.com/angular/protractor-ng-hint-plugin). - * Console Plugin (Chrome Only) The console plugin checks the browser log after each test for warnings and @@ -389,6 +144,15 @@ First Party Plugins github repo [angular/protractor-console-plugin] (https://github.com/angular/protractor-console-plugin). +* ngHint Plugin (NOT MAINTAINED) + + The ngHint plugin uses [Angular Hint](https://github.com/angular/angular-hint) + to generate run-time hinting and then turns these hints into Protractor tests. + It is published at the npm module [`protractor-ng-hint-plugin`] + (https://www.npmjs.com/package/protractor-ng-hint-plugin) and stored at the + github repo [angular/protractor-ng-hint-plugin] + (https://github.com/angular/protractor-ng-hint-plugin). + Community Plugins ----------------- diff --git a/lib/index.ts b/lib/index.ts index f8394c575..cca144bec 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -2,12 +2,12 @@ import {ElementHelper, ProtractorBrowser} from './browser'; import {ElementArrayFinder, ElementFinder} from './element'; import {ProtractorExpectedConditions} from './expectedConditions'; import {ProtractorBy} from './locators'; +import {PluginConfig, ProtractorPlugin} from './plugins'; import {Ptor} from './ptor'; import {Runner} from './runner'; // Re-export selenium-webdriver types. export {ActionSequence, Browser, Builder, Button, Capabilities, Capability, error, EventEmitter, FileDetector, Key, logging, promise, Session, until, WebDriver, WebElement, WebElementPromise} from 'selenium-webdriver'; - // Re-export public types. export {ElementHelper, ProtractorBrowser} from './browser'; export {Config} from './config'; @@ -15,7 +15,10 @@ export {ElementArrayFinder, ElementFinder} from './element'; export {ProtractorExpectedConditions} from './expectedConditions'; export {ProtractorBy} from './locators'; export {Ptor} from './ptor'; + export type Runner = Runner; +export type PluginConfig = PluginConfig; +export type ProtractorPlugin = ProtractorPlugin; export let utils = { firefox: require('selenium-webdriver/firefox'), diff --git a/lib/plugins.ts b/lib/plugins.ts index 2346b5b93..b548e4229 100644 --- a/lib/plugins.ts +++ b/lib/plugins.ts @@ -27,7 +27,7 @@ export interface ProtractorPlugin { * Sets up plugins before tests are run. This is called after the WebDriver * session has been started, but before the test framework has been set up. * - * @this {Object} bound to module.exports + * @this {Object} bound to module.exports. * * @throws {*} If this function throws an error, a failed assertion is added to * the test results. @@ -43,7 +43,9 @@ export interface ProtractorPlugin { * 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()`) + * variables/funtions (e.g. `jasmine.getEnv().addReporter()`). + * + * @this {Object} bound to module.exports. * * @throws {*} If this function throws an error, a failed assertion is added to * the test results. @@ -58,7 +60,7 @@ export interface ProtractorPlugin { * This is called after the tests have been run, but before the WebDriver * session has been terminated. * - * @this {Object} bound to module.exports + * @this {Object} bound to module.exports. * * @throws {*} If this function throws an error, a failed assertion is added to * the test results. @@ -73,9 +75,10 @@ export interface ProtractorPlugin { * Called after the test results have been finalized and any jobs have been * updated (if applicable). * - * @this {Object} bound to module.exports + * @this {Object} bound to module.exports. * - * @throws {*} If this function throws an error, it is outputted to the console + * @throws {*} If this function throws an error, it is outputted to the console. + * It is too late to add a failed assertion to the test results. * * @return {Promise=} Can return a promise, in which case protractor will wait * for the promise to resolve before continuing. If the promise is @@ -90,7 +93,7 @@ export interface ProtractorPlugin { * @param {boolean} passed True if the test passed. * @param {Object} testInfo information about the test which just ran. * - * @this {Object} bound to module.exports + * @this {Object} bound to module.exports. * * @throws {*} If this function throws an error, a failed assertion is added to * the test results. @@ -108,7 +111,7 @@ export interface ProtractorPlugin { * * @param {ProtractorBrowser} browser The browser instance which is loading a page. * - * @this {Object} bound to module.exports + * @this {Object} bound to module.exports. * * @throws {*} If this function throws an error, a failed assertion is added to * the test results. @@ -121,12 +124,12 @@ export interface ProtractorPlugin { /** * This is called inside browser.get() directly after angular is done - * bootstrapping/synchronizing. If browser.ignoreSynchronization is true, this - * will not be called. + * bootstrapping/synchronizing. If `browser.ignoreSynchronization` is `true`, + * this will not be called. * * @param {ProtractorBrowser} browser The browser instance which is loading a page. * - * @this {Object} bound to module.exports + * @this {Object} bound to module.exports. * * @throws {*} If this function throws an error, a failed assertion is added to * the test results. @@ -145,7 +148,7 @@ export interface ProtractorPlugin { * * @param {ProtractorBrowser} browser The browser instance which needs invoked `waitForAngular`. * - * @this {Object} bound to module.exports + * @this {Object} bound to module.exports. * * @throws {*} If this function throws an error, a failed assertion is added to * the test results. @@ -168,7 +171,7 @@ export interface ProtractorPlugin { * * @param {ProtractorBrowser} browser The browser instance which needs invoked `waitForAngular`. * - * @this {Object} bound to module.exports + * @this {Object} bound to module.exports. * * @throws {*} If this function throws an error, a failed assertion is added to * the test results. @@ -188,40 +191,44 @@ export interface ProtractorPlugin { * before executing the next command. This can be disabled using * browser.ignoreSynchronization, but that will also disable any * .waitForPromise or .waitForCondition checks. If you want - * to - * disable synchronization with angular, but leave in tact any custom plugin + * to disable synchronization with angular, but leave intact any custom plugin * synchronization, this is the option for you. * - * This is used by users who want to replace Protractor's synchronization code - * This is used by users who want to replace Protractor's synchronization code - * with their own. + * This is used by plugin authors who want to replace Protractor's + * synchronization code with their own. * * @type {boolean} */ skipAngularStability?: boolean; /** - * Used when reporting results. + * The name of the plugin. Used when reporting results. * * If you do not specify this property, it will be filled in with something - * reasonable (e.g. the plugin's path) + * reasonable (e.g. the plugin's path) by Protractor at runtime. * * @type {string} */ name?: string; /** - * The plugin configuration object. Note that this is not the entire - * Protractor config object, just the entry in the plugins array for this - * plugin. + * The plugin's configuration object. + * + * Note: this property is added by Protractor at runtime. Any pre-existing + * value will be overwritten. + * + * Note: that this is not the entire Protractor config object, just the entry + * in the `plugins` array for this plugin. * * @type {Object} */ config?: PluginConfig; /** - * Adds a failed assertion to the test's results. Note: this is added by the - * Protractor API, not to be implemented by the plugin author. + * Adds a failed assertion to the test's results. + * + * Note: this property is added by Protractor at runtime. Any pre-existing + * value will be overwritten. * * @param {string} message The error message for the failed assertion * @param {specName: string, stackTrace: string} options Some optional extra @@ -236,8 +243,10 @@ export interface ProtractorPlugin { addFailure?(message?: string, info?: {specName?: string, stackTrace?: string}): void; /** - * Adds a passed assertion to the test's results. Note: this is added by the - * Protractor API, not to be implemented by the plugin author. + * Adds a passed assertion to the test's results. + * + * Note: this property is added by Protractor at runtime. Any pre-existing + * value will be overwritten. * * @param {specName: string} options Extra information about the assertion: * - specName The name of the spec which this assertion belongs to. @@ -249,8 +258,10 @@ export interface ProtractorPlugin { addSuccess?(info?: {specName?: string}): void; /** - * Warns the user that something is problematic. Note: this is added by the - * Protractor API, not to be implemented by the plugin author. + * Warns the user that something is problematic. + * + * Note: this property is added by Protractor at runtime. Any pre-existing + * value will be overwritten. * * @param {string} message The message to warn the user about * @param {specName: string} options Extra information about the assertion: