diff --git a/.gitignore b/.gitignore index 68624e5e4..1dee68c33 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ xmloutput* npm-debug.log *.swp +globals.js diff --git a/exampleTypescript/tsconfig.json b/exampleTypescript/tsconfig.json index 7a8b29376..d695630f8 100644 --- a/exampleTypescript/tsconfig.json +++ b/exampleTypescript/tsconfig.json @@ -9,6 +9,7 @@ }, "exclude": [ "node_modules", - "typings/globals" + "typings/globals", + "asyncAwait" ] } diff --git a/globals.ts b/globals.ts index c50487766..4955c6847 100644 --- a/globals.ts +++ b/globals.ts @@ -7,15 +7,6 @@ import { ProtractorExpectedConditions } from 'protractor'; -export var browser: Browser = global['protractor.browser']; -export var element: ElementHelper = global['protractor.element']; -export var by: ProtractorBy = global['protractor.by']; -export var By: ProtractorBy = global['protractor.By']; -export var $: (search: string) => ElementFinder = global['protractor.$']; -export var $$: (search: string) => ElementArrayFinder = global['protractor.$$']; -export var ExpectedConditions: ProtractorExpectedConditions = - global['protractor.ExpectedConditions']; - export interface Protractor { browser: Browser; element: ElementHelper; @@ -26,3 +17,11 @@ export interface Protractor { ExpectedConditions: ProtractorExpectedConditions; } export var protractor: Protractor = global['protractor']; +export var browser: Browser = global['protractor']['browser']; +export var element: ElementHelper = global['protractor']['element']; +export var by: ProtractorBy = global['protractor']['by']; +export var By: ProtractorBy = global['protractor']['By']; +export var $: (search: string) => ElementFinder = global['protractor']['$']; +export var $$: (search: string) => ElementArrayFinder = global['protractor']['$$']; +export var ExpectedConditions: ProtractorExpectedConditions = + global['protractor']['ExpectedConditions']; diff --git a/gulpfile.js b/gulpfile.js index ed42768ca..70773cc41 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -9,9 +9,13 @@ var fs = require('fs'); var path = require('path'); var glob = require('glob'); -var runSpawn = function(done, task, opt_arg) { +var runSpawn = function(done, task, opt_arg, opt_io) { opt_arg = typeof opt_arg !== 'undefined' ? opt_arg : []; - var child = spawn(task, opt_arg, {stdio: 'inherit'}); + var stdio = 'inherit'; + if (opt_io === 'ignore') { + stdio = 'ignore'; + } + var child = spawn(task, opt_arg, {stdio: stdio}); var running = false; child.on('close', function() { if (!running) { @@ -64,14 +68,20 @@ gulp.task('tsc', function(done) { runSpawn(done, 'node', ['node_modules/typescript/bin/tsc']); }); +gulp.task('tsc:globals', function(done) { + runSpawn(done, 'node', ['node_modules/typescript/bin/tsc', 'globals.ts'], + 'ignore'); +}); + gulp.task('prepublish', function(done) { - runSequence(['typings', 'jshint', 'format'], 'tsc', 'types', 'ambient', 'built:copy', done); + runSequence(['typings', 'jshint', 'format'], 'tsc', 'tsc:globals', 'types', + 'ambient', 'built:copy', done); }); gulp.task('pretest', function(done) { runSequence( - ['webdriver:update', 'typings', 'jshint', 'format'], 'tsc', 'types', 'ambient', - 'built:copy', done); + ['webdriver:update', 'typings', 'jshint', 'format'], 'tsc', 'types', + 'ambient', 'tsc:globals', 'built:copy', done); }); gulp.task('default',['prepublish']); diff --git a/lib/browser.ts b/lib/browser.ts index 4e70dd2d7..8b897c7f1 100644 --- a/lib/browser.ts +++ b/lib/browser.ts @@ -8,11 +8,12 @@ import {ProtractorExpectedConditions} from './expectedConditions'; import {Locator, ProtractorBy} from './locators'; import {Logger} from './logger'; import {Plugins} from './plugins'; -import {protractor} from './ptor'; import * as helper from './util'; let clientSideScripts = require('./clientsidescripts'); let webdriver = require('selenium-webdriver'); +let Command = require('selenium-webdriver/lib/command').Command; +let CommandName = require('selenium-webdriver/lib/command').Name; // jshint browser: true /* global angular */ @@ -361,7 +362,7 @@ export class Browser extends Webdriver { } return this.driver.schedule( - new protractor.Command(protractor.CommandName.EXECUTE_SCRIPT) + new Command(CommandName.EXECUTE_SCRIPT) .setParameter('script', script) .setParameter('args', scriptArgs), description); @@ -387,7 +388,7 @@ export class Browser extends Webdriver { script = 'return (' + script + ').apply(null, arguments);'; } return this.driver.schedule( - new protractor.Command(protractor.CommandName.EXECUTE_ASYNC_SCRIPT) + new Command(CommandName.EXECUTE_ASYNC_SCRIPT) .setParameter('script', script) .setParameter('args', scriptArgs), description); @@ -1003,7 +1004,7 @@ export class Browser extends Webdriver { let context: Object = {require: require}; global.list = (locator: Locator) => { /* globals browser */ - return protractor.browser.findElements(locator).then( + return global.browser.findElements(locator).then( (arr: webdriver.WebElement[]) => { let found: string[] = []; for (let i = 0; i < arr.length; ++i) { diff --git a/lib/expectedConditions.ts b/lib/expectedConditions.ts index 3814321ed..b315909b8 100644 --- a/lib/expectedConditions.ts +++ b/lib/expectedConditions.ts @@ -1,5 +1,4 @@ import {ElementFinder} from './element'; -import {protractor} from './ptor'; let webdriver = require('selenium-webdriver'); @@ -150,7 +149,7 @@ export class ProtractorExpectedConditions { */ alertIsPresent(): Function { return () => { - return protractor.browser.driver.switchTo().alert().then( + return global.browser.driver.switchTo().alert().then( (): boolean => { return true; }, (err: any) => { if (err.code == webdriver.error.ErrorCode.NO_SUCH_ALERT) { @@ -253,7 +252,7 @@ export class ProtractorExpectedConditions { */ titleContains(title: string): Function { return () => { - return protractor.browser.driver.getTitle().then( + return global.browser.driver.getTitle().then( (actualTitle: string): boolean => { return actualTitle.indexOf(title) > -1; }); @@ -276,7 +275,7 @@ export class ProtractorExpectedConditions { */ titleIs(title: string): Function { return () => { - return protractor.browser.driver.getTitle().then( + return global.browser.driver.getTitle().then( (actualTitle: string): boolean => { return actualTitle === title; }); }; } @@ -298,7 +297,7 @@ export class ProtractorExpectedConditions { */ urlContains(url: string): Function { return () => { - return protractor.browser.driver.getCurrentUrl().then( + return global.browser.driver.getCurrentUrl().then( (actualUrl: string): boolean => { return actualUrl.indexOf(url) > -1; }); @@ -321,7 +320,7 @@ export class ProtractorExpectedConditions { */ urlIs(url: string): Function { return () => { - return protractor.browser.driver.getCurrentUrl().then( + return global.browser.driver.getCurrentUrl().then( (actualUrl: string): boolean => { return actualUrl === url; }); }; } diff --git a/lib/main.ts b/lib/main.ts new file mode 100644 index 000000000..281c0f2ad --- /dev/null +++ b/lib/main.ts @@ -0,0 +1,6 @@ +/** + * Requiring protractor as a node module. Export the contents of the protractor + * namespace. + */ + +export = require('./ptor').protractor diff --git a/lib/ptor.ts b/lib/ptor.ts index 409fb910d..5cc6fffcb 100644 --- a/lib/ptor.ts +++ b/lib/ptor.ts @@ -6,25 +6,27 @@ import {ProtractorBy} from './locators'; let webdriver = require('selenium-webdriver'); export namespace protractor { + // Variables tied to the global namespace. export let browser: Browser; export let $ = function(search: string): ElementFinder { return null;}; export let $$ = function(search: string): ElementArrayFinder { return null;}; export let element: ElementHelper; export let By: ProtractorBy; export let by: ProtractorBy; - export let wrapDriver: Function; + export let wrapDriver: + (webdriver: webdriver.WebDriver, baseUrl?: string, rootElement?: string, + untrackOutstandingTimeouts?: boolean) => Browser; export let ExpectedConditions: ProtractorExpectedConditions; - // Export the protractor classes + // Export protractor classes. export let Browser = require('./browser').Browser; export let ElementFinder = require('./element').ElementFinder; export let ElementArrayFinder = require('./element').ElementArrayFinder; - export let ElementHelper = require('./browser').ElementHelper; export let ProtractorBy = require('./locators').ProtractorBy; export let ProtractorExpectedConditions = require('./expectedConditions').ProtractorExpectedConditions; - // Define selenium webdriver imports. + // Export selenium webdriver. export let promise = webdriver.promise; export let WebElement = webdriver.WebElement; export let ActionSequence = webdriver.ActionSequence; diff --git a/package.json b/package.json index 4abca61a8..8200ca244 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "protractor": "bin/protractor", "webdriver-manager": "bin/webdriver-manager" }, - "main": "built/browser.js", + "main": "built/main.js", "typings": "built/index.d.ts", "scripts": { "prepublish": "gulp prepublish", diff --git a/spec/dependencyTest/protractor_spec.js b/spec/dependencyTest/protractor_spec.js new file mode 100644 index 000000000..18d7335d2 --- /dev/null +++ b/spec/dependencyTest/protractor_spec.js @@ -0,0 +1,64 @@ +// require('protractor') equivalent is requiring ptor +let protractor = require('../../built/main'); + +// the webdriver stuff we are exposing externally + + +describe('require(\'protractor\')', () => { + + describe('exported protractor classes', () => { + it('should be defined', () => { + var protractorClasses = ['Browser', 'ElementFinder', 'ElementArrayFinder', + 'ProtractorBy', 'ProtractorExpectedConditions']; + for (var pos in protractorClasses) { + var property = protractorClasses[pos]; + expect(typeof protractor[property]).toEqual('function'); + } + }); + + describe('browser class', () => { + it('should have static method defined', () => { + var staticMethod = 'wrapDriver'; + expect(typeof protractor.Browser['wrapDriver']).toEqual('function'); + }); + + it('should have static variables defined', () => { + var staticVariables = ['By', 'ExpectedConditions']; + for (var pos in staticVariables) { + var property = staticVariables[pos]; + expect(typeof protractor.Browser[property]).toEqual('object'); + } + }); + }); + + }); + + describe('exported webdriver namespace', ()=> { + it('should have exported classes', () => { + var webdriverClasses = ['WebElement', 'ActionSequence', 'Command']; + for (var pos in webdriverClasses) { + var property = webdriverClasses[pos]; + expect(typeof protractor[property]).toEqual('function'); + } + }); + + it('should have variables defined', () => { + var webdriverObjects = ['Key', 'CommandName']; + for (var pos in webdriverObjects) { + var property = webdriverObjects[pos]; + expect(typeof protractor[property]).toEqual('object'); + } + }); + + describe('promise namespace', () => { + it('should have functions defined (spot check)', () => { + var promiseFunctions = ['Promise', 'defer', 'delayed', 'createFlow', + 'controlFlow', 'all', 'fulfilled', 'filter', 'when' ] + for (var pos in promiseFunctions) { + var property = promiseFunctions[pos]; + expect(typeof protractor.promise[property]).toEqual('function'); + } + }); + }); + }); +});