Skip to content

Commit

Permalink
chore(types): clean up TypeScript support
Browse files Browse the repository at this point in the history
- fix exampleTypescript to have noGlobals
- change the exampleTypescript tsconfig.json to include @types
- alias promise as wdpromise everywhere
- refactor gulpfile task 'types' to use multiple files from tsc
- add browser method types applied from webdriver

this closes angular#3430, closes angular#3477, and closes angular#3500
  • Loading branch information
cnishina committed Sep 9, 2016
1 parent d18bba3 commit 3489cd5
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 161 deletions.
1 change: 1 addition & 0 deletions exampleTypescript/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.js
node_modules
tmp/
6 changes: 5 additions & 1 deletion exampleTypescript/conf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,9 @@ export let config: Config = {
browserName: 'chrome'
},
specs: [ 'spec.js' ],
seleniumAddress: 'http://localhost:4444/wd/hub'
seleniumAddress: 'http://localhost:4444/wd/hub',

// You could set no globals to true to avoid jQuery '$' and protractor '$'
// collisions on the global namespace.
noGlobals: true
};
80 changes: 9 additions & 71 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,90 +97,28 @@ gulp.task('tsc:globals', function(done) {

gulp.task('prepublish', function(done) {
runSequence('checkVersion', ['jshint', 'format'], 'tsc', 'tsc:globals', 'types',
'ambient', 'built:copy', done);
'built:copy', done);
});

gulp.task('pretest', function(done) {
runSequence('checkVersion',
['webdriver:update', 'jshint', 'format'], 'tsc', 'tsc:globals',
'types', 'ambient', 'built:copy', done);
'types', 'built:copy', done);
});

gulp.task('default',['prepublish']);

gulp.task('types', function(done) {
var folder = 'built';
var files = ['browser', 'element', 'locators', 'expectedConditions',
'config', 'plugins', 'ptor'];
var outputFile = path.resolve(folder, 'index.d.ts');
var outputFile = path.resolve('built', 'index.d.ts');
var contents = '';
contents += '/// <reference path="../typings/index.d.ts" />\n';
contents += '/// <reference path="./globals.d.ts" />\n';
contents += 'import {ActionSequence, By, WebDriver, WebElement, WebElementPromise, promise, promise as wdpromise, until} from \'selenium-webdriver\';\n';
files.forEach(function(file) {
contents += parseTypingsFile(folder, file);
});

// remove files with d.ts
glob.sync(folder + '/**/*.d.ts').forEach(function(file) {
fs.unlinkSync(path.resolve(file));
});

// write contents to 'built/index.d.ts'
contents += 'export { ElementHelper, ProtractorBrowser } from \'./browser\';\n';
contents += 'export { ElementArrayFinder, ElementFinder } from \'./element\';\n';
contents += 'export { ProtractorExpectedConditions } from \'./expectedConditions\';\n';
contents += 'export { ProtractorBy } from \'./locators\';\n';
contents += 'export { Config } from \'./config\';\n';
contents += 'export { Ptor } from \'./ptor\';\n';
fs.writeFileSync(outputFile, contents);
done();
});

var parseTypingsFile = function(folder, file) {
var fileContents = fs.readFileSync(path.resolve(folder, file + '.d.ts')).toString();
// Remove new lines inside types
fileContents = fileContents.replace(
/webdriver.promise.Promise<\{[a-zA-Z:,; \n]+\}>/g, function(type) {
return type.replace(/\n/g, '');
}
);
var lines = fileContents.split('\n');
var contents = '';
for (var linePos in lines) {
var line = lines[linePos];
if (!line.startsWith('import')) {
if (line.indexOf('declare') !== -1) {
line = line.replace('declare', '').trim();
}

// Remove webdriver types, q, http proxy agent
line = removeTypes(line,'webdriver.ActionSequence');
line = removeTypes(line,'webdriver.promise.Promise<[a-zA-Z{},:; ]+>');
line = removeTypes(line,'webdriver.util.Condition');
line = removeTypes(line,'webdriver.WebDriver');
line = removeTypes(line,'webdriver.Locator');
line = removeTypes(line,'webdriver.WebElement');
line = removeTypes(line,'HttpProxyAgent');
line = removeTypes(line,'Q.Promise<[a-zA-Z{},:; ]+>');
contents += line + '\n';
}
}
return contents;
}

var removeTypes = function(line, webdriverType) {
var tempLine = line.trim();
if (tempLine.startsWith('/**') || tempLine.startsWith('*')) {
return line;
}
return line.replace(new RegExp(webdriverType,'g'), 'any');
}

gulp.task('ambient', function(done) {
var fileContents = fs.readFileSync(path.resolve('built/index.d.ts')).toString();
var contents = '';
contents += 'declare namespace protractor {\n';
contents += fileContents + '\n';
contents += '}\n';
contents += 'declare module "protractor" {\n';

contents += ' export = protractor; \n';
contents += '}\n';
fs.writeFileSync(path.resolve('built/ambient.d.ts'), contents);
done();
});
49 changes: 34 additions & 15 deletions lib/browser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Util from NodeJs
import * as net from 'net';
import {ActionSequence, promise as wdpromise, until, WebDriver, WebElement} from 'selenium-webdriver';
import {ActionSequence, Capabilities, Command as WdCommand, FileDetector, Options, promise as wdpromise, Session, TargetLocator, TouchSequence, until, WebDriver, WebElement} from 'selenium-webdriver';

import * as url from 'url';
import * as util from 'util';

Expand Down Expand Up @@ -32,20 +33,39 @@ for (let foo in webdriver) {
exports[foo] = webdriver[foo];
}

// Explicitly define webdriver.WebDriver.
// Explicitly define webdriver.WebDriver
export class Webdriver {
actions: () => ActionSequence = webdriver.WebDriver.actions;
actions: () => ActionSequence;
call:
(fn: (...var_args: any[]) => any, opt_scope?: any,
...var_args: any[]) => wdpromise.Promise<any>;
close: () => void;
controlFlow: () => wdpromise.ControlFlow;
executeScript:
(script: string|Function, ...var_args: any[]) => wdpromise.Promise<any>;
executeAsyncScript:
(script: string|Function, ...var_args: any[]) => wdpromise.Promise<any>;
getCapabilities: () => Capabilities;
getCurrentUrl: () => wdpromise.Promise<string>;
getPageSource: () => wdpromise.Promise<string>;
getSession: () => wdpromise.Promise<Session>;
getTitle: () => wdpromise.Promise<string>;
getWindowHandle: () => wdpromise.Promise<string>;
getAllWindowHandles: () => wdpromise.Promise<string[]>;
manage: () => Options;
quit: () => void;
schedule:
(command: WdCommand,
description: string) => wdpromise.Promise<any>;
setFileDetector: (detector: FileDetector) => void;
sleep: (ms: number) => wdpromise.Promise<void>;
switchTo: () => TargetLocator;
touchActions: () => TouchSequence;
takeScreenshot: () => wdpromise.Promise<any>;
touchActions: () => TouchSequence;
wait:
(condition: wdpromise.Promise<any>|until.Condition<any>|Function,
opt_timeout?: number,
opt_message?:
string) => wdpromise.Promise<any> = webdriver.WebDriver.wait;
sleep: (ms: number) => wdpromise.Promise<any> = webdriver.WebDriver.sleep;
getCurrentUrl:
() => wdpromise.Promise<any> = webdriver.WebDriver.getCurrentUrl;
getTitle: () => wdpromise.Promise<any> = webdriver.WebDriver.getTitle;
takeScreenshot:
() => wdpromise.Promise<any> = webdriver.WebDriver.takeScreenshot;
opt_timeout?: number, opt_message?: string) => wdpromise.Promise<any>;
}

/**
Expand Down Expand Up @@ -268,7 +288,6 @@ export class ProtractorBrowser extends Webdriver {
// include functions which are overridden by protractor below.
let methodsToSync = ['getCurrentUrl', 'getPageSource', 'getTitle'];


// Mix all other driver functionality into Protractor.
Object.getOwnPropertyNames(webdriver.WebDriver.prototype)
.forEach((method: string) => {
Expand Down Expand Up @@ -298,7 +317,7 @@ export class ProtractorBrowser extends Webdriver {
this.resetUrl = DEFAULT_RESET_URL;
this.ng12Hybrid = false;

this.driver.getCapabilities().then((caps: webdriver.Capabilities) => {
this.driver.getCapabilities().then((caps: Capabilities) => {
// Internet Explorer does not accept data URLs, which are the default
// reset URL for Protractor.
// Safari accepts data urls, but SafariDriver fails after one is used.
Expand Down Expand Up @@ -572,7 +591,7 @@ export class ProtractorBrowser extends Webdriver {
* @returns {!webdriver.promise.Promise} A promise that will resolve to whether
* the element is present on the page.
*/
isElementPresent(locatorOrElement: webdriver.Locator|
isElementPresent(locatorOrElement: ProtractorBy|
webdriver.WebElement): webdriver.promise.Promise<any> {
let element = ((locatorOrElement as any).isPresent) ?
locatorOrElement :
Expand Down
Loading

0 comments on commit 3489cd5

Please sign in to comment.