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

Commit cd21f4d

Browse files
authored
chore(types): add in types inherited from selenium-webdriver (#3288)
- 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
1 parent bc9995b commit cd21f4d

File tree

7 files changed

+150
-72
lines changed

7 files changed

+150
-72
lines changed

gulpfile.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ gulp.task('default',['prepublish']);
7272

7373
gulp.task('types', function(done) {
7474
var folder = 'built';
75-
var files = ['ptor', 'browser', 'locators', 'expectedConditions'];
75+
var files = ['ptor', 'browser', 'element', 'locators', 'expectedConditions'];
7676
var outputFile = path.resolve(folder, 'index.d.ts');
7777
var contents = '';
7878
files.forEach(file => {
@@ -104,8 +104,29 @@ var parseTypingsFile = function(folder, file) {
104104
if (line.indexOf('export') !== -1) {
105105
line = line.replace('export', '').trim();
106106
}
107+
108+
// Remove webdriver types and plugins for now
109+
line = removeTypes(line,'webdriver.ActionSequence');
110+
line = removeTypes(line,'webdriver.promise.Promise');
111+
line = removeTypes(line,'webdriver.util.Condition');
112+
line = removeTypes(line,'webdriver.WebDriver');
113+
line = removeTypes(line,'webdriver.Locator');
114+
line = removeTypes(line,'webdriver.WebElement');
115+
line = removeTypes(line,'Plugins');
107116
contents += line + '\n';
108117
}
118+
109119
}
110120
return contents;
111121
}
122+
123+
var removeTypes = function(line, webdriverType) {
124+
var tempLine = line.trim();
125+
if (tempLine.startsWith('/**') || tempLine.startsWith('*')) {
126+
return line;
127+
}
128+
if (line.indexOf(webdriverType) !== -1) {
129+
return line.replace(new RegExp(webdriverType,'g'), 'any');
130+
}
131+
return line;
132+
}

lib/browser.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as url from 'url';
44
import * as util from 'util';
55

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

33+
// Explicitly define webdriver.WebDriver.
34+
export class Webdriver {
35+
actions: () => webdriver.ActionSequence = webdriver.WebDriver.actions;
36+
wait:
37+
(condition: webdriver.promise.Promise|webdriver.util.Condition|Function,
38+
opt_timeout?: number,
39+
opt_message?:
40+
string) => webdriver.promise.Promise = webdriver.WebDriver.wait;
41+
sleep: (ms: number) => webdriver.promise.Promise = webdriver.WebDriver.sleep;
42+
getCurrentUrl:
43+
() => webdriver.promise.Promise = webdriver.WebDriver.getCurrentUrl;
44+
getTitle: () => webdriver.promise.Promise = webdriver.WebDriver.getTitle;
45+
takeScreenshot:
46+
() => webdriver.promise.Promise = webdriver.WebDriver.takeScreenshot;
47+
}
48+
3349
/**
3450
* Mix a function from one object onto another. The function will still be
3551
* called in the context of the original object.
@@ -85,7 +101,7 @@ function buildElementHelper(browser: Browser): ElementHelper {
85101
* @param {boolean=} opt_untrackOutstandingTimeouts Whether Protractor should
86102
* stop tracking outstanding $timeouts.
87103
*/
88-
export class Browser {
104+
export class Browser extends Webdriver {
89105
/**
90106
* @type {ProtractorBy}
91107
*/
@@ -94,7 +110,7 @@ export class Browser {
94110
/**
95111
* @type {ExpectedConditions}
96112
*/
97-
static ExpectedConditions = new EC.ExpectedConditions();
113+
static ExpectedConditions = new ExpectedConditions_();
98114

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

lib/element.ts

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,32 @@ let WEB_ELEMENT_FUNCTIONS = [
1414
'serialize', 'takeScreenshot'
1515
];
1616

17+
// Explicitly define webdriver.WebElement.
18+
export class WebdriverWebElement {
19+
getDriver: () => webdriver.WebDriver;
20+
getId: () => webdriver.promise.Promise;
21+
getRawId: () => webdriver.promise.Promise;
22+
serialize: () => webdriver.promise.Promise;
23+
findElement: (subLocator: Locator) => webdriver.promise.Promise;
24+
click: () => webdriver.promise.Promise;
25+
sendKeys: (...args: (string|webdriver.promise.Promise)[]) =>
26+
webdriver.promise.Promise;
27+
getTagName: () => webdriver.promise.Promise;
28+
getCssValue: (cssStyleProperty: string) => webdriver.promise.Promise;
29+
getAttribute: (attributeName: string) => webdriver.promise.Promise;
30+
getText: () => webdriver.promise.Promise;
31+
getSize: () => webdriver.promise.Promise;
32+
getLocation: () => webdriver.promise.Promise;
33+
isEnabled: () => webdriver.promise.Promise;
34+
isSelected: () => webdriver.promise.Promise;
35+
submit: () => webdriver.promise.Promise;
36+
clear: () => webdriver.promise.Promise;
37+
isDisplayed: () => webdriver.promise.Promise;
38+
takeScreenshot: (opt_scroll?: boolean) => webdriver.promise.Promise;
39+
getOuterHtml: () => webdriver.promise.Promise;
40+
getInnerHtml: () => webdriver.promise.Promise;
41+
}
42+
1743
/**
1844
* ElementArrayFinder is used for operations on an array of elements (as opposed
1945
* to a single element).
@@ -67,13 +93,14 @@ let WEB_ELEMENT_FUNCTIONS = [
6793
* action result, or null if no action has been called.
6894
* @return {ElementArrayFinder}
6995
*/
70-
export class ElementArrayFinder {
96+
export class ElementArrayFinder extends WebdriverWebElement {
7197
getWebElements: Function;
7298

7399
constructor(
74100
private browser_: Browser, getWebElements?: Function,
75101
private locator_?: any,
76102
public actionResults_: webdriver.promise.Promise = null) {
103+
super();
77104
this.getWebElements = getWebElements || null;
78105

79106
// TODO(juliemr): might it be easier to combine this with our docs and just
@@ -379,7 +406,7 @@ export class ElementArrayFinder {
379406
*
380407
* @return {webdriver.Locator}
381408
*/
382-
locator(): any { return this.locator_; }
409+
locator(): Locator { return this.locator_; }
383410

384411
/**
385412
* Apply an action function to every element in the ElementArrayFinder,
@@ -661,12 +688,14 @@ export class ElementArrayFinder {
661688
* that this is branched from.
662689
* @return {ElementFinder}
663690
*/
664-
export class ElementFinder {
691+
export class ElementFinder extends WebdriverWebElement {
665692
parentElementArrayFinder: ElementArrayFinder;
666693
elementArrayFinder_: ElementArrayFinder;
667-
then: Function = null;
694+
then: (fn: Function, errorFn: Function) => webdriver.promise.Promise = null;
668695

669-
constructor(private browser_: Browser, elementArrayFinder: ElementArrayFinder) {
696+
constructor(
697+
private browser_: Browser, elementArrayFinder: ElementArrayFinder) {
698+
super();
670699
if (!elementArrayFinder) {
671700
throw new Error('BUG: elementArrayFinder cannot be empty');
672701
}
@@ -680,6 +709,7 @@ export class ElementFinder {
680709
*
681710
* @param {function(webdriver.promise.Promise)} fn Function which takes
682711
* the value of the underlying actionResult.
712+
* @param {function(Error)} errorFn
683713
*
684714
* @return {webdriver.promise.Promise} Promise which contains the results of
685715
* evaluating fn.
@@ -731,10 +761,12 @@ export class ElementFinder {
731761
});
732762
}
733763

734-
static fromWebElement_(ptor: any, webElem: any, locator: any): ElementFinder {
764+
static fromWebElement_(
765+
browser: Browser, webElem: webdriver.WebElement,
766+
locator: Locator): ElementFinder {
735767
let getWebElements =
736768
() => { return webdriver.promise.fulfilled([webElem]); };
737-
return new ElementArrayFinder(ptor, getWebElements, locator)
769+
return new ElementArrayFinder(browser, getWebElements, locator)
738770
.toElementFinder_();
739771
}
740772

@@ -802,7 +834,7 @@ export class ElementFinder {
802834
* @param {webdriver.Locator} subLocator
803835
* @return {ElementArrayFinder}
804836
*/
805-
all(subLocator: any): ElementArrayFinder {
837+
all(subLocator: Locator): ElementArrayFinder {
806838
return this.elementArrayFinder_.all(subLocator);
807839
}
808840

@@ -833,7 +865,7 @@ export class ElementFinder {
833865
* @param {webdriver.Locator} subLocator
834866
* @return {ElementFinder}
835867
*/
836-
element(subLocator: any): ElementFinder {
868+
element(subLocator: Locator): ElementFinder {
837869
return this.all(subLocator).toElementFinder_();
838870
}
839871

lib/expectedConditions.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import {protractor} from './ptor';
21
import {ElementFinder} from './element';
2+
import {protractor} from './ptor';
3+
34
let webdriver = require('selenium-webdriver');
45

56
/* globals browser */
@@ -44,7 +45,7 @@ let webdriver = require('selenium-webdriver');
4445
*
4546
* @constructor
4647
*/
47-
export class ExpectedConditions {
48+
export class ExpectedConditions_ {
4849
/**
4950
* Negates the result of a promise.
5051
*
@@ -189,7 +190,8 @@ export class ExpectedConditions {
189190
* @return {!function} An expected condition that returns a promise
190191
* representing whether the text is present in the element.
191192
*/
192-
textToBePresentInElement(elementFinder: ElementFinder, text: string): Function {
193+
textToBePresentInElement(elementFinder: ElementFinder, text: string):
194+
Function {
193195
var hasText = () => {
194196
return elementFinder.getText().then((actualText: string): boolean => {
195197
return actualText.indexOf(text) > -1;
@@ -213,7 +215,8 @@ export class ExpectedConditions {
213215
* @return {!function} An expected condition that returns a promise
214216
* representing whether the text is present in the element's value.
215217
*/
216-
textToBePresentInElementValue(elementFinder: ElementFinder, text: string): Function {
218+
textToBePresentInElementValue(elementFinder: ElementFinder, text: string):
219+
Function {
217220
var hasText = () => {
218221
return elementFinder.getAttribute('value').then(
219222
(actualText: string): boolean => {

lib/globals.d.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ declare interface String { startsWith: Function; }
3535

3636
declare namespace webdriver {
3737
var error: any;
38+
39+
class ActionSequence {}
40+
3841
class WebDriver {
3942
findElements: Function;
4043
getSession: Function;
@@ -61,12 +64,15 @@ declare namespace webdriver {
6164
}
6265

6366
namespace promise {
64-
interface Promise {
65-
controlFlow: Function,
66-
then: Function
67-
}
67+
interface Promise {
68+
controlFlow: Function;
69+
then: Function;
70+
}
6871
}
6972

73+
namespace util {
74+
interface Condition {}
75+
}
7076
class Capabilities {
7177
get: Function;
7278
}

lib/locators.ts

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@ import * as util from 'util';
22
let webdriver: any = require('selenium-webdriver');
33
let clientSideScripts: any = require('./clientsidescripts');
44

5-
/**
6-
* webdriver's By is an enum of locator functions, so we must set it to
7-
* a prototype before inheriting from it.
8-
*/
9-
export class WebdriverBy {}
10-
WebdriverBy.prototype = webdriver.By;
5+
// Explicitly define webdriver.By.
6+
export class WebdriverBy {
7+
className: (className: string) => Locator = webdriver.By.className;
8+
css: (css: string) => Locator = webdriver.By.css;
9+
id: (id: string) => Locator = webdriver.By.id;
10+
linkText: (linkText: string) => Locator = webdriver.By.linkText;
11+
js: (js: string) => Locator = webdriver.By.js;
12+
name: (name: string) => Locator = webdriver.By.name;
13+
partialLinkText:
14+
(partialText: string) => Locator = webdriver.By.partialLinkText;
15+
tagName: (tagName: string) => Locator = webdriver.By.tagName;
16+
xpath: (xpath: string) => Locator = webdriver.By.xpath;
17+
}
1118

19+
// Interface for webdriver.Locator.
1220
export interface Locator {
1321
findElementsOverride?:
1422
(driver: webdriver.WebDriver, using: webdriver.WebElement,
@@ -27,17 +35,6 @@ export interface Locator {
2735
export class ProtractorBy extends WebdriverBy {
2836
[key: string]: any;
2937

30-
className: (className: string) => Locator = webdriver.By.className;
31-
css: (css: string) => Locator = webdriver.By.css;
32-
id: (id: string) => Locator = webdriver.By.id;
33-
linkText: (linkText: string) => Locator = webdriver.By.linkText;
34-
js: (js: string) => Locator = webdriver.By.js;
35-
name: (name: string) => Locator = webdriver.By.name;
36-
partialLinkText:
37-
(partialText: string) => Locator = webdriver.By.partialLinkText;
38-
tagName: (tagName: string) => Locator = webdriver.By.tagName;
39-
xpath: (xpath: string) => Locator = webdriver.By.xpath;
40-
4138
/**
4239
* Add a locator to this instance of ProtractorBy. This locator can then be
4340
* used with element(by.locatorName(args)).

0 commit comments

Comments
 (0)