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

Commit

Permalink
chore(types): add in types inherited from selenium-webdriver (#3288)
Browse files Browse the repository at this point in the history
- add element.ts to the gulp task for 'gulp types'
- clang clean up
- separate out selenium-webdriver types and extend them in protractor
- remove webdriver types for index.d.ts file
  • Loading branch information
cnishina authored Jun 21, 2016
1 parent bc9995b commit cd21f4d
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 72 deletions.
23 changes: 22 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ gulp.task('default',['prepublish']);

gulp.task('types', function(done) {
var folder = 'built';
var files = ['ptor', 'browser', 'locators', 'expectedConditions'];
var files = ['ptor', 'browser', 'element', 'locators', 'expectedConditions'];
var outputFile = path.resolve(folder, 'index.d.ts');
var contents = '';
files.forEach(file => {
Expand Down Expand Up @@ -104,8 +104,29 @@ var parseTypingsFile = function(folder, file) {
if (line.indexOf('export') !== -1) {
line = line.replace('export', '').trim();
}

// Remove webdriver types and plugins for now
line = removeTypes(line,'webdriver.ActionSequence');
line = removeTypes(line,'webdriver.promise.Promise');
line = removeTypes(line,'webdriver.util.Condition');
line = removeTypes(line,'webdriver.WebDriver');
line = removeTypes(line,'webdriver.Locator');
line = removeTypes(line,'webdriver.WebElement');
line = removeTypes(line,'Plugins');
contents += line + '\n';
}

}
return contents;
}

var removeTypes = function(line, webdriverType) {
var tempLine = line.trim();
if (tempLine.startsWith('/**') || tempLine.startsWith('*')) {
return line;
}
if (line.indexOf(webdriverType) !== -1) {
return line.replace(new RegExp(webdriverType,'g'), 'any');
}
return line;
}
25 changes: 21 additions & 4 deletions lib/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as url from 'url';
import * as util from 'util';

import {ElementArrayFinder, ElementFinder, build$, build$$} from './element';
import * as EC from './expectedConditions';
import {ExpectedConditions_} from './expectedConditions';
import {Locator, ProtractorBy} from './locators';
import {Logger} from './logger2';
import {Plugins} from './plugins';
Expand All @@ -30,6 +30,22 @@ for (let foo in webdriver) {
exports[foo] = webdriver[foo];
}

// Explicitly define webdriver.WebDriver.
export class Webdriver {
actions: () => webdriver.ActionSequence = webdriver.WebDriver.actions;
wait:
(condition: webdriver.promise.Promise|webdriver.util.Condition|Function,
opt_timeout?: number,
opt_message?:
string) => webdriver.promise.Promise = webdriver.WebDriver.wait;
sleep: (ms: number) => webdriver.promise.Promise = webdriver.WebDriver.sleep;
getCurrentUrl:
() => webdriver.promise.Promise = webdriver.WebDriver.getCurrentUrl;
getTitle: () => webdriver.promise.Promise = webdriver.WebDriver.getTitle;
takeScreenshot:
() => webdriver.promise.Promise = webdriver.WebDriver.takeScreenshot;
}

/**
* Mix a function from one object onto another. The function will still be
* called in the context of the original object.
Expand Down Expand Up @@ -85,7 +101,7 @@ function buildElementHelper(browser: Browser): ElementHelper {
* @param {boolean=} opt_untrackOutstandingTimeouts Whether Protractor should
* stop tracking outstanding $timeouts.
*/
export class Browser {
export class Browser extends Webdriver {
/**
* @type {ProtractorBy}
*/
Expand All @@ -94,7 +110,7 @@ export class Browser {
/**
* @type {ExpectedConditions}
*/
static ExpectedConditions = new EC.ExpectedConditions();
static ExpectedConditions = new ExpectedConditions_();

/**
* The wrapped webdriver instance. Use this to interact with pages that do
Expand Down Expand Up @@ -225,6 +241,7 @@ export class Browser {
constructor(
webdriverInstance: webdriver.WebDriver, opt_baseUrl?: string,
opt_rootElement?: string, opt_untrackOutstandingTimeouts?: boolean) {
super();
// These functions should delegate to the webdriver instance, but should
// wait for Angular to sync up before performing the action. This does not
// include functions which are overridden by protractor below.
Expand Down Expand Up @@ -281,7 +298,7 @@ export class Browser {
*
* Set by the runner.
*
* @return {q.Promise} A promise which resolves to the capabilities object.
* @return {webdriver.promise.Promise} A promise which resolves to the capabilities object.
*/
getProcessedConfig: () => webdriver.promise.Promise;

Expand Down
50 changes: 41 additions & 9 deletions lib/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,32 @@ let WEB_ELEMENT_FUNCTIONS = [
'serialize', 'takeScreenshot'
];

// Explicitly define webdriver.WebElement.
export class WebdriverWebElement {
getDriver: () => webdriver.WebDriver;
getId: () => webdriver.promise.Promise;
getRawId: () => webdriver.promise.Promise;
serialize: () => webdriver.promise.Promise;
findElement: (subLocator: Locator) => webdriver.promise.Promise;
click: () => webdriver.promise.Promise;
sendKeys: (...args: (string|webdriver.promise.Promise)[]) =>
webdriver.promise.Promise;
getTagName: () => webdriver.promise.Promise;
getCssValue: (cssStyleProperty: string) => webdriver.promise.Promise;
getAttribute: (attributeName: string) => webdriver.promise.Promise;
getText: () => webdriver.promise.Promise;
getSize: () => webdriver.promise.Promise;
getLocation: () => webdriver.promise.Promise;
isEnabled: () => webdriver.promise.Promise;
isSelected: () => webdriver.promise.Promise;
submit: () => webdriver.promise.Promise;
clear: () => webdriver.promise.Promise;
isDisplayed: () => webdriver.promise.Promise;
takeScreenshot: (opt_scroll?: boolean) => webdriver.promise.Promise;
getOuterHtml: () => webdriver.promise.Promise;
getInnerHtml: () => webdriver.promise.Promise;
}

/**
* ElementArrayFinder is used for operations on an array of elements (as opposed
* to a single element).
Expand Down Expand Up @@ -67,13 +93,14 @@ let WEB_ELEMENT_FUNCTIONS = [
* action result, or null if no action has been called.
* @return {ElementArrayFinder}
*/
export class ElementArrayFinder {
export class ElementArrayFinder extends WebdriverWebElement {
getWebElements: Function;

constructor(
private browser_: Browser, getWebElements?: Function,
private locator_?: any,
public actionResults_: webdriver.promise.Promise = null) {
super();
this.getWebElements = getWebElements || null;

// TODO(juliemr): might it be easier to combine this with our docs and just
Expand Down Expand Up @@ -379,7 +406,7 @@ export class ElementArrayFinder {
*
* @return {webdriver.Locator}
*/
locator(): any { return this.locator_; }
locator(): Locator { return this.locator_; }

/**
* Apply an action function to every element in the ElementArrayFinder,
Expand Down Expand Up @@ -661,12 +688,14 @@ export class ElementArrayFinder {
* that this is branched from.
* @return {ElementFinder}
*/
export class ElementFinder {
export class ElementFinder extends WebdriverWebElement {
parentElementArrayFinder: ElementArrayFinder;
elementArrayFinder_: ElementArrayFinder;
then: Function = null;
then: (fn: Function, errorFn: Function) => webdriver.promise.Promise = null;

constructor(private browser_: Browser, elementArrayFinder: ElementArrayFinder) {
constructor(
private browser_: Browser, elementArrayFinder: ElementArrayFinder) {
super();
if (!elementArrayFinder) {
throw new Error('BUG: elementArrayFinder cannot be empty');
}
Expand All @@ -680,6 +709,7 @@ export class ElementFinder {
*
* @param {function(webdriver.promise.Promise)} fn Function which takes
* the value of the underlying actionResult.
* @param {function(Error)} errorFn
*
* @return {webdriver.promise.Promise} Promise which contains the results of
* evaluating fn.
Expand Down Expand Up @@ -731,10 +761,12 @@ export class ElementFinder {
});
}

static fromWebElement_(ptor: any, webElem: any, locator: any): ElementFinder {
static fromWebElement_(
browser: Browser, webElem: webdriver.WebElement,
locator: Locator): ElementFinder {
let getWebElements =
() => { return webdriver.promise.fulfilled([webElem]); };
return new ElementArrayFinder(ptor, getWebElements, locator)
return new ElementArrayFinder(browser, getWebElements, locator)
.toElementFinder_();
}

Expand Down Expand Up @@ -802,7 +834,7 @@ export class ElementFinder {
* @param {webdriver.Locator} subLocator
* @return {ElementArrayFinder}
*/
all(subLocator: any): ElementArrayFinder {
all(subLocator: Locator): ElementArrayFinder {
return this.elementArrayFinder_.all(subLocator);
}

Expand Down Expand Up @@ -833,7 +865,7 @@ export class ElementFinder {
* @param {webdriver.Locator} subLocator
* @return {ElementFinder}
*/
element(subLocator: any): ElementFinder {
element(subLocator: Locator): ElementFinder {
return this.all(subLocator).toElementFinder_();
}

Expand Down
11 changes: 7 additions & 4 deletions lib/expectedConditions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {protractor} from './ptor';
import {ElementFinder} from './element';
import {protractor} from './ptor';

let webdriver = require('selenium-webdriver');

/* globals browser */
Expand Down Expand Up @@ -44,7 +45,7 @@ let webdriver = require('selenium-webdriver');
*
* @constructor
*/
export class ExpectedConditions {
export class ExpectedConditions_ {
/**
* Negates the result of a promise.
*
Expand Down Expand Up @@ -189,7 +190,8 @@ export class ExpectedConditions {
* @return {!function} An expected condition that returns a promise
* representing whether the text is present in the element.
*/
textToBePresentInElement(elementFinder: ElementFinder, text: string): Function {
textToBePresentInElement(elementFinder: ElementFinder, text: string):
Function {
var hasText = () => {
return elementFinder.getText().then((actualText: string): boolean => {
return actualText.indexOf(text) > -1;
Expand All @@ -213,7 +215,8 @@ export class ExpectedConditions {
* @return {!function} An expected condition that returns a promise
* representing whether the text is present in the element's value.
*/
textToBePresentInElementValue(elementFinder: ElementFinder, text: string): Function {
textToBePresentInElementValue(elementFinder: ElementFinder, text: string):
Function {
var hasText = () => {
return elementFinder.getAttribute('value').then(
(actualText: string): boolean => {
Expand Down
14 changes: 10 additions & 4 deletions lib/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ declare interface String { startsWith: Function; }

declare namespace webdriver {
var error: any;

class ActionSequence {}

class WebDriver {
findElements: Function;
getSession: Function;
Expand All @@ -61,12 +64,15 @@ declare namespace webdriver {
}

namespace promise {
interface Promise {
controlFlow: Function,
then: Function
}
interface Promise {
controlFlow: Function;
then: Function;
}
}

namespace util {
interface Condition {}
}
class Capabilities {
get: Function;
}
Expand Down
31 changes: 14 additions & 17 deletions lib/locators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@ import * as util from 'util';
let webdriver: any = require('selenium-webdriver');
let clientSideScripts: any = require('./clientsidescripts');

/**
* webdriver's By is an enum of locator functions, so we must set it to
* a prototype before inheriting from it.
*/
export class WebdriverBy {}
WebdriverBy.prototype = webdriver.By;
// Explicitly define webdriver.By.
export class WebdriverBy {
className: (className: string) => Locator = webdriver.By.className;
css: (css: string) => Locator = webdriver.By.css;
id: (id: string) => Locator = webdriver.By.id;
linkText: (linkText: string) => Locator = webdriver.By.linkText;
js: (js: string) => Locator = webdriver.By.js;
name: (name: string) => Locator = webdriver.By.name;
partialLinkText:
(partialText: string) => Locator = webdriver.By.partialLinkText;
tagName: (tagName: string) => Locator = webdriver.By.tagName;
xpath: (xpath: string) => Locator = webdriver.By.xpath;
}

// Interface for webdriver.Locator.
export interface Locator {
findElementsOverride?:
(driver: webdriver.WebDriver, using: webdriver.WebElement,
Expand All @@ -27,17 +35,6 @@ export interface Locator {
export class ProtractorBy extends WebdriverBy {
[key: string]: any;

className: (className: string) => Locator = webdriver.By.className;
css: (css: string) => Locator = webdriver.By.css;
id: (id: string) => Locator = webdriver.By.id;
linkText: (linkText: string) => Locator = webdriver.By.linkText;
js: (js: string) => Locator = webdriver.By.js;
name: (name: string) => Locator = webdriver.By.name;
partialLinkText:
(partialText: string) => Locator = webdriver.By.partialLinkText;
tagName: (tagName: string) => Locator = webdriver.By.tagName;
xpath: (xpath: string) => Locator = webdriver.By.xpath;

/**
* Add a locator to this instance of ProtractorBy. This locator can then be
* used with element(by.locatorName(args)).
Expand Down
Loading

0 comments on commit cd21f4d

Please sign in to comment.