Skip to content

Commit

Permalink
chore(docs): Add docs for TypeScript, async/await, & disabling the co…
Browse files Browse the repository at this point in the history
…ntrol flow

* Added information in `/docs/control-flow.md` about disabling the control flow
* Made `/docs/async-await.md`, which redirects to
  `/exampleTypescript/asyncAwait/README.md`
* Made `docs/typescript.md`, which redirects to `/exampleTypescript/`.
* Moved our `/spec/install/noCF/` tests to `/exampleTypescript/noControlFlow/`
* Split `noCF/smokeSpec` into `is_disabled_spec.ts` and `element_spec.ts`.
* Added `exampleTypescript/noControlFlow/fullConf.ts`, which will be useful as
  we add more tests
* Set `exampleTypescript` to compile to es6
* Added information about `@types/jasminewd2` to
  `exampleTypescript/asyncAwait/README.md`
* Added `spec/noCFSmokeConf.js`, `spec/noCFPluginConf.js`, and
  `spec/noCFFullConf.js`, which essentially just redirect to
  `/exampleTypescript/noControlFlow/`.

Also did some mimor cleanup:
* Removed redundent information in `/docs/plugins.md`.  Now redirects to
  `/lib/plugins.ts`.
* Comment cleanup in `/lib/plugins.ts`
* Export some necessary types in `/lib/index.ts`
* Compile more stuff in `/exampleTypescript/`.

Website updates to come in a future change.

Closes angular#3692
  • Loading branch information
sjelin committed Feb 7, 2017
1 parent 0ad2381 commit d574a6c
Show file tree
Hide file tree
Showing 26 changed files with 223 additions and 374 deletions.
4 changes: 4 additions & 0 deletions docs/async-await.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
`async`/`await`
===============

Please see [our TypeScript examples which use `async`/`await`](/exampleTypescript/asyncAwait/).
12 changes: 12 additions & 0 deletions docs/control-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ which are managed by a [control flow](https://github.com/SeleniumHQ/selenium/wik
and adapted for [Jasmine](http://jasmine.github.io/2.3/introduction.html).
A short summary about how Protractor interacts with the control flow is presented below.

Disabling the Control Flow
--------------------------

In the future, the control flow is being removed (see
[SeleniumHQ's github issue](https://github.com/SeleniumHQ/selenium/issues/2969)
for details). To disable the control flow in your tests, you can use the
`SELENIUM_PROMISE_MANAGER: false` [config option](/lib/config.ts#L644).

Instead of the control flow, you can synchronize your commands
with promise chaining or the upcomming ES7 feature `async`/`await`. See
[`/exampleTypescript/noControlFlow/`](/exampleTypescript/noControlFlow/) for
examples of tests with the control flow disabled.

Promises and the Control Flow
-----------------------------
Expand Down
274 changes: 19 additions & 255 deletions docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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: [{
Expand All @@ -69,253 +61,25 @@ 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
---------------

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>|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
* <Plugin>.waitForPromise or <Plugin>.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 who's `module.exports` implement 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

Expand Down Expand Up @@ -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
Expand All @@ -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
-----------------

Expand Down
4 changes: 4 additions & 0 deletions docs/typescript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
TypeScript
==========

Please see [our TypeScript examples](/exampleTypescript/).
7 changes: 6 additions & 1 deletion exampleTypescript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,13 @@ export let config: Config = {

## Ambient typings

Protractor also uses ambient types including jasmine and node. These are brought in via the `tsconfig.json` file, which uses npm module resolution to get types from `node_modules/@types`.
Protractor also uses ambient types including jasmine, jasminewd2, and node. These are brought in via the `tsconfig.json` file, which uses npm module resolution to get types from `node_modules/@types`.

If you are using the jasmine framework for your tests, make sure to do:

```
npm install --save-dev @types/jasmine @types/jasminewd2
```

## Compiling your code

Expand Down
Loading

0 comments on commit d574a6c

Please sign in to comment.