Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

Commit f2a11a7

Browse files
committed
feat(plugins): Changed and expanded the plugin API
* Changed the plugin API so that it is more uniform (see docs/plugins.md) * Updated existing plugins to the new API * Added the `onPageLoad` and `onPageSync` entry points for plugins for modifying `browser.get` * Added the `waitForPromise` and `waitForCondition` entry points for plugins for modifying `waitForAngular` * Added tests This closes #2126 and helps out @andresdominguez
1 parent aded26b commit f2a11a7

17 files changed

+673
-359
lines changed

docs/plugins.md

+168-23
Original file line numberDiff line numberDiff line change
@@ -85,64 +85,209 @@ the output of Protractor by returning a results object.
8585
Plugins are node modules which export an object with the following API:
8686

8787
```js
88-
/*
88+
/**
8989
* Sets up plugins before tests are run. This is called after the WebDriver
9090
* session has been started, but before the test framework has been set up.
9191
*
92-
* @param {Object} config The plugin configuration object. Note that
93-
* this is not the entire Protractor config object, just the
94-
* entry in the plugins array for this plugin.
92+
* @this {Object} bound to module.exports
93+
*
94+
* @throws {*} If this function throws an error, a failed assertion is added to
95+
* the test results.
9596
*
96-
* @return Object If an object is returned, it is merged with the Protractor
97-
* result object. May return a promise.
97+
* @return {q.Promise=} Can return a promise, in which case protractor will wait
98+
* for the promise to resolve before continuing. If the promise is
99+
* rejected, a failed assertion is added to the test results.
98100
*/
99-
exports.setup = function(config) {};
101+
exports.setup = function() {};
100102

101-
/*
103+
/**
102104
* This is called after the tests have been run, but before the WebDriver
103105
* session has been terminated.
104106
*
105-
* @param {Object} config The plugin configuration object.
107+
* @this {Object} bound to module.exports
108+
*
109+
* @throws {*} If this function throws an error, a failed assertion is added to
110+
* the test results.
106111
*
107-
* @return Object If an object is returned, it is merged with the Protractor
108-
* result object. May return a promise.
112+
* @return {q.Promise=} Can return a promise, in which case protractor will wait
113+
* for the promise to resolve before continuing. If the promise is
114+
* rejected, a failed assertion is added to the test results.
109115
*/
110-
exports.teardown = function(config) {};
116+
exports.teardown = function() {};
111117

112-
/*
118+
/**
113119
* Called after the test results have been finalized and any jobs have been
114120
* updated (if applicable).
115121
*
116-
* @param {Object} config The plugin configuration object.
122+
* @this {Object} bound to module.exports
123+
*
124+
* @throws {*} If this function throws an error, it is outputted to the console
117125
*
118-
* @return Return values are ignored.
126+
* @return {q.Promise=} Can return a promise, in which case protractor will wait
127+
* for the promise to resolve before continuing. If the promise is
128+
* rejected, an error is logged to the console.
119129
*/
120-
exports.postResults = function(config) {};
130+
exports.postResults = function() {};
121131

122132
/**
123133
* Called after each test block (in Jasmine, this means an `it` block)
124134
* completes.
125135
*
126-
* @param {Object} config The plugin configuration object.
127136
* @param {boolean} passed True if the test passed.
128137
* @param {Object} testInfo information about the test which just ran.
129138
*
130-
* @return Object If an object is returned, it is merged with the Protractor
131-
* result object. May return a promise.
139+
* @this {Object} bound to module.exports
140+
*
141+
* @throws {*} If this function throws an error, a failed assertion is added to
142+
* the test results.
143+
*
144+
* @return {q.Promise=} Can return a promise, in which case protractor will wait
145+
* for the promise to resolve before outputting test results. Protractor
146+
* will *not* wait before executing the next test, however. If the promise
147+
* is rejected, a failed assertion is added to the test results.
148+
*/
149+
exports.postTest = function(passed, testInfo) {};
150+
151+
/**
152+
* This is called inside browser.get() directly after the page loads, and before
153+
* angular bootstraps.
154+
*
155+
* @this {Object} bound to module.exports
156+
*
157+
* @throws {*} If this function throws an error, a failed assertion is added to
158+
* the test results.
159+
*
160+
* @return {q.Promise=} Can return a promise, in which case protractor will wait
161+
* for the promise to resolve before continuing. If the promise is
162+
* rejected, a failed assertion is added to the test results.
163+
*/
164+
exports.onPageLoad = function() {};
165+
166+
/**
167+
* This is called inside browser.get() directly after angular is done
168+
* bootstrapping/synchronizing. If browser.ignoreSynchronization is true, this
169+
* will not be called.
170+
*
171+
* @this {Object} bound to module.exports
172+
*
173+
* @throws {*} If this function throws an error, a failed assertion is added to
174+
* the test results.
175+
*
176+
* @return {q.Promise=} Can return a promise, in which case protractor will wait
177+
* for the promise to resolve before continuing. If the promise is
178+
* rejected, a failed assertion is added to the test results.
179+
*/
180+
exports.onPageStable = function() {};
181+
182+
/**
183+
* Between every webdriver action, Protractor calls browser.waitForAngular() to
184+
* make sure that Angular has no outstanding $http or $timeout calls.
185+
* You can use waitForPromise() to have Protractor additionally wait for your
186+
* custom promise to be resolved inside of browser.waitForAngular().
187+
*
188+
* @this {Object} bound to module.exports
189+
*
190+
* @throws {*} If this function throws an error, a failed assertion is added to
191+
* the test results.
192+
*
193+
* @return {q.Promise=} Can return a promise, in which case protractor will wait
194+
* for the promise to resolve before continuing. If the promise is
195+
* rejected, a failed assertion is added to the test results, and protractor
196+
* will continue onto the next command. If nothing is returned or something
197+
* other than a promise is returned, protractor will continue onto the next
198+
* command.
199+
*/
200+
exports.waitForPromise = function() {};
201+
202+
/**
203+
* Between every webdriver action, Protractor calls browser.waitForAngular() to
204+
* make sure that Angular has no outstanding $http or $timeout calls.
205+
* You can use waitForCondition() to have Protractor additionally wait for your
206+
* custom condition to be truthy.
207+
*
208+
* @this {Object} bound to module.exports
209+
*
210+
* @throws {*} If this function throws an error, a failed assertion is added to
211+
* the test results.
212+
*
213+
* @return {q.Promise<boolean>|boolean} If truthy, Protractor will continue onto
214+
* the next command. If falsy, webdriver will continuously re-run this
215+
* function until it is truthy. If a rejected promise is returned, a failed
216+
* assertion is added to the test results, and protractor will continue onto
217+
* the next command.
132218
*/
133-
exports.postTest = function(config, passed, testInfo) {};
219+
exports.waitForCondition = function() {};
134220

135221
/**
136222
* Used when reporting results.
223+
*
224+
* If you do not specify this property, it will be filled in with something
225+
* reasonable (e.g. the plugin's path)
226+
*
137227
* @type {string}
138228
*/
139229
exports.name = '';
140230
```
141231

142-
Each of these exported properties are totally optional.
232+
Each of these exported properties are optional.
233+
234+
### Provided properties and functions
235+
236+
Extra properties are added to your `module.exports` when Protractor loads your
237+
plugin. These allow your plugin to do things like access its configuration
238+
block or add test results. They are as follows:
239+
240+
```js
241+
/**
242+
* The plugin configuration object. Note that this is not the entire
243+
* Protractor config object, just the entry in the plugins array for this
244+
* plugin.
245+
*
246+
* @type {Object}
247+
*/
248+
exports.config;
249+
250+
/**
251+
* Adds a failed assertion to the test's results.
252+
*
253+
* @param {string} message The error message for the failed assertion
254+
* @param {specName: string, stackTrace: string} options Some optional extra
255+
* information about the assertion:
256+
* - specName The name of the spec which this assertion belongs to.
257+
* Defaults to `PLUGIN_NAME + ' Plugin Tests'`.
258+
* - stackTrace The stack trace for the failure. Defaults to undefined.
259+
* Defaults to `{}`.
260+
*
261+
* @throws {Error} Throws an error if called after results have been reported
262+
*/
263+
exports.addFailure(message, options);
264+
265+
/**
266+
* Adds a passed assertion to the test's results.
267+
*
268+
* @param {specName: string} options Extra information about the assertion:
269+
* - specName The name of the spec which this assertion belongs to.
270+
* Defaults to `PLUGIN_NAME + ' Plugin Tests'`.
271+
* Defaults to `{}`.
272+
*
273+
* @throws {Error} Throws an error if called after results have been reported
274+
*/
275+
exports.addSuccess(options);
276+
277+
/**
278+
* Warns the user that something is problematic.
279+
*
280+
* @param {string} message The message to warn the user about
281+
* @param {specName: string} options Extra information about the assertion:
282+
* - specName The name of the spec which this assertion belongs to.
283+
* Defaults to `PLUGIN_NAME + ' Plugin Tests'`.
284+
* Defaults to `{}`.
285+
*/
286+
exports.addWarning(message, options);
287+
```
143288

144-
The protractor results object follows the format specified in
145-
the [Framework documentation](../lib/frameworks/README.md).
289+
If you specify any of these properties in your plugin file, they will be
290+
overwritten.
146291

147292
Accessibility Plugin
148293
--------------------

lib/frameworks/jasmine.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@ exports.run = function(runner, specs) {
3131
};
3232
RunnerReporter.prototype.reportSpecResults = function(spec) {
3333
var specInfo = {
34-
name: spec.suite.getFullName(),
35-
category: spec.description
34+
name: spec.description,
35+
category: spec.suite.getFullName()
3636
};
37-
if (spec.results().passedCount) {
38-
this.emitter.emit('testPass', specInfo);
39-
} else if (spec.results().failedCount) {
40-
this.emitter.emit('testFail', specInfo);
37+
if (!spec.results().skipped) {
38+
if (spec.results().passed()) {
39+
this.emitter.emit('testPass', specInfo);
40+
} else {
41+
this.emitter.emit('testFail', specInfo);
42+
}
4143
}
4244

4345
var entry = {

0 commit comments

Comments
 (0)