From ecc322a0a226d5dc6dc8bf5085f232149aa11db6 Mon Sep 17 00:00:00 2001 From: Sammy Jelin Date: Mon, 6 Feb 2017 18:07:35 -0800 Subject: [PATCH] chore(docs): Add docs for TypeScript, async/await, & disabling the control 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 https://github.com/angular/protractor/issues/3692 --- docs/async-await.md | 4 + docs/control-flow.md | 12 + docs/plugins.md | 274 ++---------------- docs/typescript.md | 4 + exampleTypescript/README.md | 7 +- exampleTypescript/asyncAwait/README.md | 36 +-- exampleTypescript/asyncAwait/conf.ts | 3 +- exampleTypescript/noControlFlow/fullConf.ts | 24 ++ .../noControlFlow/pluginConf.ts | 11 +- exampleTypescript/noControlFlow/smokeConf.ts | 21 ++ .../noControlFlow/specs/element_spec.ts | 0 .../noControlFlow/specs/is_disabled_spec.ts | 16 + .../noControlFlow/specs}/plugin_spec.ts | 0 exampleTypescript/package.json | 3 +- exampleTypescript/tsconfig.json | 9 +- lib/index.ts | 5 +- lib/plugins.ts | 67 +++-- package.json | 1 + scripts/test.js | 3 + spec/install/noCFSmokeConf.ts | 18 -- spec/install/test.js | 2 - spec/noCFFullConf.js | 12 + spec/noCFPluginConf.js | 12 + spec/noCFSmokeConf.js | 12 + spec/tsconfig.json | 21 -- 25 files changed, 220 insertions(+), 357 deletions(-) create mode 100644 docs/async-await.md create mode 100644 docs/typescript.md create mode 100644 exampleTypescript/noControlFlow/fullConf.ts rename spec/install/noCFPluginConf.ts => exampleTypescript/noControlFlow/pluginConf.ts (76%) create mode 100644 exampleTypescript/noControlFlow/smokeConf.ts rename spec/install/noCF/smoke_spec.ts => exampleTypescript/noControlFlow/specs/element_spec.ts (100%) create mode 100644 exampleTypescript/noControlFlow/specs/is_disabled_spec.ts rename {spec/install/noCF => exampleTypescript/noControlFlow/specs}/plugin_spec.ts (100%) delete mode 100644 spec/install/noCFSmokeConf.ts create mode 100644 spec/noCFFullConf.js create mode 100644 spec/noCFPluginConf.js create mode 100644 spec/noCFSmokeConf.js delete mode 100644 spec/tsconfig.json diff --git a/docs/async-await.md b/docs/async-await.md new file mode 100644 index 000000000..e4ecd2e57 --- /dev/null +++ b/docs/async-await.md @@ -0,0 +1,4 @@ +`async`/`await` +=============== + +Please see [our TypeScript examples which use `async`/`await`](/exampleTypescript/asyncAwait/). diff --git a/docs/control-flow.md b/docs/control-flow.md index 4d8c9e65e..e57729dea 100644 --- a/docs/control-flow.md +++ b/docs/control-flow.md @@ -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 ----------------------------- diff --git a/docs/plugins.md b/docs/plugins.md index df02478c6..9d2e86f6d 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 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. Again, 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/docs/typescript.md b/docs/typescript.md new file mode 100644 index 000000000..81c896d36 --- /dev/null +++ b/docs/typescript.md @@ -0,0 +1,4 @@ +TypeScript +========== + +Please see [our TypeScript examples](/exampleTypescript/). diff --git a/exampleTypescript/README.md b/exampleTypescript/README.md index 48b33153b..ed64002ed 100644 --- a/exampleTypescript/README.md +++ b/exampleTypescript/README.md @@ -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 jasmine in your tests, make sure to do: + +``` +npm install --save-dev @types/jasmine @types/jasminewd2 +``` ## Compiling your code diff --git a/exampleTypescript/asyncAwait/README.md b/exampleTypescript/asyncAwait/README.md index 2c482e5ed..0e0ca3cfc 100644 --- a/exampleTypescript/asyncAwait/README.md +++ b/exampleTypescript/asyncAwait/README.md @@ -2,28 +2,28 @@ =============================================== The Web Driver Control Flow is used to synchronize your commands so they reach -the browser in the correct order (see [control-flow.md]( -../../docs/control-flow.md) for details). In the future, the control flow is -being removed, however (see [github issue]( -https://github.com/SeleniumHQ/selenium/issues/2969) for details). Instead of -the control flow, you can synchronize your commands with promise chaining or the -upcomming ES7 feature `async`/`await`. However, you cannot use a mix of -`async`/`await` and the control flow: `async`/`await` causes the control flow to -become unreliable (see [github issue]( -https://github.com/SeleniumHQ/selenium/issues/3037)). So if you `async`/`await` -anywhere in a spec, you should use `await` or promise chaining to handle all -asynchronous activity (e.g. any command interacting with the browser) for the -rest of that test. - -In the near future there will be an option to disable the Web Driver control -flow entierly (see https://github.com/angular/protractor/issues/3691). If you -are using `async`/`await`, it is highly recommended that you disable the Web -Driver control flow. +the browser in the correct order (see +[/docs/control-flow.md](/docs/control-flow.md) for details). In the future, the +control flow is being removed, however (see [SeleniumHQ's github +issue](https://github.com/SeleniumHQ/selenium/issues/2969) for details). +Instead of the control flow, you can synchronize your commands with promise +chaining or the upcomming ES7 feature `async`/`await`. +However, you cannot use a mix of `async`/`await` and the control flow: +`async`/`await` causes the control flow to become unreliable (see +[github issue]( https://github.com/SeleniumHQ/selenium/issues/3037)). So if you +`async`/`await` anywhere in a spec, you should use the +`SELENIUM_PROMISE_MANAGER: false` [config option](/lib/config.ts#L644). Compiling `async`/`await` syntax ================================ `async`/`await` syntax is currently accessible via typescript if you compile -using `tsc -t ES2015 `. You can also compile it using [regenerator]( +using `--target ES2015` or above. You can also compile it using [regenerator]( https://github.com/facebook/regenerator). + + +More Examples +============= + +More examples can be found under [`/exampleTypescript/noControlFlow/`](/../noControlFlow). diff --git a/exampleTypescript/asyncAwait/conf.ts b/exampleTypescript/asyncAwait/conf.ts index 14d32e8a1..e73e026c3 100644 --- a/exampleTypescript/asyncAwait/conf.ts +++ b/exampleTypescript/asyncAwait/conf.ts @@ -11,5 +11,6 @@ export let config: Config = { browserName: 'chrome' }, specs: [ 'spec.js' ], - seleniumAddress: 'http://localhost:4444/wd/hub' + seleniumAddress: 'http://localhost:4444/wd/hub', + SELENIUM_PROMISE_MANAGER: false }; diff --git a/exampleTypescript/noControlFlow/fullConf.ts b/exampleTypescript/noControlFlow/fullConf.ts new file mode 100644 index 000000000..9c0968ea1 --- /dev/null +++ b/exampleTypescript/noControlFlow/fullConf.ts @@ -0,0 +1,24 @@ +import {Config} from '../..'; +const env = require('../../environment'); + +export let config: Config = { + seleniumAddress: 'http://localhost:4444/wd/hub', + + framework: 'jasmine', + + specs: [ + 'specs/*_spec.js' + ], + + exclude: [ + 'specs/plugin_spec.js' + ], + + capabilities: { + browserName: 'chrome' + }, + + baseUrl: 'http://localhost:8081/ng1/', + + SELENIUM_PROMISE_MANAGER: false +}; diff --git a/spec/install/noCFPluginConf.ts b/exampleTypescript/noControlFlow/pluginConf.ts similarity index 76% rename from spec/install/noCFPluginConf.ts rename to exampleTypescript/noControlFlow/pluginConf.ts index 42bbfda96..c24c6976c 100644 --- a/spec/install/noCFPluginConf.ts +++ b/exampleTypescript/noControlFlow/pluginConf.ts @@ -1,20 +1,21 @@ import * as q from 'q'; import {Config, protractor} from 'protractor'; import {promise as wdpromise} from 'selenium-webdriver'; -const env = require('../../environment'); export let config: Config = { - seleniumAddress: env.seleniumAddress, + seleniumAddress: 'http://localhost:4444/wd/hub', framework: 'jasmine', specs: [ - 'noCF/plugin_spec.js' + 'specs/plugin_spec.js' ], - capabilities: env.capabilities, + capabilities: { + browserName: 'chrome' + }, - baseUrl: env.baseUrl + '/ng1/', + baseUrl: 'http://localhost:8081/ng1/', plugins: [{ inline: { diff --git a/exampleTypescript/noControlFlow/smokeConf.ts b/exampleTypescript/noControlFlow/smokeConf.ts new file mode 100644 index 000000000..0c395c2bf --- /dev/null +++ b/exampleTypescript/noControlFlow/smokeConf.ts @@ -0,0 +1,21 @@ +import {Config} from '../..'; +const env = require('../../environment'); + +export let config: Config = { + seleniumAddress: 'http://localhost:4444/wd/hub', + + framework: 'jasmine', + + specs: [ + 'specs/is_disabled_spec.js', + 'specs/element_spec.js' + ], + + capabilities: { + browserName: 'chrome' + }, + + baseUrl: 'http://localhost:8081/ng1/', + + SELENIUM_PROMISE_MANAGER: false +}; diff --git a/spec/install/noCF/smoke_spec.ts b/exampleTypescript/noControlFlow/specs/element_spec.ts similarity index 100% rename from spec/install/noCF/smoke_spec.ts rename to exampleTypescript/noControlFlow/specs/element_spec.ts diff --git a/exampleTypescript/noControlFlow/specs/is_disabled_spec.ts b/exampleTypescript/noControlFlow/specs/is_disabled_spec.ts new file mode 100644 index 000000000..8acd1c77d --- /dev/null +++ b/exampleTypescript/noControlFlow/specs/is_disabled_spec.ts @@ -0,0 +1,16 @@ +import {browser, promise as ppromise} from 'protractor'; + +describe('verify control flow is off', function() { + it('should have set webdriver.promise.USE_PROMISE_MANAGER', () => { + expect((ppromise as any).USE_PROMISE_MANAGER).toBe(false); + }); + + it('should not wait on one command before starting another', async function() { + // Wait forever + browser.controlFlow().wait( + (browser.controlFlow() as any).promise((): void => undefined) as ppromise.Promise); + + // then return + await browser.controlFlow().execute(() => ppromise.when(null)); + }); +}); diff --git a/spec/install/noCF/plugin_spec.ts b/exampleTypescript/noControlFlow/specs/plugin_spec.ts similarity index 100% rename from spec/install/noCF/plugin_spec.ts rename to exampleTypescript/noControlFlow/specs/plugin_spec.ts diff --git a/exampleTypescript/package.json b/exampleTypescript/package.json index d01641fd6..7a4650327 100644 --- a/exampleTypescript/package.json +++ b/exampleTypescript/package.json @@ -6,11 +6,12 @@ "license": "MIT", "scripts": { "tsc": "tsc", - "pretest": "npm run tsc", + "prepublish": "npm run tsc", "test": "protractor tmp/conf.js" }, "dependencies": { "@types/jasmine": "^2.5.38", + "@types/jasminewd2": "^2.0.0", "jasmine": "^2.4.1", "protractor": "file:../", "typescript": "~2.0.0" diff --git a/exampleTypescript/tsconfig.json b/exampleTypescript/tsconfig.json index aa7469576..bbf56bf53 100644 --- a/exampleTypescript/tsconfig.json +++ b/exampleTypescript/tsconfig.json @@ -1,17 +1,14 @@ { "compilerOptions": { - "target": "es5", + "target": "es6", "module": "commonjs", "moduleResolution": "node", "sourceMap": false, "declaration": false, "noImplicitAny": false, - "outDir": "tmp", - "types": ["node", "jasmine"] + "outDir": "tmp" }, "exclude": [ - "node_modules", - "asyncAwait", - "plugins.ts" + "node_modules" ] } 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..167d5195d 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 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 - * 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: diff --git a/package.json b/package.json index 7d11634eb..c308fe531 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "scripts": { "format": "gulp format", "install_testapp": "cd testapp && npm install", + "compile_exampleTS": "cd exampleTypescript && npm install", "prepublish": "gulp prepublish", "pretest": "gulp pretest", "start": "cd testapp && npm start", diff --git a/scripts/test.js b/scripts/test.js index b2f8421cd..f1b3e979f 100755 --- a/scripts/test.js +++ b/scripts/test.js @@ -38,6 +38,9 @@ var passingTests = [ 'node built/cli.js spec/noGlobalsConf.js', 'node built/cli.js spec/angular2Conf.js', 'node built/cli.js spec/hybridConf.js', + 'node built/cli.js spec/noCFSmokeConf.js', + 'node built/cli.js spec/noCFPluginConf.js', + 'node built/cli.js spec/noCFFullConf.js', 'node scripts/driverProviderAttachSession.js', 'node scripts/errorTest.js', // Interactive Element Explorer tasks diff --git a/spec/install/noCFSmokeConf.ts b/spec/install/noCFSmokeConf.ts deleted file mode 100644 index 0e5cf1942..000000000 --- a/spec/install/noCFSmokeConf.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {Config} from '../..'; -const env = require('../../environment'); - -export let config: Config = { - seleniumAddress: env.seleniumAddress, - - framework: 'jasmine', - - specs: [ - 'noCF/smoke_spec.js' - ], - - capabilities: env.capabilities, - - baseUrl: env.baseUrl + '/ng1/', - - SELENIUM_PROMISE_MANAGER: false -}; diff --git a/spec/install/test.js b/spec/install/test.js index f0e56b5a8..8e182e79a 100644 --- a/spec/install/test.js +++ b/spec/install/test.js @@ -62,5 +62,3 @@ install(); tsc(); test('tmp/conf.js'); test('tmp/typescript_conf.js'); -test('tmp/noCFSmokeConf.js'); -test('tmp/noCFPluginConf.js'); diff --git a/spec/noCFFullConf.js b/spec/noCFFullConf.js new file mode 100644 index 000000000..b71b3031e --- /dev/null +++ b/spec/noCFFullConf.js @@ -0,0 +1,12 @@ +// Run /exampleTypescripit/noControlFlow/smokeConf.ts, but with the environmental settings from +// /spec/environment.js. + +var path = require('path'); +var env = require('./environment.js'); +var exports = require('../exampleTypescripit/tmp/noControlFlow/smokeConf'); +exports.seleniumAddress = env.seleniumAddress; +exports.specs.map(function(spec) { + return path.resolve(require.resolve('../exampleTypescripit/tmp/noControlFlow'), spec); +}); +exports.capabilities = env.capabilities; +exports.baseUrl = env.baseUrl + '/ng1/'; diff --git a/spec/noCFPluginConf.js b/spec/noCFPluginConf.js new file mode 100644 index 000000000..b71b3031e --- /dev/null +++ b/spec/noCFPluginConf.js @@ -0,0 +1,12 @@ +// Run /exampleTypescripit/noControlFlow/smokeConf.ts, but with the environmental settings from +// /spec/environment.js. + +var path = require('path'); +var env = require('./environment.js'); +var exports = require('../exampleTypescripit/tmp/noControlFlow/smokeConf'); +exports.seleniumAddress = env.seleniumAddress; +exports.specs.map(function(spec) { + return path.resolve(require.resolve('../exampleTypescripit/tmp/noControlFlow'), spec); +}); +exports.capabilities = env.capabilities; +exports.baseUrl = env.baseUrl + '/ng1/'; diff --git a/spec/noCFSmokeConf.js b/spec/noCFSmokeConf.js new file mode 100644 index 000000000..b71b3031e --- /dev/null +++ b/spec/noCFSmokeConf.js @@ -0,0 +1,12 @@ +// Run /exampleTypescripit/noControlFlow/smokeConf.ts, but with the environmental settings from +// /spec/environment.js. + +var path = require('path'); +var env = require('./environment.js'); +var exports = require('../exampleTypescripit/tmp/noControlFlow/smokeConf'); +exports.seleniumAddress = env.seleniumAddress; +exports.specs.map(function(spec) { + return path.resolve(require.resolve('../exampleTypescripit/tmp/noControlFlow'), spec); +}); +exports.capabilities = env.capabilities; +exports.baseUrl = env.baseUrl + '/ng1/'; diff --git a/spec/tsconfig.json b/spec/tsconfig.json deleted file mode 100644 index eb8af8c8e..000000000 --- a/spec/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "target": "es6", - "module": "commonjs", - "moduleResolution": "node", - "sourceMap": true, - "declaration": true, - "removeComments": false, - "noImplicitAny": true, - "outDir": "built", - "types": [ - "jasmine", "jasminewd2", "node", - "chalk", "glob", "minimatch", - "minimist", "optimist", "q", - "selenium-webdriver" - ] - }, - "include": [ - "ts" - ] -}