From 4b3b00d6d24dbea9887a88e7270b52239389838e Mon Sep 17 00:00:00 2001 From: Bill Armstrong Date: Sun, 14 Dec 2014 09:41:03 -0500 Subject: [PATCH] Updated Angular-Protractor to v1.5.0. --- .../angular-protractor-tests.ts | 416 +++-- angular-protractor/angular-protractor.d.ts | 1637 ++++++++++++----- .../angular-protractor-1.0.0-rc4-tests.ts | 280 +++ .../legacy/angular-protractor-1.0.0-rc4.d.ts | 1125 +++++++++++ selenium-webdriver/chrome.d.ts | 4 +- selenium-webdriver/firefox.d.ts | 18 +- ....ts => selenium-webdriver-2.39.0-tests.ts} | 2 +- .../selenium-webdriver-tests.ts | 5 +- selenium-webdriver/selenium-webdriver.d.ts | 812 +++++--- 9 files changed, 3407 insertions(+), 892 deletions(-) create mode 100644 angular-protractor/legacy/angular-protractor-1.0.0-rc4-tests.ts create mode 100644 angular-protractor/legacy/angular-protractor-1.0.0-rc4.d.ts rename selenium-webdriver/legacy/{selenium-webdriver-tests-2.39.0.ts => selenium-webdriver-2.39.0-tests.ts} (99%) diff --git a/angular-protractor/angular-protractor-tests.ts b/angular-protractor/angular-protractor-tests.ts index 5ca9ecde4..e0f4040b0 100644 --- a/angular-protractor/angular-protractor-tests.ts +++ b/angular-protractor/angular-protractor-tests.ts @@ -1,11 +1,7 @@ /// function TestWebDriverExports() { - var abstractBuilder: protractor.AbstractBuilder = new protractor.AbstractBuilder(); - var baseAbstractBuilder: webdriver.AbstractBuilder = abstractBuilder; - - var button: protractor.Button = new protractor.Button(); - var baseButton: webdriver.Button = button; + var button: number = protractor.Button.LEFT; var key: string = protractor.Key.ADD; var chord: string = protractor.Key.chord(protractor.Key.NUMPAD0, protractor.Key.NUMPAD1); @@ -18,12 +14,6 @@ function TestWebDriverExports() { var action: protractor.ActionSequence = new protractor.ActionSequence(driver); var baseAction: webdriver.ActionSequence = action; - var alert: protractor.Alert = new protractor.Alert(driver, 'Message'); - var baseAlert: webdriver.Alert = alert; - - var unhandledAlertError: protractor.UnhandledAlertError = new protractor.UnhandledAlertError('Message', alert); - var baseUnhandledAlertError: webdriver.UnhandledAlertError = unhandledAlertError; - var browser: string = protractor.Browser.ANDROID; var builder: protractor.Builder = new protractor.Builder(); @@ -42,71 +32,25 @@ function TestWebDriverExports() { var eventEmitter: protractor.EventEmitter = new protractor.EventEmitter(); var baseEventEmitter: webdriver.EventEmitter = eventEmitter; - var firefoxDomExecutor: protractor.FirefoxDomExecutor = new protractor.FirefoxDomExecutor(); - var baseFirefoxDomExecutor: webdriver.FirefoxDomExecutor = firefoxDomExecutor; - var webElement: protractor.WebElement = new protractor.WebElement(driver, new protractor.promise.Promise()); var baseWebElement: webdriver.WebElement = webElement; - var locator: protractor.Locator = new protractor.Locator('id', 'ABC'); - var baseLocator: webdriver.Locator = locator; + var locator: webdriver.Locator = by.id('abc'); var session: protractor.Session = new protractor.Session('ABC', webdriver.Capabilities.android()); var baseSession: webdriver.Session = session; locator = protractor.By.name('name'); - // logging module + var driver: protractor.WebDriver = new protractor.WebDriver(session, {}); + driver = new protractor.WebDriver(session, {}, new webdriver.promise.ControlFlow()); + var baseDriver: webdriver.WebDriver = driver; - var levelName: string = protractor.logging.LevelName.ALL; - var loggingType: string = protractor.logging.Type.CLIENT; + var webElement: protractor.WebElement = new protractor.WebElement(driver, { ELEMENT: 'abc' }); + var baseWebElement: webdriver.WebElement = webElement; - var level: webdriver.logging.Level = protractor.logging.Level.ALL; - - var entry: protractor.logging.Entry = new protractor.logging.Entry(protractor.logging.Level.ALL, 'Message'); - var baseEntry: webdriver.logging.Entry = entry; - - level = protractor.logging.getLevel('DEBUG'); - - protractor.logging.Preferences = { a: 123 }; - - // promise module - - var promise: protractor.promise.Promise = new protractor.promise.Promise(); - var basePromise: webdriver.promise.Promise = promise; - - var deferred: protractor.promise.Deferred = new protractor.promise.Deferred(); - var baseDeferred: webdriver.promise.Deferred = deferred; - - var flow: protractor.promise.ControlFlow = new protractor.promise.ControlFlow(); - var baseFlow: webdriver.promise.ControlFlow = flow; - - protractor.promise.asap(promise, function(value: any){ return true; }); - protractor.promise.asap(promise, function(value: any){}, function(err: any) { return 'ABC'; }); - - promise = protractor.promise.checkedNodeCall(function(err: any, value: any) { return 123; }); - - flow = protractor.promise.controlFlow(); - - promise = protractor.promise.createFlow(function(newFlow: webdriver.promise.ControlFlow) { }); - - deferred = protractor.promise.defer(function() {}); - deferred = protractor.promise.defer(function(reason?: any) {}); - - promise = protractor.promise.delayed(123); - - promise = protractor.promise.fulfilled(); - promise = protractor.promise.fulfilled({a: 123}); - - promise = protractor.promise.fullyResolved({a: 123}); - - var isPromise: boolean = protractor.promise.isPromise('ABC'); - - promise = protractor.promise.rejected({a: 123}); - - protractor.promise.setDefaultFlow(new webdriver.promise.ControlFlow()); - - promise = protractor.promise.when(promise, function(value: any) { return 123; }, function(err: Error) { return 123; }); + var webElementPromise: protractor.WebElementPromise = new protractor.WebElementPromise(driver, { ELEMENT: 'abc' }); + var baseWebElementPromise: webdriver.WebElementPromise = webElementPromise; // error module @@ -114,17 +58,140 @@ function TestWebDriverExports() { var error: protractor.error.Error = new protractor.error.Error(protractor.error.ErrorCode.ELEMENT_NOT_VISIBLE); var baseError: webdriver.error.Error = error; - // process module + // logging module - var isNative: boolean = protractor.process.isNative(); - var value: string; + var levelName: string = protractor.logging.Level.ALL.name; + var loggingType: string = protractor.logging.Type.CLIENT; - value = protractor.process.getEnv('name'); - value = protractor.process.getEnv('name', 'default'); + var level: webdriver.logging.ILevel = protractor.logging.Level.ALL; - protractor.process.setEnv('name', 'value'); - protractor.process.setEnv('name', 123); + var entry: protractor.logging.Entry = new protractor.logging.Entry(protractor.logging.Level.ALL, 'Message'); + var baseEntry: webdriver.logging.Entry = entry; + level = protractor.logging.getLevel('DEBUG'); + + var prefs: protractor.logging.Preferences = new protractor.logging.Preferences(); + + // promise module + + var cancelError: protractor.promise.CancellationError = new protractor.promise.CancellationError(); + cancelError = new protractor.promise.CancellationError('message'); + var baseCancelError: webdriver.promise.CancellationError = cancelError; + + var thenable: protractor.promise.Thenable = new protractor.promise.Thenable(); + var baseThenable: webdriver.promise.Thenable = thenable; + + var promise: protractor.promise.Promise = new protractor.promise.Promise(); + var basePromise: webdriver.promise.Promise = promise; + + var deferred: protractor.promise.Deferred = new protractor.promise.Deferred(); + var baseDeferred: webdriver.promise.Deferred = deferred; + + var flow: protractor.promise.ControlFlow = new protractor.promise.ControlFlow(); + var baseFlow: webdriver.promise.ControlFlow = flow; + + var arrayPromise: protractor.promise.Promise = protractor.promise.all([new protractor.promise.Promise(), new protractor.promise.Promise()]); + + protractor.promise.asap(promise, function(value: any){ return true; }); + protractor.promise.asap(promise, function(value: any){}, function(err: any) { return 'ABC'; }); + + promise = protractor.promise.checkedNodeCall(function(err: any, value: any) { return 123; }); + + promise = protractor.promise.consume(function () { + return 5; + }); + promise = protractor.promise.consume(function () { + return 5; + }, this); + promise = protractor.promise.consume(function () { + return 5; + }, this, 1, 2, 3); + + flow = protractor.promise.controlFlow(); + + promise = protractor.promise.createFlow(function(newFlow: webdriver.promise.ControlFlow) { }); + + deferred = protractor.promise.defer(); + + promise = protractor.promise.delayed(123); + + var numbersPromise: protractor.promise.Promise = protractor.promise.filter([1, 2, 3], function (el: number, index: number, arr: number[]) { + return true; + }); + numbersPromise = protractor.promise.filter([1, 2, 3], function (el: number, index: number, arr: number[]) { + return true; + }, this); + numbersPromise = protractor.promise.filter(numbersPromise, function (el: number, index: number, arr: number[]) { + return true; + }); + numbersPromise = protractor.promise.filter(numbersPromise, function (el: number, index: number, arr: number[]) { + return true; + }, this); + + numbersPromise = protractor.promise.map([1, 2, 3], function (el: number, index: number, arr: number[]) { + return true; + }); + numbersPromise = protractor.promise.map([1, 2, 3], function (el: number, index: number, arr: number[]) { + return true; + }, this); + numbersPromise = protractor.promise.map(numbersPromise, function (el: number, index: number, arr: number[]) { + return true; + }); + numbersPromise = protractor.promise.map(numbersPromise, function (el: number, index: number, arr: number[]) { + return true; + }, this); + + promise = protractor.promise.fulfilled(); + promise = protractor.promise.fulfilled({a: 123}); + + promise = protractor.promise.fullyResolved({a: 123}); + + var bool: boolean = protractor.promise.isGenerator(function () { }); + var bool: boolean = protractor.promise.isPromise('ABC'); + + promise = protractor.promise.rejected({a: 123}); + + protractor.promise.setDefaultFlow(new webdriver.promise.ControlFlow()); + + promise = protractor.promise.when(promise, function (value: any) { return 123; }, function (err: Error) { return 123; }); + + // stacktrace module + bool = protractor.stacktrace.BROWSER_SUPPORTED; + + var frame: protractor.stacktrace.Frame = new protractor.stacktrace.Frame(); + var baseFrame: webdriver.stacktrace.Frame = frame; + + var snapshot: protractor.stacktrace.Snapshot = new protractor.stacktrace.Snapshot(); + var baseSnapshot: webdriver.stacktrace.Snapshot = snapshot; + + var err: Error = protractor.stacktrace.format(new Error("Error")); + var frames: protractor.stacktrace.Frame[] = protractor.stacktrace.get(); + + // until module + var conditionB: protractor.until.Condition = new protractor.until.Condition('message', function (driver: webdriver.WebDriver) { return true; }); + var conditionBBase: webdriver.until.Condition = conditionB; + var conditionWebElement: protractor.until.Condition; + var conditionWebElements: protractor.until.Condition; + + conditionB = protractor.until.ableToSwitchToFrame(5); + var conditionAlert: protractor.until.Condition = protractor.until.alertIsPresent(); + var el: protractor.ElementFinder = element(by.id('id')); + conditionB = protractor.until.elementIsDisabled(el); + conditionB = protractor.until.elementIsEnabled(el); + conditionB = protractor.until.elementIsNotSelected(el); + conditionB = protractor.until.elementIsNotVisible(el); + conditionB = protractor.until.elementIsSelected(el); + conditionB = protractor.until.elementIsVisible(el); + conditionB = protractor.until.elementTextContains(el, 'text'); + conditionB = protractor.until.elementTextIs(el, 'text'); + conditionB = protractor.until.elementTextMatches(el, /text/); + conditionB = protractor.until.stalenessOf(el); + conditionB = protractor.until.titleContains('text'); + conditionB = protractor.until.titleIs('text'); + conditionB = protractor.until.titleMatches(/text/); + + conditionWebElement = protractor.until.elementLocated(by.id('id')); + conditionWebElements = protractor.until.elementsLocated(by.className('class')); } function TestProtractor() { @@ -133,31 +200,47 @@ function TestProtractor() { withCapabilities(webdriver.Capabilities.chrome()). build(); - ptor = new protractor.Protractor(driver); - ptor = new protractor.Protractor(driver, 'baseUrl'); - ptor = new protractor.Protractor(driver, 'baseUrl', 'rootElement'); - ptor = protractor.getInstance(); - protractor.setInstance(ptor); - ptor = protractor.wrapDriver(driver); ptor = protractor.wrapDriver(driver, 'baseUrl'); ptor = protractor.wrapDriver(driver, 'baseUrl', 'rootElement'); ptor = browser; + var actions: protractor.ActionSequence = ptor.actions(); + + var promise: protractor.promise.Promise = ptor.call(function () { }); + var promise: protractor.promise.Promise = ptor.call(function () { }, this); + var promise: protractor.promise.Promise = ptor.call(function (a: number, b: number, c:number) { }, this, 1, 2,3); + + promise = ptor.executeAsyncScript('SomeScript'); + promise = ptor.executeAsyncScript('SomeScript', 1, 2, 3); + promise = ptor.executeAsyncScript(function () { }); + promise = ptor.executeAsyncScript(function (a: number, b: number, c: number) { }, 1, 2, 3); + + promise = ptor.executeScript('SomeScript'); + promise = ptor.executeScript('SomeScript', 1, 2, 3); + promise = ptor.executeScript(function () { }); + promise = ptor.executeScript(function (a: number, b: number, c: number) { }, 1, 2, 3); + + ptor = browser.forkNewDriverInstance(); + ptor = browser.forkNewDriverInstance(true); + ptor = browser.forkNewDriverInstance(true, false); + driver = ptor.driver; var baseUrl: string = ptor.baseUrl; var rootEl: string = ptor.rootEl; var ignoreSynchronization: boolean = ptor.ignoreSynchronization; var params: any = ptor.params; + ptor.resetUrl = "url"; ptor.debugger(); + ptor.close(); + var controlFlow: protractor.promise.ControlFlow = ptor.controlFlow(); var webElement: protractor.WebElement = ptor.findElement(by.css('.class')); - var promise: webdriver.promise.Promise; - promise = ptor.findElements(by.css('.class')); - promise = ptor.isElementPresent(by.css('.class')); - promise = ptor.isElementPresent(webElement); + ptor.findElements(by.css('.class')).then(function (elements: webdriver.WebElement[]) { }); + ptor.isElementPresent(by.css('.class')).then(function (present: boolean) { }); + ptor.isElementPresent(webElement).then(function (present: boolean) { }); ptor.clearMockModules(); ptor.addMockModule('name', 'script'); @@ -173,16 +256,43 @@ function TestProtractor() { elementArrayFinder = ptor.$$('.class'); - var locationAbsUrl: webdriver.promise.Promise = ptor.getLocationAbsUrl(); + var locationAbsUrl: webdriver.promise.Promise = ptor.getLocationAbsUrl(); ptor.setLocation('webaddress.com'); - promise = ptor.get('webaddress.com'); - promise = ptor.get('webdaddress.com', 45); + var voidPromise: webdriver.promise.Promise = ptor.get('webaddress.com'); + voidPromise = ptor.get('webdaddress.com', 45); + voidPromise = ptor.quit(); + voidPromise = ptor.sleep(5000); + ptor.refresh(); ptor.refresh(45); var navigation: webdriver.WebDriverNavigation = ptor.navigate(); ptor.pause(); ptor.pause(8080); + + ptor.getAllWindowHandles().then(function (handles: string[]) { }); + + var capabilities: protractor.promise.Promise = ptor.getCapabilities(); + + var stringPromise: webdriver.promise.Promise; + stringPromise = ptor.getCurrentUrl(); + stringPromise = ptor.getPageSource(); + stringPromise = ptor.getTitle(); + stringPromise = ptor.getWindowHandle(); + stringPromise = ptor.takeScreenshot(); + + ptor.getPageTimeout = 5000; + + var session: protractor.promise.Promise = ptor.getSession(); + + var options: webdriver.WebDriverOptions = ptor.manage(); + + promise = ptor.schedule(new protractor.Command(protractor.CommandName.ACCEPT_ALERT), 'asdf'); + + var targetLocator: webdriver.WebDriverTargetLocator = ptor.switchTo(); + + ptor.wait(protractor.until.elementLocated(by.id('id')), 5000).then(function (el: webdriver.IWebElement) { });; + ptor.wait(protractor.until.elementLocated(by.id('id')), 5000, 'message').then(function (el: webdriver.IWebElement) { });; } function TestElement() { @@ -192,80 +302,121 @@ function TestElement() { function TestElementFinder() { var elementFinder: protractor.ElementFinder = element(by.id('id')); - var promise: webdriver.promise.Promise; + var voidPromise: webdriver.promise.Promise; + var stringPromise: webdriver.promise.Promise; + var booleanPromise: webdriver.promise.Promise; - promise = elementFinder.click(); - promise = elementFinder.allowAnimations('string'); - promise = elementFinder.sendKeys(protractor.Key.UP, protractor.Key.DOWN); - promise = elementFinder.getTagName(); - promise = elementFinder.getCssValue('display'); - promise = elementFinder.getAttribute('atribute'); - promise = elementFinder.getText(); - promise = elementFinder.getSize(); - promise = elementFinder.getLocation(); - promise = elementFinder.isEnabled(); - promise = elementFinder.isSelected(); - promise = elementFinder.submit(); - promise = elementFinder.clear(); - promise = elementFinder.isDisplayed(); - promise = elementFinder.getOuterHtml(); - promise = elementFinder.getInnerHtml(); - promise = elementFinder.isElementPresent(by.id('id')); - promise = elementFinder.$('.class'); - promise = elementFinder.$$('.class'); - promise = elementFinder.evaluate('expression'); - promise = elementFinder.isPresent(); + elementFinder.getId().then(function (id: webdriver.IWebElementId) { }); + voidPromise = elementFinder.click(); + elementFinder = elementFinder.allowAnimations('string'); + voidPromise = elementFinder.sendKeys(protractor.Key.UP, protractor.Key.DOWN); + stringPromise = elementFinder.getTagName(); + stringPromise = elementFinder.getCssValue('display'); + stringPromise = elementFinder.getAttribute('atribute'); + stringPromise = elementFinder.getText(); + elementFinder.getSize().then(function (size: webdriver.ISize) { }); + elementFinder.getLocation().then(function (location: webdriver.ILocation) { }); + booleanPromise = elementFinder.isEnabled(); + booleanPromise = elementFinder.isSelected(); + voidPromise = elementFinder.submit(); + voidPromise = elementFinder.clear(); + booleanPromise = elementFinder.isDisplayed(); + stringPromise = elementFinder.getOuterHtml(); + stringPromise = elementFinder.getInnerHtml(); + booleanPromise = elementFinder.isElementPresent(by.id('id')); + elementFinder = elementFinder.$('.class'); + var finders: protractor.ElementArrayFinder = elementFinder.$$('.class'); + elementFinder = elementFinder.evaluate('expression'); + booleanPromise = elementFinder.isPresent(); - var webElement: webdriver.WebElement; + var webElement: webdriver.WebElement = elementFinder.getWebElement(); + finders = elementFinder.all(by.className('class')); + elementFinder = elementFinder.allowAnimations('abc'); + elementFinder = elementFinder.clone(); + elementFinder = elementFinder.element(by.id('id')); + + var b: boolean = elementFinder.isPending(); + var locator: webdriver.Locator = elementFinder.locator(); } function TestElementArrayFinder() { var elementArrayFinder: protractor.ElementArrayFinder = element.all(by.id('id')); - var promise: webdriver.promise.Promise; - var elementFinder: protractor.ElementFinder; + + var voidPromise: webdriver.promise.Promise; + var stringPromise: webdriver.promise.Promise; + var booleanPromise: webdriver.promise.Promise; + + elementArrayFinder.getId().then(function (id: webdriver.IWebElementId[]) { }); + voidPromise = elementArrayFinder.click(); + elementArrayFinder = elementArrayFinder.allowAnimations(true); + voidPromise = elementArrayFinder.sendKeys(protractor.Key.UP, protractor.Key.DOWN); + stringPromise = elementArrayFinder.getTagName(); + stringPromise = elementArrayFinder.getCssValue('display'); + stringPromise = elementArrayFinder.getAttribute('atribute'); + stringPromise = elementArrayFinder.getText(); + elementArrayFinder.getSize().then(function (size: webdriver.ISize[]) { }); + elementArrayFinder.getLocation().then(function (location: webdriver.ILocation[]) { }); + booleanPromise = elementArrayFinder.isEnabled(); + booleanPromise = elementArrayFinder.isSelected(); + voidPromise = elementArrayFinder.submit(); + voidPromise = elementArrayFinder.clear(); + booleanPromise = elementArrayFinder.isDisplayed(); + stringPromise = elementArrayFinder.getOuterHtml(); + stringPromise = elementArrayFinder.getInnerHtml(); + var finders: protractor.ElementArrayFinder = elementArrayFinder.$$('.class'); + elementArrayFinder = elementArrayFinder.evaluate('expression'); + + finders = elementArrayFinder.all(by.className('class')); + elementArrayFinder = elementArrayFinder.clone(); + + var b: boolean = elementArrayFinder.isPending(); + var locator: webdriver.Locator = elementArrayFinder.locator(); + + var findersArray: protractor.ElementFinder[] = elementArrayFinder.asElementFinders_(); var driverElementArray: webdriver.WebElement[] = elementArrayFinder.getWebElements(); - elementFinder = elementArrayFinder.get(42); + var elementFinder: protractor.ElementFinder = elementArrayFinder.get(42); elementFinder = elementArrayFinder.first(); elementFinder = elementArrayFinder.last(); - promise = elementArrayFinder.count(); - promise = elementArrayFinder.asElementFinders_(); + elementFinder = elementArrayFinder.toElementFinder_() + var numberPromise: protractor.promise.Promise = elementArrayFinder.count(); elementArrayFinder.each(function(element: protractor.ElementFinder){ // nothing }); - elementArrayFinder.map(function(element: protractor.ElementFinder, index: number){ - // nothing - }); - elementArrayFinder.filter(function(element: protractor.ElementFinder, index: number){ + stringPromise = elementArrayFinder.map(function(element: protractor.ElementFinder, index: number){ + return 'abc'; + }) + elementArrayFinder = elementArrayFinder.filter(function(element: protractor.ElementFinder, index: number){ return element.getText().then((text: string) => { return text === "foo"; }); }); - elementArrayFinder.reduce(function(accumulator: string, element: protractor.ElementFinder){ + elementArrayFinder.reduce(function (accumulator: string, element: protractor.ElementFinder) { return element.getText().then((text: string) => { return accumulator + ',' + text; }); - }, ''); + }, '').then(function (result: string) { }); elementArrayFinder.reduce(function(accumulator: string, element: protractor.ElementFinder, index: number, array: protractor.ElementFinder[]){ return element.getText().then((text: string) => { return accumulator + ',' + text; }); - }, ''); + }, '').then(function (result: string) { }); elementArrayFinder.then(function(underlyingElementFinders: protractor.ElementFinder[]){ //nothing }); } -// This function tests the angular specific locator strategies. +// This function tests the locator strategies. function TestLocatorStrategies() { - var ptor: protractor.Protractor = protractor.getInstance(); + var ptor: protractor.Protractor = browser; var webElement: webdriver.WebElement; - // Protractor Specific Locators protractor.By.addLocator('customLocator', 'script'); protractor.By.addLocator('customLocator2', function(){ // nothing }); + + // Angular specific locators. webElement = ptor.findElement(protractor.By.binding('binding')); webElement = ptor.findElement(protractor.By.exactBinding('exactBinding')); webElement = ptor.findElement(protractor.By.model('model')); @@ -277,4 +428,23 @@ function TestLocatorStrategies() { webElement = ptor.findElement(protractor.By.partialButtonText('partialButtonText')); webElement = ptor.findElement(protractor.By.cssContainingText('cssSelector', 'search text')); webElement = ptor.findElement(protractor.By.options('options')); + // One standard locator for good measure. + webElement = ptor.findElement(protractor.By.id('id')); + + var el: protractor.ElementFinder; + + // Angular specific locators. + el = element(by.binding('binding')); + el = element(by.exactBinding('exactBinding')); + el = element(by.model('model')); + el = element(by.repeater('repeater')); + el = element(by.repeater('repeater').column(0)); + el = element(by.repeater('repeater').row(0)); + el = element(by.repeater('repeater').row(0).column(0)); + el = element(by.buttonText('buttonText')); + el = element(by.partialButtonText('partialButtonText')); + el = element(by.cssContainingText('cssSelector', 'search text')); + el = element(by.options('options')); + // One standard locator for good measure. + el = element(by.id('id')); } diff --git a/angular-protractor/angular-protractor.d.ts b/angular-protractor/angular-protractor.d.ts index 2de49a0a4..8e24c5f57 100644 --- a/angular-protractor/angular-protractor.d.ts +++ b/angular-protractor/angular-protractor.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Angular Protractor 1.0.0-rc4 +// Type definitions for Angular Protractor 1.5.0 // Project: https://github.com/angular/protractor // Definitions by: Bill Armstrong // Definitions: https://github.com/borisyankov/DefinitelyTyped @@ -8,55 +8,72 @@ declare module protractor { //region Wrapped webdriver Items - class AbstractBuilder extends webdriver.AbstractBuilder {} class ActionSequence extends webdriver.ActionSequence {} - class Alert extends webdriver.Alert {} class Builder extends webdriver.Builder {} - class Button extends webdriver.Button {} class Capabilities extends webdriver.Capabilities {} class Command extends webdriver.Command {} class EventEmitter extends webdriver.EventEmitter {} - class FirefoxDomExecutor extends webdriver.FirefoxDomExecutor {} - class Locator extends webdriver.Locator {} class Session extends webdriver.Session {} class WebDriver extends webdriver.WebDriver {} - class Browser extends webdriver.Browser {} - class Capability extends webdriver.Capability {} - class CommandName extends webdriver.CommandName {} - class Key extends webdriver.Key {} - class UnhandledAlertError extends webdriver.UnhandledAlertError {} class WebElement extends webdriver.WebElement {} + class WebElementPromise extends webdriver.WebElementPromise { } - module command { - class Command extends webdriver.Command {} - class CommandName extends webdriver.CommandName {} - } + var Browser: webdriver.IBrowser; + var Button: webdriver.IButton; + var Capability: webdriver.ICapability; + var CommandName: webdriver.ICommandName; + var Key: webdriver.IKey; module error { class Error extends webdriver.error.Error {} - class ErrorCode extends webdriver.error.ErrorCode {} - } - - module events { - class EventEmitter extends webdriver.EventEmitter {} + var ErrorCode: webdriver.error.IErrorCode; } module logging { - var Preferences: any; + class Preferences extends webdriver.logging.Preferences { } + class Entry extends webdriver.logging.Entry { } - class LevelName extends webdriver.logging.LevelName {} - class Type extends webdriver.logging.Type {} - class Level extends webdriver.logging.Level {} - class Entry extends webdriver.logging.Entry {} + var Type: webdriver.logging.IType; + var Level: webdriver.logging.ILevelValues; - function getLevel(nameOrValue: string): webdriver.logging.Level; - function getLevel(nameOrValue: number): webdriver.logging.Level; + function getLevel(nameOrValue: string): webdriver.logging.ILevel; + function getLevel(nameOrValue: number): webdriver.logging.ILevel; } module promise { - class Promise extends webdriver.promise.Promise {} - class Deferred extends webdriver.promise.Deferred {} - class ControlFlow extends webdriver.promise.ControlFlow {} + class Thenable extends webdriver.promise.Thenable { } + class Promise extends webdriver.promise.Promise { } + class Deferred extends webdriver.promise.Deferred { } + class ControlFlow extends webdriver.promise.ControlFlow { } + class CancellationError extends webdriver.promise.CancellationError { } + + /** + * Given an array of promises, will return a promise that will be fulfilled + * with the fulfillment values of the input array's values. If any of the + * input array's promises are rejected, the returned promise will be rejected + * with the same reason. + * + * @param {!Array.<(T|!webdriver.promise.Promise.)>} arr An array of + * promises to wait on. + * @return {!webdriver.promise.Promise.>} A promise that is + * fulfilled with an array containing the fulfilled values of the + * input array, or rejected with the same reason as the first + * rejected value. + * @template T + */ + function all(arr: webdriver.promise.Promise[]): webdriver.promise.Promise; + + /** + * Invokes the appropriate callback function as soon as a promised + * {@code value} is resolved. This function is similar to + * {@link webdriver.promise.when}, except it does not return a new promise. + * @param {*} value The value to observe. + * @param {Function} callback The function to call when the value is + * resolved successfully. + * @param {Function=} opt_errback The function to call when the value is + * rejected. + */ + function asap(value: any, callback: Function, opt_errback?: Function): void; /** * @return {!webdriver.promise.ControlFlow} The currently active control flow. @@ -72,7 +89,7 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise that resolves to the callback * result. */ - function createFlow(callback: (flow: webdriver.promise.ControlFlow) => any): webdriver.promise.Promise; + function createFlow(callback: (flow: webdriver.promise.ControlFlow) => R): webdriver.promise.Promise; /** * Determines whether a {@code value} should be treated as a promise. @@ -83,28 +100,83 @@ declare module protractor { */ function isPromise(value: any): boolean; + /** + * Tests is a function is a generator. + * @param {!Function} fn The function to test. + * @return {boolean} Whether the function is a generator. + */ + function isGenerator(fn: Function): boolean; + /** * Creates a promise that will be resolved at a set time in the future. * @param {number} ms The amount of time, in milliseconds, to wait before * resolving the promise. * @return {!webdriver.promise.Promise} The promise. */ - function delayed(ms: number): webdriver.promise.Promise; + function delayed(ms: number): webdriver.promise.Promise; + + /** + * Calls a function for each element in an array, and if the function returns + * true adds the element to a new array. + * + *

If the return value of the filter function is a promise, this function + * will wait for it to be fulfilled before determining whether to insert the + * element into the new array. + * + *

If the filter function throws or returns a rejected promise, the promise + * returned by this function will be rejected with the same reason. Only the + * first failure will be reported; all subsequent errors will be silently + * ignored. + * + * @param {!(Array.|webdriver.promise.Promise.>)} arr The + * array to iterator over, or a promise that will resolve to said array. + * @param {function(this: SELF, TYPE, number, !Array.): ( + * boolean|webdriver.promise.Promise.)} fn The function + * to call for each element in the array. + * @param {SELF=} opt_self The object to be used as the value of 'this' within + * {@code fn}. + * @template TYPE, SELF + */ + function filter(arr: T[], fn: (element: T, index: number, array: T[]) => any, opt_self?: any): webdriver.promise.Promise; + function filter(arr: webdriver.promise.Promise, fn: (element: T, index: number, array: T[]) => any, opt_self?: any): webdriver.promise.Promise /** * Creates a new deferred object. - * @param {Function=} opt_canceller Function to call when cancelling the - * computation of this instance's value. * @return {!webdriver.promise.Deferred} The new deferred object. */ - function defer(opt_canceller?: any): webdriver.promise.Deferred; + function defer(): webdriver.promise.Deferred; /** * Creates a promise that has been resolved with the given value. * @param {*=} opt_value The resolved value. * @return {!webdriver.promise.Promise} The resolved promise. */ - function fulfilled(opt_value?: any): webdriver.promise.Promise; + function fulfilled(opt_value?: T): webdriver.promise.Promise; + + /** + * Calls a function for each element in an array and inserts the result into a + * new array, which is used as the fulfillment value of the promise returned + * by this function. + * + *

If the return value of the mapping function is a promise, this function + * will wait for it to be fulfilled before inserting it into the new array. + * + *

If the mapping function throws or returns a rejected promise, the + * promise returned by this function will be rejected with the same reason. + * Only the first failure will be reported; all subsequent errors will be + * silently ignored. + * + * @param {!(Array.|webdriver.promise.Promise.>)} arr The + * array to iterator over, or a promise that will resolve to said array. + * @param {function(this: SELF, TYPE, number, !Array.): ?} fn The + * function to call for each element in the array. This function should + * expect three arguments (the element, the index, and the array itself. + * @param {SELF=} opt_self The object to be used as the value of 'this' within + * {@code fn}. + * @template TYPE, SELF + */ + function map(arr: T[], fn: (element: T, index: number, array: T[]) => any, opt_self?: any): webdriver.promise.Promise + function map(arr: webdriver.promise.Promise, fn: (element: T, index: number, array: T[]) => any, opt_self?: any): webdriver.promise.Promise /** * Creates a promise that has been rejected with the given reason. @@ -112,7 +184,7 @@ declare module protractor { * usually an Error or a string. * @return {!webdriver.promise.Promise} The rejected promise. */ - function rejected(opt_reason?: any): webdriver.promise.Promise; + function rejected(opt_reason?: any): webdriver.promise.Promise; /** * Wraps a function that is assumed to be a node-style callback as its final @@ -124,7 +196,49 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise that will be resolved with the * result of the provided function's callback. */ - function checkedNodeCall(fn: (error: any, value: any) => any): webdriver.promise.Promise; + function checkedNodeCall(fn: Function, ...var_args: any[]): webdriver.promise.Promise; + + /** + * Consumes a {@code GeneratorFunction}. Each time the generator yields a + * promise, this function will wait for it to be fulfilled before feeding the + * fulfilled value back into {@code next}. Likewise, if a yielded promise is + * rejected, the rejection error will be passed to {@code throw}. + * + *

Example 1: the Fibonacci Sequence. + *


+         * webdriver.promise.consume(function* fibonacci() {
+         *   var n1 = 1, n2 = 1;
+         *   for (var i = 0; i < 4; ++i) {
+         *     var tmp = yield n1 + n2;
+         *     n1 = n2;
+         *     n2 = tmp;
+         *   }
+         *   return n1 + n2;
+         * }).then(function(result) {
+         *   console.log(result);  // 13
+         * });
+         * 
+ * + *

Example 2: a generator that throws. + *


+         * webdriver.promise.consume(function* () {
+         *   yield webdriver.promise.delayed(250).then(function() {
+         *     throw Error('boom');
+         *   });
+         * }).thenCatch(function(e) {
+         *   console.log(e.toString());  // Error: boom
+         * });
+         * 
+ * + * @param {!Function} generatorFn The generator function to execute. + * @param {Object=} opt_self The object to use as "this" when invoking the + * initial generator. + * @param {...*} var_args Any arguments to pass to the initial generator. + * @return {!webdriver.promise.Promise.} A promise that will resolve to the + * generator's final result. + * @throws {TypeError} If the given function is not a generator. + */ + function consume(generatorFn: Function, opt_self?: any, ...var_args: any[]): webdriver.promise.Promise; /** * Registers an observer on a promised {@code value}, returning a new promise @@ -137,19 +251,8 @@ declare module protractor { * rejected. * @return {!webdriver.promise.Promise} A new promise. */ - function when(value: any, opt_callback?: (value: any) => any, opt_errback?: (error: any) => any): webdriver.promise.Promise; - - /** - * Invokes the appropriate callback function as soon as a promised - * {@code value} is resolved. This function is similar to - * {@code webdriver.promise.when}, except it does not return a new promise. - * @param {*} value The value to observe. - * @param {Function} callback The function to call when the value is - * resolved successfully. - * @param {Function=} opt_errback The function to call when the value is - * rejected. - */ - function asap(value: any, callback: (value: any) => any, opt_errback?: (error: any) => any): void; + function when(value: T, opt_callback?: (value: T) => any, opt_errback?: (error: any) => any): webdriver.promise.Promise; + function when(value: webdriver.promise.Promise, opt_callback?: (value: T) => any, opt_errback?: (error: any) => any): webdriver.promise.Promise; /** * Returns a promise that will be resolved with the input value in a @@ -170,7 +273,7 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise for a fully resolved version * of the input value. */ - function fullyResolved(value: any): webdriver.promise.Promise; + function fullyResolved(value: any): webdriver.promise.Promise; /** * Changes the default flow to use when no others are active. @@ -178,55 +281,246 @@ declare module protractor { * @throws {Error} If the default flow is not currently active. */ function setDefaultFlow(flow: webdriver.promise.ControlFlow): void; - } - module process { + module stacktrace { + class Frame extends webdriver.stacktrace.Frame { } + class Snapshot extends webdriver.stacktrace.Snapshot { } /** - * Queries for a named environment variable. - * @param {string} name The name of the environment variable to look up. - * @param {string=} opt_default The default value if the named variable is not - * defined. - * @return {string} The queried environment variable. + * Formats an error's stack trace. + * @param {!(Error|goog.testing.JsUnitException)} error The error to format. + * @return {!(Error|goog.testing.JsUnitException)} The formatted error. */ - function getEnv(name: string, opt_default?: string): string; + function format(error: any): any; /** - * @return {boolean} Whether the current process is Node's native process - * object. + * Gets the native stack trace if available otherwise follows the call chain. + * The generated trace will exclude all frames up to and including the call to + * this function. + * @return {!Array.} The frames of the stack trace. */ - function isNative(): boolean; + function get(): webdriver.stacktrace.Frame[]; /** - * Sets an environment value. If the new value is either null or undefined, the - * environment variable will be cleared. - * @param {string} name The value to set. - * @param {*} value The new value; will be coerced to a string. + * Whether the current browser supports stack traces. + * + * @type {boolean} + * @const */ - function setEnv(name: string, value: any): void; + var BROWSER_SUPPORTED: boolean; + } + module until { + class Condition extends webdriver.until.Condition { } + + /** + * Creates a condition that will wait until the input driver is able to switch + * to the designated frame. The target frame may be specified as: + *
    + *
  1. A numeric index into {@code window.frames} for the currently selected + * frame. + *
  2. A {@link webdriver.WebElement}, which must reference a FRAME or IFRAME + * element on the current page. + *
  3. A locator which may be used to first locate a FRAME or IFRAME on the + * current page before attempting to switch to it. + *
+ * + *

Upon successful resolution of this condition, the driver will be left + * focused on the new frame. + * + * @param {!(number|webdriver.WebElement| + * webdriver.Locator|webdriver.By.Hash| + * function(!webdriver.WebDriver): !webdriver.WebElement)} frame + * The frame identifier. + * @return {!until.Condition.} A new condition. + */ + function ableToSwitchToFrame(frame: number): webdriver.until.Condition; + function ableToSwitchToFrame(frame: webdriver.IWebElement): webdriver.until.Condition; + function ableToSwitchToFrame(frame: webdriver.Locator): webdriver.until.Condition; + function ableToSwitchToFrame(frame: (webdriver: webdriver.WebDriver) => webdriver.IWebElement): webdriver.until.Condition; + function ableToSwitchToFrame(frame: any): webdriver.until.Condition; + + /** + * Creates a condition that waits for an alert to be opened. Upon success, the + * returned promise will be fulfilled with the handle for the opened alert. + * + * @return {!until.Condition.} The new condition. + */ + function alertIsPresent(): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the given element to be disabled. + * + * @param {!webdriver.WebElement} element The element to test. + * @return {!until.Condition.} The new condition. + * @see webdriver.WebDriver#isEnabled + */ + function elementIsDisabled(element: webdriver.IWebElement): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the given element to be enabled. + * + * @param {!webdriver.WebElement} element The element to test. + * @return {!until.Condition.} The new condition. + * @see webdriver.WebDriver#isEnabled + */ + function elementIsEnabled(element: webdriver.IWebElement): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the given element to be deselected. + * + * @param {!webdriver.WebElement} element The element to test. + * @return {!until.Condition.} The new condition. + * @see webdriver.WebDriver#isSelected + */ + function elementIsNotSelected(element: webdriver.IWebElement): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the given element to be in the DOM, + * yet not visible to the user. + * + * @param {!webdriver.WebElement} element The element to test. + * @return {!until.Condition.} The new condition. + * @see webdriver.WebDriver#isDisplayed + */ + function elementIsNotVisible(element: webdriver.IWebElement): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the given element to be selected. + * @param {!webdriver.WebElement} element The element to test. + * @return {!until.Condition.} The new condition. + * @see webdriver.WebDriver#isSelected + */ + function elementIsSelected(element: webdriver.IWebElement): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the given element to become visible. + * + * @param {!webdriver.WebElement} element The element to test. + * @return {!until.Condition.} The new condition. + * @see webdriver.WebDriver#isDisplayed + */ + function elementIsVisible(element: webdriver.IWebElement): webdriver.until.Condition; + + /** + * Creates a condition that will loop until an element is + * {@link webdriver.WebDriver#findElement found} with the given locator. + * + * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The locator + * to use. + * @return {!until.Condition.} The new condition. + */ + function elementLocated(locator: webdriver.Locator): webdriver.until.Condition; + function elementLocated(locator: any): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the given element's + * {@link webdriver.WebDriver#getText visible text} to contain the given + * substring. + * + * @param {!webdriver.WebElement} element The element to test. + * @param {string} substr The substring to search for. + * @return {!until.Condition.} The new condition. + * @see webdriver.WebDriver#getText + */ + function elementTextContains(element: webdriver.IWebElement, substr: string): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the given element's + * {@link webdriver.WebDriver#getText visible text} to match the given + * {@code text} exactly. + * + * @param {!webdriver.WebElement} element The element to test. + * @param {string} text The expected text. + * @return {!until.Condition.} The new condition. + * @see webdriver.WebDriver#getText + */ + function elementTextIs(element: webdriver.IWebElement, text: string): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the given element's + * {@link webdriver.WebDriver#getText visible text} to match a regular + * expression. + * + * @param {!webdriver.WebElement} element The element to test. + * @param {!RegExp} regex The regular expression to test against. + * @return {!until.Condition.} The new condition. + * @see webdriver.WebDriver#getText + */ + function elementTextMatches(element: webdriver.IWebElement, regex: RegExp): webdriver.until.Condition; + + /** + * Creates a condition that will loop until at least one element is + * {@link webdriver.WebDriver#findElement found} with the given locator. + * + * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The locator + * to use. + * @return {!until.Condition.>} The new + * condition. + */ + function elementsLocated(locator: webdriver.Locator): webdriver.until.Condition; + function elementsLocated(locator: any): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the given element to become stale. An + * element is considered stale once it is removed from the DOM, or a new page + * has loaded. + * + * @param {!webdriver.WebElement} element The element that should become stale. + * @return {!until.Condition.} The new condition. + */ + function stalenessOf(element: webdriver.IWebElement): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the current page's title to contain + * the given substring. + * + * @param {string} substr The substring that should be present in the page + * title. + * @return {!until.Condition.} The new condition. + */ + function titleContains(substr: string): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the current page's title to match the + * given value. + * + * @param {string} title The expected page title. + * @return {!until.Condition.} The new condition. + */ + function titleIs(title: string): webdriver.until.Condition; + + /** + * Creates a condition that will wait for the current page's title to match the + * given regular expression. + * + * @param {!RegExp} regex The regular expression to test against. + * @return {!until.Condition.} The new condition. + */ + function titleMatches(regex: RegExp): webdriver.until.Condition; } //endregion - /** - * Use as: element(locator) - * - * The ElementFinder can be treated as a WebElement for most purposes, in - * particular, you may perform actions (i.e. click, getText) on them as you - * would a WebElement. ElementFinders extend Promise, and once an action - * is performed on an ElementFinder, the latest result from the chain can be - * accessed using then. Unlike a WebElement, an ElementFinder will wait for - * angular to settle before performing finds or actions. - * - * ElementFinder can be used to build a chain of locators that is used to find - * an element. An ElementFinder does not actually attempt to find the element - * until an action is called, which means they can be set up in helper files - * before the page is available. - * - * @param {webdriver.Locator} locator An element locator. - * @return {ElementFinder} - */ + + /** + * Use as: element(locator) + * + * The ElementFinder can be treated as a WebElement for most purposes, in + * particular, you may perform actions (i.e. click, getText) on them as you + * would a WebElement. ElementFinders extend Promise, and once an action + * is performed on an ElementFinder, the latest result from the chain can be + * accessed using then. Unlike a WebElement, an ElementFinder will wait for + * angular to settle before performing finds or actions. + * + * ElementFinder can be used to build a chain of locators that is used to find + * an element. An ElementFinder does not actually attempt to find the element + * until an action is called, which means they can be set up in helper files + * before the page is available. + * + * @param {webdriver.Locator} locator An element locator. + * @return {ElementFinder} + */ interface Element { (locator: webdriver.Locator): ElementFinder; @@ -240,115 +534,605 @@ declare module protractor { all(locator: webdriver.Locator): ElementArrayFinder; } - interface ElementFinder { + interface ElementFinder extends webdriver.IWebElement, webdriver.promise.IThenable { /** - * Use as: element(locator).element(locator) - * Calls to element may be chained to find elements within a parent. - * - * @param {webdriver.Locator} locator The locator that will be used to find descendents. - * - * @return {protractor.ElementFinder} The descendent element found by the locator - */ - element(locator: webdriver.Locator): protractor.ElementFinder; + * Calls to element may be chained to find elements within a parent. + * + * @alias element(locator).element(locator) + * @view + *

+ *
+ * Child text + *
{{person.phone}}
+ *
+ *
+ * + * @example + * // Chain 2 element calls. + * var child = element(by.css('.parent')). + * element(by.css('.child')); + * expect(child.getText()).toBe('Child text\n555-123-4567'); + * + * // Chain 3 element calls. + * var triple = element(by.css('.parent')). + * element(by.css('.child')). + * element(by.binding('person.phone')); + * expect(triple.getText()).toBe('555-123-4567'); + * + * @param {webdriver.Locator} subLocator + * @return {ElementFinder} + */ + element(subLocator: webdriver.Locator): ElementFinder; + + /** + * Calls to element may be chained to find an array of elements within a parent. + * + * @alias element(locator).all(locator) + * @view + *
+ *
    + *
  • First
  • + *
  • Second
  • + *
  • Third
  • + *
+ *
+ * + * @example + * var items = element(by.css('.parent')).all(by.tagName('li')) + * + * @param {webdriver.Locator} subLocator + * @return {ElementArrayFinder} + */ + all(subLocator: webdriver.Locator): ElementArrayFinder; /** - * Use as: element(locator).all(locator) - * Calls to element may be chained to find an array of elements within a parent. - * - * @param {webdriver.Locator} locator The locator that will be used to find descendents. - * - * @return {protractor.ElementArrayFinder} The descendent elements found by the locator - */ - all(locator: webdriver.Locator): protractor.ElementArrayFinder; + * Shortcut for querying the document directly with css. + * + * @alias $(cssSelector) + * @view + *
+ * First + * Second + *
+ * + * @example + * var item = $('.count .two'); + * expect(item.getText()).toBe('Second'); + * + * @param {string} selector A css selector + * @return {ElementFinder} which identifies the located + * {@link webdriver.WebElement} + */ + $(selector: string): ElementFinder; /** - * Shortcut for querying the document directly with css. - * - * @param {string} selector a css selector - * @see webdriver.WebElement.findElement - * @return {!protractor.WebElement} - */ - $(selector: string): protractor.WebElement; + * Shortcut for querying the document directly with css. + * + * @alias $$(cssSelector) + * @view + *
+ * First + * Second + *
+ * + * @example + * // The following protractor expressions are equivalent. + * var list = element.all(by.css('.count span')); + * expect(list.count()).toBe(2); + * + * list = $$('.count span'); + * expect(list.count()).toBe(2); + * expect(list.get(0).getText()).toBe('First'); + * expect(list.get(1).getText()).toBe('Second'); + * + * @param {string} selector a css selector + * @return {ElementArrayFinder} which identifies the + * array of the located {@link webdriver.WebElement}s. + */ + $$(selector: string): ElementArrayFinder; /** - * Shortcut for querying the document directly with css. - * - * @param {string} selector a css selector - * @see webdriver.WebElement.findElements - * @return {!webdriver.promise.Promise} A promise that will be resolved to an - * array of the located {@link webdriver.WebElement}s. - */ - $$(selector: string): webdriver.promise.Promise; + * Determine whether the element is present on the page. + * + * @view + * {{person.name}} + * + * @example + * // Element exists. + * expect(element(by.binding('person.name')).isPresent()).toBe(true); + * + * // Element not present. + * expect(element(by.binding('notPresent')).isPresent()).toBe(false); + * + * @return {ElementFinder} which resolves to whether + * the element is present on the page. + */ + isPresent(): webdriver.promise.Promise; /** - * Use as: element(locator).isPresent() - * Determine whether the element is present on the page. - * - * @return {protractor.ElementFinder} Which resolves to whether the element is present on the page. - */ - isPresent(): webdriver.promise.Promise; + * Override for WebElement.prototype.isElementPresent so that protractor waits + * for Angular to settle before making the check. + * + * @see ElementFinder.isPresent + * + * @param {webdriver.Locator} subLocator Locator for element to look for. + * @return {ElementFinder} which resolves to whether + * the element is present on the page. + */ + isElementPresent(subLocator: webdriver.Locator): webdriver.promise.Promise; /** - * Override for WebElement.prototype.isElementPresent so that protractor waits - * for Angular to settle before making the check. - * - * @see ElementFinder.isPresent - * @return {!webdriver.promise.Promise} which resolves to whether the element is present on the page. - */ - isElementPresent(locator: webdriver.Locator): webdriver.promise.Promise; - - /** - * Return this ElementFinder's locator. - * - * @return {webdriver.Locator} - */ + * @see ElementArrayFinder.prototype.locator + * + * @return {webdriver.Locator} + */ locator(): webdriver.Locator; /** - * Use as: element(locator).getWebElement() - * Returns the WebElement represented by this ElementFinder. - * Throws the WebDriver error if the element doesn't exist. - * If index is null, it makes sure that there is only one underlying WebElement - * described by the chain of locators and issues a warning otherwise. - * If index is not null, it retrieves the WebElement specified by the index.. - * @return {webdriver.WebElement} The WebElement represented by the ElementFinder. - */ + * Returns the WebElement represented by this ElementFinder. + * Throws the WebDriver error if the element doesn't exist. + * + * @example + * The following three expressions are equivalent. + * element(by.css('.parent')).getWebElement(); + * browser.waitForAngular(); browser.driver.findElement(by.css('.parent')); + * browser.findElement(by.css('.parent')); + * + * @alias element(locator).getWebElement() + * @return {webdriver.WebElement} + */ getWebElement(): webdriver.WebElement; /** - * Evalates the input as if it were on the scope of the current element. + * Evaluates the input as if it were on the scope of the current element. + * @see ElementArrayFinder.evaluate + * + * @param {string} expression + * + * @return {ElementFinder} which resolves to the evaluated expression. + */ + evaluate(expression: string): ElementFinder; + + /** + * @see ElementArrayFinder.prototype.allowAnimations. + * @param {string} value + * + * @return {ElementFinder} which resolves to whether animation is allowed. + */ + allowAnimations(value: string): ElementFinder; + + /** + * Cancels the computation of this promise's value, rejecting the promise in the + * process. This method is a no-op if the promise has alreayd been resolved. + * + * @param {string=} opt_reason The reason this promise is being cancelled. + */ + cancel(opt_reason?: string): void; + + + /** @return {boolean} Whether this promise's value is still being computed. */ + isPending(): boolean; + + + /** + * Registers listeners for when this instance is resolved. + * + * @param {?(function(T): (R|webdriver.promise.Promise.))=} opt_callback The + * function to call if this promise is successfully resolved. The function + * should expect a single argument: the promise's resolved value. + * @param {?(function(*): (R|webdriver.promise.Promise.))=} opt_errback The + * function to call if this promise is rejected. The function should expect + * a single argument: the rejection reason. + * @return {!webdriver.promise.Promise.} A new promise which will be + * resolved with the result of the invoked callback. + * @template R + */ + then(opt_callback?: (value: ElementFinder) => any, opt_errback?: (error: any) => any): webdriver.promise.Promise; + + + /** + * Registers a listener for when this promise is rejected. This is synonymous + * with the {@code catch} clause in a synchronous API: + *

+         *   // Synchronous API:
+         *   try {
+         *     doSynchronousWork();
+         *   } catch (ex) {
+         *     console.error(ex);
+         *   }
+         *
+         *   // Asynchronous promise API:
+         *   doAsynchronousWork().thenCatch(function(ex) {
+         *     console.error(ex);
+         *   });
+         * 
+ * + * @param {function(*): (R|webdriver.promise.Promise.)} errback The function + * to call if this promise is rejected. The function should expect a single + * argument: the rejection reason. + * @return {!webdriver.promise.Promise.} A new promise which will be + * resolved with the result of the invoked callback. + * @template R + */ + thenCatch(errback: (error: any) => any): webdriver.promise.Promise; + + + /** + * Registers a listener to invoke when this promise is resolved, regardless + * of whether the promise's value was successfully computed. This function + * is synonymous with the {@code finally} clause in a synchronous API: + *

+         *   // Synchronous API:
+         *   try {
+         *     doSynchronousWork();
+         *   } finally {
+         *     cleanUp();
+         *   }
+         *
+         *   // Asynchronous promise API:
+         *   doAsynchronousWork().thenFinally(cleanUp);
+         * 
+ * + * Note: similar to the {@code finally} clause, if the registered + * callback returns a rejected promise or throws an error, it will silently + * replace the rejection error (if any) from this promise: + *

+         *   try {
+         *     throw Error('one');
+         *   } finally {
+         *     throw Error('two');  // Hides Error: one
+         *   }
+         *
+         *   webdriver.promise.rejected(Error('one'))
+         *       .thenFinally(function() {
+         *         throw Error('two');  // Hides Error: one
+         *       });
+         * 
+ * + * + * @param {function(): (R|webdriver.promise.Promise.)} callback The function + * to call when this promise is resolved. + * @return {!webdriver.promise.Promise.} A promise that will be fulfilled + * with the callback result. + * @template R + */ + thenFinally(callback: () => any): webdriver.promise.Promise; + + /** + * Create a shallow copy of ElementFinder. + * + * @return {!ElementFinder} A shallow copy of this. + */ + clone(): ElementFinder; + } + + interface ElementArrayFinder extends webdriver.promise.IThenable { + /** + * Returns the elements as an array of WebElements. + */ + getWebElements(): webdriver.WebElement[]; + + + /** + * Get an element within the ElementArrayFinder by index. The index starts at 0. + * Negative indices are wrapped (i.e. -i means ith element from last) + * This does not actually retrieve the underlying element. + * + * @alias element.all(locator).get(index) + * @view + *
    + *
  • First
  • + *
  • Second
  • + *
  • Third
  • + *
+ * + * @example + * var list = element.all(by.css('.items li')); + * expect(list.get(0).getText()).toBe('First'); + * expect(list.get(1).getText()).toBe('Second'); + * + * @param {number} index Element index. + * @return {ElementFinder} finder representing element at the given index. + */ + get(index: number): ElementFinder; + + /** + * Get the first matching element for the ElementArrayFinder. This does not + * actually retrieve the underlying element. + * + * @alias element.all(locator).first() + * @view + *
    + *
  • First
  • + *
  • Second
  • + *
  • Third
  • + *
+ * + * @example + * var first = element.all(by.css('.items li')).first(); + * expect(first.getText()).toBe('First'); + * + * @return {ElementFinder} finder representing the first matching element + */ + first(): ElementFinder; + + /** + * Get the last matching element for the ElementArrayFinder. This does not + * actually retrieve the underlying element. + * + * @alias element.all(locator).last() + * @view + *
    + *
  • First
  • + *
  • Second
  • + *
  • Third
  • + *
+ * + * @example + * var last = element.all(by.css('.items li')).last(); + * expect(last.getText()).toBe('Third'); + * + * @return {ElementFinder} finder representing the last matching element + */ + last(): ElementFinder; + + /** + * Count the number of elements represented by the ElementArrayFinder. + * + * @alias element.all(locator).count() + * @view + *
    + *
  • First
  • + *
  • Second
  • + *
  • Third
  • + *
+ * + * @example + * var list = element.all(by.css('.items li')); + * expect(list.count()).toBe(3); + * + * @return {!webdriver.promise.Promise} A promise which resolves to the + * number of elements matching the locator. + */ + count(): webdriver.promise.Promise; + + /** + * Calls the input function on each ElementFinder represented by the ElementArrayFinder. + * + * @alias element.all(locator).each(eachFunction) + * @view + *
    + *
  • First
  • + *
  • Second
  • + *
  • Third
  • + *
+ * + * @example + * element.all(by.css('.items li')).each(function(element) { + * // Will print First, Second, Third. + * element.getText().then(console.log); + * }); + * + * @param {function(ElementFinder)} fn Input function + */ + each(fn: (element: ElementFinder, index: number) => void): void; + + /** + * Apply a map function to each element within the ElementArrayFinder. The + * callback receives the ElementFinder as the first argument and the index as + * a second arg. + * + * @alias element.all(locator).map(mapFunction) + * @view + *
    + *
  • First
  • + *
  • Second
  • + *
  • Third
  • + *
+ * + * @example + * var items = element.all(by.css('.items li')).map(function(elm, index) { + * return { + * index: index, + * text: elm.getText(), + * class: elm.getAttribute('class') + * }; + * }); + * expect(items).toEqual([ + * {index: 0, text: 'First', class: 'one'}, + * {index: 1, text: 'Second', class: 'two'}, + * {index: 2, text: 'Third', class: 'three'} + * ]); + * + * @param {function(ElementFinder, number)} mapFn Map function that + * will be applied to each element. + * @return {!webdriver.promise.Promise} A promise that resolves to an array + * of values returned by the map function. + */ + map(mapFn: (element: ElementFinder, index: number) => T): webdriver.promise.Promise; + + /** + * Apply a filter function to each element within the ElementArrayFinder. Returns + * a new ElementArrayFinder with all elements that pass the filter function. The + * filter function receives the ElementFinder as the first argument + * and the index as a second arg. + * This does not actually retrieve the underlying list of elements, so it can + * be used in page objects. + * + * @alias element.all(locator).filter(filterFn) + * @view + *
    + *
  • First
  • + *
  • Second
  • + *
  • Third
  • + *
+ * + * @example + * element.all(by.css('.items li')).filter(function(elem, index) { + * return elem.getText().then(function(text) { + * return text === 'Third'; + * }); + * }).then(function(filteredElements) { + * filteredElements[0].click(); + * }); + * + * @param {function(ElementFinder, number): webdriver.WebElement.Promise} filterFn + * Filter function that will test if an element should be returned. + * filterFn can either return a boolean or a promise that resolves to a boolean. + * @return {!ElementArrayFinder} A ElementArrayFinder that represents an array + * of element that satisfy the filter function. + */ + filter(filterFn: (element: ElementFinder, index: number) => any): ElementArrayFinder; + + /** + * Apply a reduce function against an accumulator and every element found + * using the locator (from left-to-right). The reduce function has to reduce + * every element into a single value (the accumulator). Returns promise of + * the accumulator. The reduce function receives the accumulator, current + * ElementFinder, the index, and the entire array of ElementFinders, + * respectively. + * + * @alias element.all(locator).reduce(reduceFn) + * @view + *
    + *
  • First
  • + *
  • Second
  • + *
  • Third
  • + *
+ * + * @example + * var value = element.all(by.css('.items li')).reduce(function(acc, elem) { + * return elem.getText().then(function(text) { + * return acc + text + ' '; + * }); + * }); + * + * expect(value).toEqual('First Second Third '); + * + * @param {function(number, ElementFinder, number, Array.)} + * reduceFn Reduce function that reduces every element into a single value. + * @param {*} initialValue Initial value of the accumulator. + * @return {!webdriver.promise.Promise} A promise that resolves to the final + * value of the accumulator. + */ + reduce(reduceFn: (acc: T, element: ElementFinder, index: number, arr: ElementFinder[]) => T, initialValue: T): webdriver.promise.Promise; + + /** + * Represents the ElementArrayFinder as an array of ElementFinders. + * + * @return {Array.} Return a promise, which resolves to a list + * of ElementFinders specified by the locator. + */ + asElementFinders_(): ElementFinder[]; + + /** + * Create a shallow copy of ElementArrayFinder. + * + * @return {!ElementArrayFinder} A shallow copy of this. + */ + clone(): ElementArrayFinder; + + /** + * Calls to ElementArrayFinder may be chained to find an array of elements + * using the current elements in this ElementArrayFinder as the starting point. + * This function returns a new ElementArrayFinder which would contain the + * children elements found (and could also be empty). + * + * @alias element.all(locator).all(locator) + * @view + *
+ *
    + *
  • 1a
  • + *
  • 1b
  • + *
+ *
+ *
+ *
    + *
  • 2a
  • + *
  • 2b
  • + *
+ *
+ * + * @example + * var foo = element.all(by.css('.parent')).all(by.css('.foo')) + * expect(foo.getText()).toEqual(['1a', '2a']) + * var baz = element.all(by.css('.parent')).all(by.css('.baz')) + * expect(baz.getText()).toEqual(['1b']) + * var nonexistent = element.all(by.css('.parent')).all(by.css('.NONEXISTENT')) + * expect(nonexistent.getText()).toEqual(['']) + * + * @param {webdriver.Locator} subLocator + * @return {ElementArrayFinder} + */ + all(locator: webdriver.Locator): ElementArrayFinder; + + /** + * Shorthand function for finding arrays of elements by css. + * + * @type {function(string): ElementArrayFinder} + */ + $$(selector: string): ElementArrayFinder; + + /** + * Returns an ElementFinder representation of ElementArrayFinder. It ensures + * that the ElementArrayFinder resolves to one and only one underlying element. + * + * @return {ElementFinder} An ElementFinder representation + * @private + */ + toElementFinder_(): ElementFinder; + + /** + * Returns the most relevant locator. + * + * @example + * $('#ID1').locator() // returns by.css('#ID1') + * $('#ID1').$('#ID2').locator() // returns by.css('#ID2') + * $$('#ID1').filter(filterFn).get(0).click().locator() // returns by.css('#ID1') + * + * @return {webdriver.Locator} + */ + locator(): webdriver.Locator; + + /** + * Evaluates the input as if it were on the scope of the current underlying + * elements. + * + * @view + * {{variableInScope}} + * + * @example + * var value = element(by.id('foo')).evaluate('variableInScope'); + * * @param {string} expression * - * @return {!webdriver.promise.Promise} A promise that will resolve to the - * evaluated expression. The result will be resolved as in + * @return {ElementArrayFinder} which resolves to the + * evaluated expression for each underlying element. + * The result will be resolved as in * {@link webdriver.WebDriver.executeScript}. In summary - primitives will * be resolved as is, functions will be converted to string, and elements * will be returned as a WebElement. */ - evaluate(expression: string): webdriver.promise.Promise; + evaluate(expression: string): ElementArrayFinder; /** - * Determine if animation is allowed on the current element. + * Determine if animation is allowed on the current underlying elements. * @param {string} value * - * @return {ElementFinder} which resolves to whether animation is allowed. - */ - allowAnimations(value: string): webdriver.promise.Promise; - - /** - * Access the underlying actionResult of ElementFinder. Implementation allows ElementFinder to be used as a webdriver.promise.Promise. - * @param {function(webdriver.promise.Promise)} fn Function which takes the value of the underlying actionResult. + * @example + * // Turns off ng-animate animations for all elements in the + * element(by.css('body')).allowAnimations(false); * - * @return {webdriver.promise.Promise} Promise which contains the results of evaluating fn. + * @return {ElementArrayFinder} which resolves to whether animation is allowed. */ - then(fn: IThenFunction): webdriver.promise.Promise; + allowAnimations(value: boolean): ElementArrayFinder; /** * Schedules a command to click on this element. * @return {!webdriver.promise.Promise} A promise that will be resolved when * the click command has completed. */ - click(): webdriver.promise.Promise; + click(): webdriver.promise.Promise; /** * Schedules a command to type a sequence on the DOM element represented by this @@ -390,14 +1174,14 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise that will be resolved when all * keys have been typed. */ - sendKeys(...var_args: string[]): webdriver.promise.Promise; + sendKeys(...var_args: string[]): webdriver.promise.Promise; /** * Schedules a command to query for the tag/node name of this element. * @return {!webdriver.promise.Promise} A promise that will be resolved with the * element's tag name. */ - getTagName(): webdriver.promise.Promise; + getTagName(): webdriver.promise.Promise; /** * Schedules a command to query for the computed style of the element @@ -414,7 +1198,7 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise that will be resolved with the * requested CSS value. */ - getCssValue(cssStyleProperty: string): webdriver.promise.Promise; + getCssValue(cssStyleProperty: string): webdriver.promise.Promise; /** * Schedules a command to query for the value of the given attribute of the @@ -443,7 +1227,7 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise that will be resolved with the * attribute's value. */ - getAttribute(attributeName: string): webdriver.promise.Promise; + getAttribute(attributeName: string): webdriver.promise.Promise; /** * Get the visible (i.e. not hidden by CSS) innerText of this element, including @@ -451,7 +1235,7 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise that will be resolved with the * element's visible text. */ - getText(): webdriver.promise.Promise; + getText(): webdriver.promise.Promise; /** * Schedules a command to compute the size of this element's bounding box, in @@ -459,14 +1243,14 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise that will be resolved with the * element's size as a {@code {width:number, height:number}} object. */ - getSize(): webdriver.promise.Promise; + getSize(): webdriver.promise.Promise; /** * Schedules a command to compute the location of this element in page space. * @return {!webdriver.promise.Promise} A promise that will be resolved to the * element's location as a {@code {x:number, y:number}} object. */ - getLocation(): webdriver.promise.Promise; + getLocation(): webdriver.promise.Promise; /** * Schedules a command to query whether the DOM element represented by this @@ -474,14 +1258,14 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise that will be resolved with * whether this element is currently enabled. */ - isEnabled(): webdriver.promise.Promise; + isEnabled(): webdriver.promise.Promise; /** * Schedules a command to query whether this element is selected. * @return {!webdriver.promise.Promise} A promise that will be resolved with * whether this element is currently selected. */ - isSelected(): webdriver.promise.Promise; + isSelected(): webdriver.promise.Promise; /** * Schedules a command to submit the form containing this element (or this @@ -490,7 +1274,7 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise that will be resolved when * the form has been submitted. */ - submit(): webdriver.promise.Promise; + submit(): webdriver.promise.Promise; /** * Schedules a command to clear the {@code value} of this element. This command @@ -499,276 +1283,173 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise that will be resolved when * the element has been cleared. */ - clear(): webdriver.promise.Promise; + clear(): webdriver.promise.Promise; /** * Schedules a command to test whether this element is currently displayed. * @return {!webdriver.promise.Promise} A promise that will be resolved with * whether this element is currently visible on the page. */ - isDisplayed(): webdriver.promise.Promise; + isDisplayed(): webdriver.promise.Promise; /** * Schedules a command to retrieve the outer HTML of this element. * @return {!webdriver.promise.Promise} A promise that will be resolved with * the element's outer HTML. */ - getOuterHtml(): webdriver.promise.Promise; + getOuterHtml(): webdriver.promise.Promise; + + /** + * @return {!webdriver.promise.Promise.} A promise + * that resolves to this element's JSON representation as defined by the + * WebDriver wire protocol. + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol + */ + getId(): webdriver.promise.Promise /** * Schedules a command to retrieve the inner HTML of this element. * @return {!webdriver.promise.Promise} A promise that will be resolved with the * element's inner HTML. */ - getInnerHtml(): webdriver.promise.Promise; - - /** - * @return {!webdriver.promise.Promise.} A promise - * that resolves to this element's JSON representation as defined by the - * WebDriver wire protocol. - * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol - */ - toWireValue(): webdriver.promise.Promise; + getInnerHtml(): webdriver.promise.Promise; } - interface IThenFunction { - (promiseResult: any): any; - } - - - interface ElementArrayFinder { - /** - * Use as: element.all(locator).getWebElements() - * Returns the array of WebElements represented by this ElementArrayFinder. - * - * @return {Array.} Array of WebElements represented by this ElementArrayFinder - */ - getWebElements(): webdriver.WebElement[]; - - /** - * Use as: element.all(locator).get(index) - * Get an element found by the locator by index. The index starts at 0. This does not actually retrieve the underlying element. - * - * @param {number} index Element index. - * - * @return {protractor.ElementFinder} Finder representing element at the given index - */ - get(index: number): protractor.ElementFinder; - - - /** - * Use as: element.all(locator).first() - * Get the first matching element for the locator. This does not actually retrieve the underlying element. - * - * @return {Protractor.ElementFinder} Finder representing the first matching element - */ - first(): protractor.ElementFinder; - - /** - * Use as: element.all(locator).last() - * Get the last matching element for the locator. This does not actually retrieve the underlying element. - * - * @return {Protractor.ElementFinder} Finder representing the last matching element - */ - last(): protractor.ElementFinder; - - /** - * Use as: element.all(locator).getWebElements() - * Returns the array of WebElements represented by this ElementArrayFinder. - * - * @return {!webdriver.promise.Promise} The array of WebElements represented by this ElementArrayFinder - */ - count(): webdriver.promise.Promise; - - /** - * Use as: element.all(locator).each(eachFunction) - * Calls the input function on each ElementFinder found by the locator. - * - * @param {function(ElementFinder)} fn Input function. - */ - each(fn: IEachFunction): void; - - /** - * Use as: element.all(locator).map(mapFunction) - * Apply a map function to each element found using the locator. The callback receives the ElementFinder as the first argument and the index as a second arg. - * - * @param {function(ElementFinder, number)} mapFn Map function that will be applied to each element. - * - * @return {!webdriver.promise.Promise} A promise that resolves to an array of values returned by the map function. - */ - map(mapFn: IMapFunction): webdriver.promise.Promise; - - /** - * Use as: element.all(locator).filter(filterFn) - * Apply a filter function to each element found using the locator. Returns promise of a new array with all elements that pass the filter function. The filter function receives the ElementFinder as the first argument and the index as a second arg. - * - * @param {function(ElementFinder, number): webdriver.promise.Promise} filterFn Filter function that will test if an element should be returned. filterFn should return a promise that resolves to a boolean. - * - * @return {!webdriver.promise.Promise} A promise that resolves to an array of ElementFinders that satisfy the filter function. - */ - filter(func: IFilterFunction): webdriver.promise.Promise; - - /** - * Use as: element.all(locator).reduce(reduceFn) - * Apply a reduce function against an accumulator and every element found using the locator (from left-to-right). - * The reduce function has to reduce every element into a single value (the accumulator). - * Returns promise of the accumulator. - * The reduce function receives the accumulator, current ElementFinder, the index, and the entire array of ElementFinders, respectively. - * - * @param {function(number, ElementFinder, number, Array.): webdriver.promise.Promise} reduceFn Reduce function that reduces every element into a single value. - * @param {*} initialValue Initial value of the accumulator. - * - * @return {!webdriver.promise.Promise} A promise that resolves to the final value of the accumulator. - */ - reduce(func: IReductionFunction, initialValue: any): webdriver.promise.Promise; - - /** - * Represents the ElementArrayFinder as an array of ElementFinders. - * - * @return {!webdriver.promise.Promise} Return a promise, which resolves to a list (array) - * of ElementFinders specified by the locator. - */ - asElementFinders_(): webdriver.promise.Promise; - - - /** - * Find the elements specified by the locator. The input function is passed - * to the resulting promise, which resolves to an array of ElementFinders. - * - * Use as: element.all(locator).then(thenFunction) - *
    - *
  • First
  • - *
  • Second
  • - *
  • Third
  • - *
- * - * element.all(by.css('.items li')).then(function(arr) { - * expect(arr.length).toEqual(3); - * }); - * - * @param {function(Array.)} fn - * - * @type {webdriver.promise.Promise} a promise which will resolve to - * an array of ElementFinders matching the locator. - */ - then(fn: IElementArrayFinderThenFunction): webdriver.promise.Promise; - } - - interface IEachFunction { - (element: protractor.ElementFinder): void; - } - - interface IMapFunction { - (element: ElementFinder, index: number): any; - } - - interface IFilterFunction { - (element: ElementFinder, index: number): webdriver.promise.Promise; - } - - interface IReductionFunction { - (accumulator: any, element: protractor.ElementFinder, index?: number, array?: protractor.ElementFinder[]): webdriver.promise.Promise; - } - - interface IElementArrayFinderThenFunction { - (promiseResult: ElementFinder[]): any; - } - - class LocatorWithColumn extends webdriver.Locator { + interface LocatorWithColumn extends webdriver.Locator { column(index: number): webdriver.Locator; } - class RepeaterLocator extends LocatorWithColumn { + interface RepeaterLocator extends LocatorWithColumn { row(index: number): LocatorWithColumn; } interface IProtractorLocatorStrategy extends webdriver.ILocatorStrategy { /** * Add a locator to this instance of ProtractorBy. This locator can then be - * used with element(by.()). + * used with element(by.locatorName(args)). * - * @param {string} name - * @param {function|string} script A script to be run in the context of + * @view + * + * + * @example + * // Add the custom locator. + * by.addLocator('buttonTextSimple', + * function(buttonText, opt_parentElement, opt_rootSelector) { + * // This function will be serialized as a string and will execute in the + * // browser. The first argument is the text for the button. The second + * // argument is the parent element, if any. + * var using = opt_parentElement, + * buttons = using.querySelectorAll('button'); + * + * // Return an array of buttons with the text. + * return Array.prototype.filter.call(buttons, function(button) { + * return button.textContent === buttonText; + * }); + * }); + * + * // Use the custom locator. + * element(by.buttonTextSimple('Go!')).click(); + * + * @alias by.addLocator(locatorName, functionOrScript) + * @param {string} name The name of the new locator. + * @param {Function|string} script A script to be run in the context of * the browser. This script will be passed an array of arguments - * that begins with the element scoping the search, and then - * contains any args passed into the locator. It should return - * an array of elements. + * that contains any args passed into the locator followed by the + * element scoping the search and the css selector for the root angular + * element. It should return an array of elements. */ - addLocator(name: string, script: any): void; + addLocator(name: string, script: string): void; + addLocator(name: string, script: Function): void; /** - * Usage: - * {{status}} - * var status = element(by.binding('{{status}}')); + * Find an element by binding. + * + * @view + * {{person.name}} + * + * + * @example + * var span1 = element(by.binding('person.name')); + * expect(span1.getText()).toBe('Foo'); + * + * var span2 = element(by.binding('person.email')); + * expect(span2.getText()).toBe('foo@bar.com'); * * @param {string} bindingDescriptor - * @return {webdriver.Locator} + * @return {{findElementsOverride: findElementsOverride, toString: Function|string}} */ binding(bindingDescriptor: string): webdriver.Locator; /** * Find an element by exact binding. * + * @view * {{ person.name }} * * {{person_phone|uppercase}} * + * @example * expect(element(by.exactBinding('person.name')).isPresent()).toBe(true); * expect(element(by.exactBinding('person-email')).isPresent()).toBe(true); * expect(element(by.exactBinding('person')).isPresent()).toBe(false); * expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true); * expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(true); * expect(element(by.exactBinding('phone')).isPresent()).toBe(false); - * + * * @param {string} bindingDescriptor - * @return {webdriver.Locator} + * @return {{findElementsOverride: findElementsOverride, toString: Function|string}} */ exactBinding(bindingDescriptor: string): webdriver.Locator; /** - * * Find an element by ng-model expression. * - * Usage: - * - * var input = element(by.model('person.name')); - * input.sendKeys('123'); - * expect(input.getAttribute('value')).toBe('Foo123'); + * @alias by.model(modelName) + * @view + * + * + * @example + * var input = element(by.model('person.name')); + * input.sendKeys('123'); + * expect(input.getAttribute('value')).toBe('Foo123'); * * @param {string} model ng-model expression. - * @return {webdriver.Locator} */ model(model: string): webdriver.Locator; /** * Find a button by text. * - * Usage: - * - * element(by.buttonText('Save')); + * @view + * + * + * @example + * element(by.buttonText('Save')); * * @param {string} searchText - * @return {webdriver.Locator} + * @return {{findElementsOverride: findElementsOverride, toString: Function|string}} */ buttonText(searchText: string): webdriver.Locator; - /** * Find a button by partial text. * - * Usage: - * - * element(by.partialButtonText('Save')); + * @view + * + * + * @example + * element(by.partialButtonText('Save')); * * @param {string} searchText - * @return {webdriver.Locator} + * @return {{findElementsOverride: findElementsOverride, toString: Function|string}} */ partialButtonText(searchText: string): webdriver.Locator; + /** * Find elements inside an ng-repeat. * - * Usage: + * @view *
* {{cat.name}} * {{cat.age}} @@ -782,6 +1463,7 @@ declare module protractor { *

{{book.blurb}}

*
* + * @example * // Returns the DIV for the second cat. * var secondCat = element(by.repeater('cat in pets').row(1)); * @@ -829,98 +1511,111 @@ declare module protractor { * @example * // Returns the DIV for the dog, but not cat. * var dog = element(by.cssContainingText('.pet', 'Dog')); - * - * @param cssSelector {string} - * @param searchText {string} - * @return {webdriver.Locator} */ cssContainingText(cssSelector: string, searchText: string): webdriver.Locator; /** * Find an element by ng-options expression. * - * Usage: + * @alias by.options(optionsDescriptor) + * @view * * + * @example * var allOptions = element.all(by.options('c for c in colors')); * expect(allOptions.count()).toEqual(2); * var firstOption = allOptions.first(); * expect(firstOption.getText()).toEqual('red'); * * @param {string} optionsDescriptor ng-options expression. - * @return {webdriver.Locator} */ options(optionsDescriptor: string): webdriver.Locator; } var By: IProtractorLocatorStrategy; - class Protractor extends webdriver.WebDriver { - - //region Constructors + interface Protractor extends webdriver.WebDriver { /** - * @param {webdriver.WebDriver} webdriver - * @param {string=} opt_baseUrl A base URL to run get requests against. - * @param {string=body} opt_rootElement Selector element that has an ng-app in - * scope. - * @constructor - */ - constructor(webdriver: webdriver.WebDriver, opt_baseUrl?: string, opt_rootElement?: string); - - //endregion - - //region Properties - - /** - * The wrapped webdriver instance. Use this to interact with pages that do - * not contain Angular (such as a log-in screen). - * - * @type {webdriver.WebDriver} - */ + * The wrapped webdriver instance. Use this to interact with pages that do + * not contain Angular (such as a log-in screen). + * + * @type {webdriver.WebDriver} + */ driver: webdriver.WebDriver; /** - * All get methods will be resolved against this base URL. Relative URLs are = - * resolved the way anchor tags resolve. - * - * @type {string} - */ + * Helper function for finding elements. + * + * @type {function(webdriver.Locator): ElementFinder} + */ + element(locator: webdriver.Locator): ElementFinder; + + /** + * Shorthand function for finding elements by css. + * + * @type {function(string): ElementFinder} + */ + $(selector: string): ElementFinder; + + /** + * Shorthand function for finding arrays of elements by css. + * + * @type {function(string): ElementArrayFinder} + */ + $$(selector: string): ElementArrayFinder; + + /** + * All get methods will be resolved against this base URL. Relative URLs are = + * resolved the way anchor tags resolve. + * + * @type {string} + */ baseUrl: string; /** - * The css selector for an element on which to find Angular. This is usually - * 'body' but if your ng-app is on a subsection of the page it may be - * a subelement. - * - * @type {string} - */ + * The css selector for an element on which to find Angular. This is usually + * 'body' but if your ng-app is on a subsection of the page it may be + * a subelement. + * + * @type {string} + */ rootEl: string; /** - * If true, Protractor will not attempt to synchronize with the page before - * performing actions. This can be harmful because Protractor will not wait - * until $timeouts and $http calls have been processed, which can cause - * tests to become flaky. This should be used only when necessary, such as - * when a page continuously polls an API using $timeout. - * - * @type {boolean} - */ + * If true, Protractor will not attempt to synchronize with the page before + * performing actions. This can be harmful because Protractor will not wait + * until $timeouts and $http calls have been processed, which can cause + * tests to become flaky. This should be used only when necessary, such as + * when a page continuously polls an API using $timeout. + * + * @type {boolean} + */ ignoreSynchronization: boolean; /** - * An object that holds custom test parameters. - * - * @type {Object} - */ + * Timeout in milliseconds to wait for pages to load when calling `get`. + * + * @type {number} + */ + getPageTimeout: number; + + /** + * An object that holds custom test parameters. + * + * @type {Object} + */ params: any; - //endregion - - //region Methods + /** + * The reset URL to use between page loads. + * + * @type {string} + */ + resetUrl: string; /** * Instruct webdriver to wait until Angular has finished rendering and has @@ -929,56 +1624,7 @@ declare module protractor { * @return {!webdriver.promise.Promise} A promise that will resolve to the * scripts return value. */ - waitForAngular(): webdriver.promise.Promise; - - /** - * Waits for Angular to finish rendering before searching for elements. - * @see webdriver.WebDriver.findElement - * - * @param {webdriver.Locator} locator The locator used to find the element. - * @return {!webdriver.WebElement} - */ - findElement(locator: webdriver.Locator): protractor.WebElement; - - /** - * Waits for Angular to finish rendering before searching for elements. - * @see webdriver.WebDriver.findElements - * - * @param {webdriver.Locator} locator The locator used to find the elements. - * @return {!webdriver.promise.Promise} A promise that will be resolved to an - * array of the located {@link webdriver.WebElement}s. - */ - findElements(locator: webdriver.Locator): webdriver.promise.Promise; - - /** - * Tests if an element is present on the page. - * @see webdriver.WebDriver.isElementPresent - * @return {!webdriver.promise.Promise} A promise that will resolve to whether - * the element is present on the page. - */ - isElementPresent(locatorOrElement: webdriver.Locator): webdriver.promise.Promise; - isElementPresent(locatorOrElement: any): webdriver.promise.Promise; - - /** - * Helper function for finding elements. - * - * @type {function(webdriver.Locator): ElementFinder} - */ - element(locator: webdriver.Locator): ElementFinder; - - /** - * Helper function for finding elements by css. - * - * @type {function(string): ElementFinder} - */ - $(cssLocator: string): ElementFinder; - - /** - * Helper function for finding arrays of elements by css. - * - * @type {function(string): ElementArrayFinder} - */ - $$(cssLocator: string): ElementArrayFinder; + waitForAngular(): webdriver.promise.Promise; /** * Add a module to load before Angular whenever Protractor.get is called. @@ -986,13 +1632,18 @@ declare module protractor { * so any module registered here will override preexisting modules with the same * name. * - * @param {string} name The name of the module to load or override. - * @param {string|Function} script The JavaScript to load the module. + * @example + * browser.addMockModule('modName', function() { + * angular.module('modName', []).value('foo', 'bar'); + * }); + * + * @param {!string} name The name of the module to load or override. + * @param {!string|Function} script The JavaScript to load the module. * @param {...*} varArgs Any additional arguments will be provided to * the script and may be referenced using the `arguments` object. */ addMockModule(name: string, script: string, ...varArgs: any[]): void; - addMockModule(name: string, script: any, ...varArgs: any[]): void; + addMockModule(name: string, script: Function, ...varArgs: any[]): void; /** * Clear the list of registered mock modules. @@ -1001,12 +1652,16 @@ declare module protractor { /** * Remove a registered mock module. + * + * @example + * browser.removeMockModule('modName'); + * * @param {!string} name The name of the module to remove. */ removeMockModule(name: string): void; /** - * See webdriver.WebDriver.get + * @see webdriver.WebDriver.get * * Navigate to the given destination and loads mock modules before * Angular. Assumes that the page being loaded uses Angular. @@ -1014,9 +1669,10 @@ declare module protractor { * the wrapped webdriver directly. * * @param {string} destination Destination URL. - * @param {number=} opt_timeout Number of seconds to wait for Angular to start. + * @param {number=} opt_timeout Number of milliseconds to wait for Angular to + * start. */ - get(destination: string, opt_timeout?: number): webdriver.promise.Promise; + get(destination: string, opt_timeout?: number): webdriver.promise.Promise; /** * See webdriver.WebDriver.refresh @@ -1028,13 +1684,7 @@ declare module protractor { * * @param {number=} opt_timeout Number of seconds to wait for Angular to start. */ - refresh(opt_timeout?: number): void; - - /** - * Mixin navigation methods back into the navigation object so that - * they are invoked as before, i.e. driver.navigate().refresh() - */ - navigate(): webdriver.WebDriverNavigation; + refresh(opt_timeout?: number): webdriver.promise.Promise; /** * Browse to another page using in-page navigation. @@ -1043,12 +1693,12 @@ declare module protractor { * @returns {!webdriver.promise.Promise} A promise that will resolve once * page has been changed. */ - setLocation(url: string): webdriver.promise.Promise; + setLocation(url: string): webdriver.promise.Promise; /** * Returns the current absolute url from AngularJS. */ - getLocationAbsUrl(): webdriver.promise.Promise; + getLocationAbsUrl(): webdriver.promise.Promise; /** * Pauses the test and injects some helper functions into the browser, so that @@ -1057,6 +1707,7 @@ declare module protractor { * This should be used under node in debug mode, i.e. with * protractor debug * + * @example * While in the debugger, commands can be scheduled through webdriver by * entering the repl: * debug> repl @@ -1076,11 +1727,27 @@ declare module protractor { * point in the control flow. * Does not require changes to the command line (no need to add 'debug'). * - * @param {=number} opt_debugPort Optional port to use for the debugging process + * @example + * element(by.id('foo')).click(); + * browser.pause(); + * // Execution will stop before the next click action. + * element(by.id('bar')).click(); + * + * @param {number=} opt_debugPort Optional port to use for the debugging process */ pause(opt_debugPort?: number): void; + } - //endregion + // Interface for the global browser object. + interface IBrowser extends Protractor { + /** + * Fork another instance of protractor for use in interactive tests. + * + * @param {boolean} opt_useSameUrl Whether to navigate to current url on creation + * @param {boolean} opt_copyMockModules Whether to apply same mock modules on creation + * @return {Protractor} a protractor instance. + */ + forkNewDriverInstance(opt_useSameUrl?: boolean, opt_copyMockModules?: boolean): Protractor; } /** @@ -1091,19 +1758,6 @@ declare module protractor { * @return {Protractor} */ function wrapDriver(webdriver: webdriver.WebDriver, opt_baseUrl?: string, opt_rootElement?: string): Protractor; - - /** - * Set a singleton instance of protractor. - * @param {Protractor} ptor - */ - function setInstance(ptor: Protractor): void; - - /** - * Get the singleton instance. - * @return {Protractor} - */ - function getInstance(): Protractor; - } interface cssSelectorHelper { @@ -1114,8 +1768,9 @@ interface cssArraySelectorHelper { (cssLocator: string): protractor.ElementArrayFinder; } -declare var browser: protractor.Protractor; +declare var browser: protractor.IBrowser; declare var by: protractor.IProtractorLocatorStrategy; +declare var By: protractor.IProtractorLocatorStrategy; declare var element: protractor.Element; declare var $: cssSelectorHelper; declare var $$: cssArraySelectorHelper; diff --git a/angular-protractor/legacy/angular-protractor-1.0.0-rc4-tests.ts b/angular-protractor/legacy/angular-protractor-1.0.0-rc4-tests.ts new file mode 100644 index 000000000..e1394d10c --- /dev/null +++ b/angular-protractor/legacy/angular-protractor-1.0.0-rc4-tests.ts @@ -0,0 +1,280 @@ +/// + +function TestWebDriverExports() { + var abstractBuilder: protractor.AbstractBuilder = new protractor.AbstractBuilder(); + var baseAbstractBuilder: webdriver.AbstractBuilder = abstractBuilder; + + var button: protractor.Button = new protractor.Button(); + var baseButton: webdriver.Button = button; + + var key: string = protractor.Key.ADD; + var chord: string = protractor.Key.chord(protractor.Key.NUMPAD0, protractor.Key.NUMPAD1); + + var driver: protractor.WebDriver = new protractor.Builder(). + withCapabilities(protractor.Capabilities.chrome()). + build(); + var baseDriver: webdriver.WebDriver = driver; + + var action: protractor.ActionSequence = new protractor.ActionSequence(driver); + var baseAction: webdriver.ActionSequence = action; + + var alert: protractor.Alert = new protractor.Alert(driver, 'Message'); + var baseAlert: webdriver.Alert = alert; + + var unhandledAlertError: protractor.UnhandledAlertError = new protractor.UnhandledAlertError('Message', alert); + var baseUnhandledAlertError: webdriver.UnhandledAlertError = unhandledAlertError; + + var browser: string = protractor.Browser.ANDROID; + + var builder: protractor.Builder = new protractor.Builder(); + var baseBuilder: webdriver.Builder = builder; + + var capability: string = protractor.Capability.BROWSER_NAME; + + var capabilities: protractor.Capabilities = protractor.Capabilities.chrome(); + var baseCapabilities: webdriver.Capabilities = capabilities; + + var commandName: string = protractor.CommandName.CLICK_ELEMENT; + + var command: protractor.Command = new protractor.Command(protractor.CommandName.CLICK); + var baseCommand: webdriver.Command = command; + + var eventEmitter: protractor.EventEmitter = new protractor.EventEmitter(); + var baseEventEmitter: webdriver.EventEmitter = eventEmitter; + + var firefoxDomExecutor: protractor.FirefoxDomExecutor = new protractor.FirefoxDomExecutor(); + var baseFirefoxDomExecutor: webdriver.FirefoxDomExecutor = firefoxDomExecutor; + + var webElement: protractor.WebElement = new protractor.WebElement(driver, new protractor.promise.Promise()); + var baseWebElement: webdriver.WebElement = webElement; + + var locator: protractor.Locator = new protractor.Locator('id', 'ABC'); + var baseLocator: webdriver.Locator = locator; + + var session: protractor.Session = new protractor.Session('ABC', webdriver.Capabilities.android()); + var baseSession: webdriver.Session = session; + + locator = protractor.By.name('name'); + + // logging module + + var levelName: string = protractor.logging.LevelName.ALL; + var loggingType: string = protractor.logging.Type.CLIENT; + + var level: webdriver.logging.Level = protractor.logging.Level.ALL; + + var entry: protractor.logging.Entry = new protractor.logging.Entry(protractor.logging.Level.ALL, 'Message'); + var baseEntry: webdriver.logging.Entry = entry; + + level = protractor.logging.getLevel('DEBUG'); + + protractor.logging.Preferences = { a: 123 }; + + // promise module + + var promise: protractor.promise.Promise = new protractor.promise.Promise(); + var basePromise: webdriver.promise.Promise = promise; + + var deferred: protractor.promise.Deferred = new protractor.promise.Deferred(); + var baseDeferred: webdriver.promise.Deferred = deferred; + + var flow: protractor.promise.ControlFlow = new protractor.promise.ControlFlow(); + var baseFlow: webdriver.promise.ControlFlow = flow; + + protractor.promise.asap(promise, function(value: any){ return true; }); + protractor.promise.asap(promise, function(value: any){}, function(err: any) { return 'ABC'; }); + + promise = protractor.promise.checkedNodeCall(function(err: any, value: any) { return 123; }); + + flow = protractor.promise.controlFlow(); + + promise = protractor.promise.createFlow(function(newFlow: webdriver.promise.ControlFlow) { }); + + deferred = protractor.promise.defer(function() {}); + deferred = protractor.promise.defer(function(reason?: any) {}); + + promise = protractor.promise.delayed(123); + + promise = protractor.promise.fulfilled(); + promise = protractor.promise.fulfilled({a: 123}); + + promise = protractor.promise.fullyResolved({a: 123}); + + var isPromise: boolean = protractor.promise.isPromise('ABC'); + + promise = protractor.promise.rejected({a: 123}); + + protractor.promise.setDefaultFlow(new webdriver.promise.ControlFlow()); + + promise = protractor.promise.when(promise, function(value: any) { return 123; }, function(err: Error) { return 123; }); + + // error module + + var errorCode: number = protractor.error.ErrorCode.ELEMENT_NOT_VISIBLE; + var error: protractor.error.Error = new protractor.error.Error(protractor.error.ErrorCode.ELEMENT_NOT_VISIBLE); + var baseError: webdriver.error.Error = error; + + // process module + + var isNative: boolean = protractor.process.isNative(); + var value: string; + + value = protractor.process.getEnv('name'); + value = protractor.process.getEnv('name', 'default'); + + protractor.process.setEnv('name', 'value'); + protractor.process.setEnv('name', 123); + +} + +function TestProtractor() { + var ptor: protractor.Protractor; + var driver: webdriver.WebDriver = new webdriver.Builder(). + withCapabilities(webdriver.Capabilities.chrome()). + build(); + + ptor = new protractor.Protractor(driver); + ptor = new protractor.Protractor(driver, 'baseUrl'); + ptor = new protractor.Protractor(driver, 'baseUrl', 'rootElement'); + ptor = protractor.getInstance(); + protractor.setInstance(ptor); + + ptor = protractor.wrapDriver(driver); + ptor = protractor.wrapDriver(driver, 'baseUrl'); + ptor = protractor.wrapDriver(driver, 'baseUrl', 'rootElement'); + + ptor = browser; + + driver = ptor.driver; + var baseUrl: string = ptor.baseUrl; + var rootEl: string = ptor.rootEl; + var ignoreSynchronization: boolean = ptor.ignoreSynchronization; + var params: any = ptor.params; + + ptor.debugger(); + + var webElement: protractor.WebElement = ptor.findElement(by.css('.class')); + var promise: webdriver.promise.Promise; + promise = ptor.findElements(by.css('.class')); + promise = ptor.isElementPresent(by.css('.class')); + promise = ptor.isElementPresent(webElement); + + ptor.clearMockModules(); + ptor.addMockModule('name', 'script'); + ptor.addMockModule('name', function() {}); + ptor.removeMockModule('name'); + ptor.waitForAngular(); + + var elementFinder: protractor.ElementFinder; + var elementArrayFinder: protractor.ElementArrayFinder; + + elementFinder = ptor.element(by.id('ABC')); + elementFinder = ptor.$('.class'); + + elementArrayFinder = ptor.$$('.class'); + + var locationAbsUrl: webdriver.promise.Promise = ptor.getLocationAbsUrl(); + ptor.setLocation('webaddress.com'); + + promise = ptor.get('webaddress.com'); + promise = ptor.get('webdaddress.com', 45); + ptor.refresh(); + ptor.refresh(45); + var navigation: webdriver.WebDriverNavigation = ptor.navigate(); + ptor.pause(); + ptor.pause(8080); +} + +function TestElement() { + var elementFinder: protractor.ElementFinder = element(by.id('id')); + var elementArrayFinder: protractor.ElementArrayFinder = element.all(by.className('class')); +} + +function TestElementFinder() { + var elementFinder: protractor.ElementFinder = element(by.id('id')); + var promise: webdriver.promise.Promise; + + promise = elementFinder.click(); + promise = elementFinder.allowAnimations('string'); + promise = elementFinder.sendKeys(protractor.Key.UP, protractor.Key.DOWN); + promise = elementFinder.getTagName(); + promise = elementFinder.getCssValue('display'); + promise = elementFinder.getAttribute('atribute'); + promise = elementFinder.getText(); + promise = elementFinder.getSize(); + promise = elementFinder.getLocation(); + promise = elementFinder.isEnabled(); + promise = elementFinder.isSelected(); + promise = elementFinder.submit(); + promise = elementFinder.clear(); + promise = elementFinder.isDisplayed(); + promise = elementFinder.getOuterHtml(); + promise = elementFinder.getInnerHtml(); + promise = elementFinder.isElementPresent(by.id('id')); + promise = elementFinder.$('.class'); + promise = elementFinder.$$('.class'); + promise = elementFinder.evaluate('expression'); + promise = elementFinder.isPresent(); + + var webElement: webdriver.WebElement; +} + +function TestElementArrayFinder() { + var elementArrayFinder: protractor.ElementArrayFinder = element.all(by.id('id')); + var promise: webdriver.promise.Promise; + var elementFinder: protractor.ElementFinder; + + var driverElementArray: webdriver.WebElement[] = elementArrayFinder.getWebElements(); + elementFinder = elementArrayFinder.get(42); + elementFinder = elementArrayFinder.first(); + elementFinder = elementArrayFinder.last(); + promise = elementArrayFinder.count(); + promise = elementArrayFinder.asElementFinders_(); + elementArrayFinder.each(function(element: protractor.ElementFinder){ + // nothing + }); + elementArrayFinder.map(function(element: protractor.ElementFinder, index: number){ + // nothing + }); + elementArrayFinder.filter(function(element: protractor.ElementFinder, index: number){ + return element.getText().then((text: string) => { + return text === "foo"; + }); + }); + elementArrayFinder.reduce(function(accumulator: string, element: protractor.ElementFinder){ + return element.getText().then((text: string) => { + return accumulator + ',' + text; + }); + }, ''); + elementArrayFinder.reduce(function(accumulator: string, element: protractor.ElementFinder, index: number, array: protractor.ElementFinder[]){ + return element.getText().then((text: string) => { + return accumulator + ',' + text; + }); + }, ''); + elementArrayFinder.then(function(underlyingElementFinders: protractor.ElementFinder[]){ + //nothing + }); +} + +// This function tests the angular specific locator strategies. +function TestLocatorStrategies() { + var ptor: protractor.Protractor = protractor.getInstance(); + var webElement: webdriver.WebElement; + + // Protractor Specific Locators + protractor.By.addLocator('customLocator', 'script'); + protractor.By.addLocator('customLocator2', function(){ + // nothing + }); + webElement = ptor.findElement(protractor.By.binding('binding')); + webElement = ptor.findElement(protractor.By.exactBinding('exactBinding')); + webElement = ptor.findElement(protractor.By.model('model')); + webElement = ptor.findElement(protractor.By.repeater('repeater')); + webElement = ptor.findElement(protractor.By.repeater('repeater').column(0)); + webElement = ptor.findElement(protractor.By.repeater('repeater').row(0)); + webElement = ptor.findElement(protractor.By.repeater('repeater').row(0).column(0)); + webElement = ptor.findElement(protractor.By.buttonText('buttonText')); + webElement = ptor.findElement(protractor.By.partialButtonText('partialButtonText')); + webElement = ptor.findElement(protractor.By.cssContainingText('cssSelector', 'search text')); + webElement = ptor.findElement(protractor.By.options('options')); +} diff --git a/angular-protractor/legacy/angular-protractor-1.0.0-rc4.d.ts b/angular-protractor/legacy/angular-protractor-1.0.0-rc4.d.ts new file mode 100644 index 000000000..5ec8dd09c --- /dev/null +++ b/angular-protractor/legacy/angular-protractor-1.0.0-rc4.d.ts @@ -0,0 +1,1125 @@ +// Type definitions for Angular Protractor 1.0.0-rc4 +// Project: https://github.com/angular/protractor +// Definitions by: Bill Armstrong +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +declare module protractor { + //region Wrapped webdriver Items + + class AbstractBuilder extends webdriver.AbstractBuilder {} + class ActionSequence extends webdriver.ActionSequence {} + class Alert extends webdriver.Alert {} + class Builder extends webdriver.Builder {} + class Button extends webdriver.Button {} + class Capabilities extends webdriver.Capabilities {} + class Command extends webdriver.Command {} + class EventEmitter extends webdriver.EventEmitter {} + class FirefoxDomExecutor extends webdriver.FirefoxDomExecutor {} + class Locator extends webdriver.Locator {} + class Session extends webdriver.Session {} + class WebDriver extends webdriver.WebDriver {} + class Browser extends webdriver.Browser {} + class Capability extends webdriver.Capability {} + class CommandName extends webdriver.CommandName {} + class Key extends webdriver.Key {} + class UnhandledAlertError extends webdriver.UnhandledAlertError {} + class WebElement extends webdriver.WebElement {} + + module command { + class Command extends webdriver.Command {} + class CommandName extends webdriver.CommandName {} + } + + module error { + class Error extends webdriver.error.Error {} + class ErrorCode extends webdriver.error.ErrorCode {} + } + + module events { + class EventEmitter extends webdriver.EventEmitter {} + } + + module logging { + var Preferences: any; + + class LevelName extends webdriver.logging.LevelName {} + class Type extends webdriver.logging.Type {} + class Level extends webdriver.logging.Level {} + class Entry extends webdriver.logging.Entry {} + + function getLevel(nameOrValue: string): webdriver.logging.Level; + function getLevel(nameOrValue: number): webdriver.logging.Level; + } + + module promise { + class Promise extends webdriver.promise.Promise {} + class Deferred extends webdriver.promise.Deferred {} + class ControlFlow extends webdriver.promise.ControlFlow {} + + /** + * @return {!webdriver.promise.ControlFlow} The currently active control flow. + */ + function controlFlow(): webdriver.promise.ControlFlow; + + /** + * Creates a new control flow. The provided callback will be invoked as the + * first task within the new flow, with the flow as its sole argument. Returns + * a promise that resolves to the callback result. + * @param {function(!webdriver.promise.ControlFlow)} callback The entry point + * to the newly created flow. + * @return {!webdriver.promise.Promise} A promise that resolves to the callback + * result. + */ + function createFlow(callback: (flow: webdriver.promise.ControlFlow) => any): webdriver.promise.Promise; + + /** + * Determines whether a {@code value} should be treated as a promise. + * Any object whose "then" property is a function will be considered a promise. + * + * @param {*} value The value to test. + * @return {boolean} Whether the value is a promise. + */ + function isPromise(value: any): boolean; + + /** + * Creates a promise that will be resolved at a set time in the future. + * @param {number} ms The amount of time, in milliseconds, to wait before + * resolving the promise. + * @return {!webdriver.promise.Promise} The promise. + */ + function delayed(ms: number): webdriver.promise.Promise; + + /** + * Creates a new deferred object. + * @param {Function=} opt_canceller Function to call when cancelling the + * computation of this instance's value. + * @return {!webdriver.promise.Deferred} The new deferred object. + */ + function defer(opt_canceller?: any): webdriver.promise.Deferred; + + /** + * Creates a promise that has been resolved with the given value. + * @param {*=} opt_value The resolved value. + * @return {!webdriver.promise.Promise} The resolved promise. + */ + function fulfilled(opt_value?: any): webdriver.promise.Promise; + + /** + * Creates a promise that has been rejected with the given reason. + * @param {*=} opt_reason The rejection reason; may be any value, but is + * usually an Error or a string. + * @return {!webdriver.promise.Promise} The rejected promise. + */ + function rejected(opt_reason?: any): webdriver.promise.Promise; + + /** + * Wraps a function that is assumed to be a node-style callback as its final + * argument. This callback takes two arguments: an error value (which will be + * null if the call succeeded), and the success value as the second argument. + * If the call fails, the returned promise will be rejected, otherwise it will + * be resolved with the result. + * @param {!Function} fn The function to wrap. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * result of the provided function's callback. + */ + function checkedNodeCall(fn: (error: any, value: any) => any): webdriver.promise.Promise; + + /** + * Registers an observer on a promised {@code value}, returning a new promise + * that will be resolved when the value is. If {@code value} is not a promise, + * then the return promise will be immediately resolved. + * @param {*} value The value to observe. + * @param {Function=} opt_callback The function to call when the value is + * resolved successfully. + * @param {Function=} opt_errback The function to call when the value is + * rejected. + * @return {!webdriver.promise.Promise} A new promise. + */ + function when(value: any, opt_callback?: (value: any) => any, opt_errback?: (error: any) => any): webdriver.promise.Promise; + + /** + * Invokes the appropriate callback function as soon as a promised + * {@code value} is resolved. This function is similar to + * {@code webdriver.promise.when}, except it does not return a new promise. + * @param {*} value The value to observe. + * @param {Function} callback The function to call when the value is + * resolved successfully. + * @param {Function=} opt_errback The function to call when the value is + * rejected. + */ + function asap(value: any, callback: (value: any) => any, opt_errback?: (error: any) => any): void; + + /** + * Returns a promise that will be resolved with the input value in a + * fully-resolved state. If the value is an array, each element will be fully + * resolved. Likewise, if the value is an object, all keys will be fully + * resolved. In both cases, all nested arrays and objects will also be + * fully resolved. All fields are resolved in place; the returned promise will + * resolve on {@code value} and not a copy. + * + * Warning: This function makes no checks against objects that contain + * cyclical references: + * + * var value = {}; + * value['self'] = value; + * webdriver.promise.fullyResolved(value); // Stack overflow. + * + * @param {*} value The value to fully resolve. + * @return {!webdriver.promise.Promise} A promise for a fully resolved version + * of the input value. + */ + function fullyResolved(value: any): webdriver.promise.Promise; + + /** + * Changes the default flow to use when no others are active. + * @param {!webdriver.promise.ControlFlow} flow The new default flow. + * @throws {Error} If the default flow is not currently active. + */ + function setDefaultFlow(flow: webdriver.promise.ControlFlow): void; + + } + + module process { + + /** + * Queries for a named environment variable. + * @param {string} name The name of the environment variable to look up. + * @param {string=} opt_default The default value if the named variable is not + * defined. + * @return {string} The queried environment variable. + */ + function getEnv(name: string, opt_default?: string): string; + + /** + * @return {boolean} Whether the current process is Node's native process + * object. + */ + function isNative(): boolean; + + /** + * Sets an environment value. If the new value is either null or undefined, the + * environment variable will be cleared. + * @param {string} name The value to set. + * @param {*} value The new value; will be coerced to a string. + */ + function setEnv(name: string, value: any): void; + + } + + //endregion + /** + * Use as: element(locator) + * + * The ElementFinder can be treated as a WebElement for most purposes, in + * particular, you may perform actions (i.e. click, getText) on them as you + * would a WebElement. ElementFinders extend Promise, and once an action + * is performed on an ElementFinder, the latest result from the chain can be + * accessed using then. Unlike a WebElement, an ElementFinder will wait for + * angular to settle before performing finds or actions. + * + * ElementFinder can be used to build a chain of locators that is used to find + * an element. An ElementFinder does not actually attempt to find the element + * until an action is called, which means they can be set up in helper files + * before the page is available. + * + * @param {webdriver.Locator} locator An element locator. + * @return {ElementFinder} + */ + interface Element { + (locator: webdriver.Locator): ElementFinder; + + /** + * ElementArrayFinder is used for operations on an array of elements (as opposed + * to a single element). + * + * @param {webdriver.Locator} locator An element locator. + * @return {ElementArrayFinder} + */ + all(locator: webdriver.Locator): ElementArrayFinder; + } + + interface ElementFinder { + /** + * Use as: element(locator).element(locator) + * Calls to element may be chained to find elements within a parent. + * + * @param {webdriver.Locator} locator The locator that will be used to find descendents. + * + * @return {protractor.ElementFinder} The descendent element found by the locator + */ + element(locator: webdriver.Locator): protractor.ElementFinder; + + /** + * Use as: element(locator).all(locator) + * Calls to element may be chained to find an array of elements within a parent. + * + * @param {webdriver.Locator} locator The locator that will be used to find descendents. + * + * @return {protractor.ElementArrayFinder} The descendent elements found by the locator + */ + all(locator: webdriver.Locator): protractor.ElementArrayFinder; + + /** + * Shortcut for querying the document directly with css. + * + * @param {string} selector a css selector + * @see webdriver.WebElement.findElement + * @return {!protractor.WebElement} + */ + $(selector: string): protractor.WebElement; + + /** + * Shortcut for querying the document directly with css. + * + * @param {string} selector a css selector + * @see webdriver.WebElement.findElements + * @return {!webdriver.promise.Promise} A promise that will be resolved to an + * array of the located {@link webdriver.WebElement}s. + */ + $$(selector: string): webdriver.promise.Promise; + + /** + * Use as: element(locator).isPresent() + * Determine whether the element is present on the page. + * + * @return {protractor.ElementFinder} Which resolves to whether the element is present on the page. + */ + isPresent(): webdriver.promise.Promise; + + /** + * Override for WebElement.prototype.isElementPresent so that protractor waits + * for Angular to settle before making the check. + * + * @see ElementFinder.isPresent + * @return {!webdriver.promise.Promise} which resolves to whether the element is present on the page. + */ + isElementPresent(locator: webdriver.Locator): webdriver.promise.Promise; + + /** + * Return this ElementFinder's locator. + * + * @return {webdriver.Locator} + */ + locator(): webdriver.Locator; + + /** + * Use as: element(locator).getWebElement() + * Returns the WebElement represented by this ElementFinder. + * Throws the WebDriver error if the element doesn't exist. + * If index is null, it makes sure that there is only one underlying WebElement + * described by the chain of locators and issues a warning otherwise. + * If index is not null, it retrieves the WebElement specified by the index.. + * @return {webdriver.WebElement} The WebElement represented by the ElementFinder. + */ + getWebElement(): webdriver.WebElement; + + /** + * Evalates the input as if it were on the scope of the current element. + * @param {string} expression + * + * @return {!webdriver.promise.Promise} A promise that will resolve to the + * evaluated expression. The result will be resolved as in + * {@link webdriver.WebDriver.executeScript}. In summary - primitives will + * be resolved as is, functions will be converted to string, and elements + * will be returned as a WebElement. + */ + evaluate(expression: string): webdriver.promise.Promise; + + /** + * Determine if animation is allowed on the current element. + * @param {string} value + * + * @return {ElementFinder} which resolves to whether animation is allowed. + */ + allowAnimations(value: string): webdriver.promise.Promise; + + /** + * Access the underlying actionResult of ElementFinder. Implementation allows ElementFinder to be used as a webdriver.promise.Promise. + * @param {function(webdriver.promise.Promise)} fn Function which takes the value of the underlying actionResult. + * + * @return {webdriver.promise.Promise} Promise which contains the results of evaluating fn. + */ + then(fn: IThenFunction): webdriver.promise.Promise; + + /** + * Schedules a command to click on this element. + * @return {!webdriver.promise.Promise} A promise that will be resolved when + * the click command has completed. + */ + click(): webdriver.promise.Promise; + + /** + * Schedules a command to type a sequence on the DOM element represented by this + * instance. + *

+ * Modifier keys (SHIFT, CONTROL, ALT, META) are stateful; once a modifier is + * processed in the keysequence, that key state is toggled until one of the + * following occurs: + *

    + *
  • The modifier key is encountered again in the sequence. At this point the + * state of the key is toggled (along with the appropriate keyup/down events). + *
  • + *
  • The {@code webdriver.Key.NULL} key is encountered in the sequence. When + * this key is encountered, all modifier keys current in the down state are + * released (with accompanying keyup events). The NULL key can be used to + * simulate common keyboard shortcuts: + * + * element.sendKeys("text was", + * webdriver.Key.CONTROL, "a", webdriver.Key.NULL, + * "now text is"); + * // Alternatively: + * element.sendKeys("text was", + * webdriver.Key.chord(webdriver.Key.CONTROL, "a"), + * "now text is"); + *
  • + *
  • The end of the keysequence is encountered. When there are no more keys + * to type, all depressed modifier keys are released (with accompanying keyup + * events). + *
  • + *
+ * Note: On browsers where native keyboard events are not yet + * supported (e.g. Firefox on OS X), key events will be synthesized. Special + * punctionation keys will be synthesized according to a standard QWERTY en-us + * keyboard layout. + * + * @param {...string} var_args The sequence of keys to + * type. All arguments will be joined into a single sequence (var_args is + * permitted for convenience). + * @return {!webdriver.promise.Promise} A promise that will be resolved when all + * keys have been typed. + */ + sendKeys(...var_args: string[]): webdriver.promise.Promise; + + /** + * Schedules a command to query for the tag/node name of this element. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * element's tag name. + */ + getTagName(): webdriver.promise.Promise; + + /** + * Schedules a command to query for the computed style of the element + * represented by this instance. If the element inherits the named style from + * its parent, the parent will be queried for its value. Where possible, color + * values will be converted to their hex representation (e.g. #00ff00 instead of + * rgb(0, 255, 0)). + *

+ * Warning: the value returned will be as the browser interprets it, so + * it may be tricky to form a proper assertion. + * + * @param {string} cssStyleProperty The name of the CSS style property to look + * up. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * requested CSS value. + */ + getCssValue(cssStyleProperty: string): webdriver.promise.Promise; + + /** + * Schedules a command to query for the value of the given attribute of the + * element. Will return the current value even if it has been modified after the + * page has been loaded. More exactly, this method will return the value of the + * given attribute, unless that attribute is not present, in which case the + * value of the property with the same name is returned. If neither value is + * set, null is returned. The "style" attribute is converted as best can be to a + * text representation with a trailing semi-colon. The following are deemed to + * be "boolean" attributes and will be returned as thus: + * + *

async, autofocus, autoplay, checked, compact, complete, controls, declare, + * defaultchecked, defaultselected, defer, disabled, draggable, ended, + * formnovalidate, hidden, indeterminate, iscontenteditable, ismap, itemscope, + * loop, multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open, + * paused, pubdate, readonly, required, reversed, scoped, seamless, seeking, + * selected, spellcheck, truespeed, willvalidate + * + *

Finally, the following commonly mis-capitalized attribute/property names + * are evaluated as expected: + *

    + *
  • "class" + *
  • "readonly" + *
+ * @param {string} attributeName The name of the attribute to query. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * attribute's value. + */ + getAttribute(attributeName: string): webdriver.promise.Promise; + + /** + * Get the visible (i.e. not hidden by CSS) innerText of this element, including + * sub-elements, without any leading or trailing whitespace. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * element's visible text. + */ + getText(): webdriver.promise.Promise; + + /** + * Schedules a command to compute the size of this element's bounding box, in + * pixels. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * element's size as a {@code {width:number, height:number}} object. + */ + getSize(): webdriver.promise.Promise; + + /** + * Schedules a command to compute the location of this element in page space. + * @return {!webdriver.promise.Promise} A promise that will be resolved to the + * element's location as a {@code {x:number, y:number}} object. + */ + getLocation(): webdriver.promise.Promise; + + /** + * Schedules a command to query whether the DOM element represented by this + * instance is enabled, as dicted by the {@code disabled} attribute. + * @return {!webdriver.promise.Promise} A promise that will be resolved with + * whether this element is currently enabled. + */ + isEnabled(): webdriver.promise.Promise; + + /** + * Schedules a command to query whether this element is selected. + * @return {!webdriver.promise.Promise} A promise that will be resolved with + * whether this element is currently selected. + */ + isSelected(): webdriver.promise.Promise; + + /** + * Schedules a command to submit the form containing this element (or this + * element if it is a FORM element). This command is a no-op if the element is + * not contained in a form. + * @return {!webdriver.promise.Promise} A promise that will be resolved when + * the form has been submitted. + */ + submit(): webdriver.promise.Promise; + + /** + * Schedules a command to clear the {@code value} of this element. This command + * has no effect if the underlying DOM element is neither a text INPUT element + * nor a TEXTAREA element. + * @return {!webdriver.promise.Promise} A promise that will be resolved when + * the element has been cleared. + */ + clear(): webdriver.promise.Promise; + + /** + * Schedules a command to test whether this element is currently displayed. + * @return {!webdriver.promise.Promise} A promise that will be resolved with + * whether this element is currently visible on the page. + */ + isDisplayed(): webdriver.promise.Promise; + + /** + * Schedules a command to retrieve the outer HTML of this element. + * @return {!webdriver.promise.Promise} A promise that will be resolved with + * the element's outer HTML. + */ + getOuterHtml(): webdriver.promise.Promise; + + /** + * Schedules a command to retrieve the inner HTML of this element. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * element's inner HTML. + */ + getInnerHtml(): webdriver.promise.Promise; + + /** + * @return {!webdriver.promise.Promise.} A promise + * that resolves to this element's JSON representation as defined by the + * WebDriver wire protocol. + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol + */ + toWireValue(): webdriver.promise.Promise; + } + + interface IThenFunction { + (promiseResult: any): any; + } + + + interface ElementArrayFinder { + /** + * Use as: element.all(locator).getWebElements() + * Returns the array of WebElements represented by this ElementArrayFinder. + * + * @return {Array.} Array of WebElements represented by this ElementArrayFinder + */ + getWebElements(): webdriver.WebElement[]; + + /** + * Use as: element.all(locator).get(index) + * Get an element found by the locator by index. The index starts at 0. This does not actually retrieve the underlying element. + * + * @param {number} index Element index. + * + * @return {protractor.ElementFinder} Finder representing element at the given index + */ + get(index: number): protractor.ElementFinder; + + + /** + * Use as: element.all(locator).first() + * Get the first matching element for the locator. This does not actually retrieve the underlying element. + * + * @return {Protractor.ElementFinder} Finder representing the first matching element + */ + first(): protractor.ElementFinder; + + /** + * Use as: element.all(locator).last() + * Get the last matching element for the locator. This does not actually retrieve the underlying element. + * + * @return {Protractor.ElementFinder} Finder representing the last matching element + */ + last(): protractor.ElementFinder; + + /** + * Use as: element.all(locator).getWebElements() + * Returns the array of WebElements represented by this ElementArrayFinder. + * + * @return {!webdriver.promise.Promise} The array of WebElements represented by this ElementArrayFinder + */ + count(): webdriver.promise.Promise; + + /** + * Use as: element.all(locator).each(eachFunction) + * Calls the input function on each ElementFinder found by the locator. + * + * @param {function(ElementFinder)} fn Input function. + */ + each(fn: IEachFunction): void; + + /** + * Use as: element.all(locator).map(mapFunction) + * Apply a map function to each element found using the locator. The callback receives the ElementFinder as the first argument and the index as a second arg. + * + * @param {function(ElementFinder, number)} mapFn Map function that will be applied to each element. + * + * @return {!webdriver.promise.Promise} A promise that resolves to an array of values returned by the map function. + */ + map(mapFn: IMapFunction): webdriver.promise.Promise; + + /** + * Use as: element.all(locator).filter(filterFn) + * Apply a filter function to each element found using the locator. Returns promise of a new array with all elements that pass the filter function. The filter function receives the ElementFinder as the first argument and the index as a second arg. + * + * @param {function(ElementFinder, number): webdriver.promise.Promise} filterFn Filter function that will test if an element should be returned. filterFn should return a promise that resolves to a boolean. + * + * @return {!webdriver.promise.Promise} A promise that resolves to an array of ElementFinders that satisfy the filter function. + */ + filter(func: IFilterFunction): webdriver.promise.Promise; + + /** + * Use as: element.all(locator).reduce(reduceFn) + * Apply a reduce function against an accumulator and every element found using the locator (from left-to-right). + * The reduce function has to reduce every element into a single value (the accumulator). + * Returns promise of the accumulator. + * The reduce function receives the accumulator, current ElementFinder, the index, and the entire array of ElementFinders, respectively. + * + * @param {function(number, ElementFinder, number, Array.): webdriver.promise.Promise} reduceFn Reduce function that reduces every element into a single value. + * @param {*} initialValue Initial value of the accumulator. + * + * @return {!webdriver.promise.Promise} A promise that resolves to the final value of the accumulator. + */ + reduce(func: IReductionFunction, initialValue: any): webdriver.promise.Promise; + + /** + * Represents the ElementArrayFinder as an array of ElementFinders. + * + * @return {!webdriver.promise.Promise} Return a promise, which resolves to a list (array) + * of ElementFinders specified by the locator. + */ + asElementFinders_(): webdriver.promise.Promise; + + + /** + * Find the elements specified by the locator. The input function is passed + * to the resulting promise, which resolves to an array of ElementFinders. + * + * Use as: element.all(locator).then(thenFunction) + *
    + *
  • First
  • + *
  • Second
  • + *
  • Third
  • + *
+ * + * element.all(by.css('.items li')).then(function(arr) { + * expect(arr.length).toEqual(3); + * }); + * + * @param {function(Array.)} fn + * + * @type {webdriver.promise.Promise} a promise which will resolve to + * an array of ElementFinders matching the locator. + */ + then(fn: IElementArrayFinderThenFunction): webdriver.promise.Promise; + } + + interface IEachFunction { + (element: protractor.ElementFinder): void; + } + + interface IMapFunction { + (element: ElementFinder, index: number): any; + } + + interface IFilterFunction { + (element: ElementFinder, index: number): webdriver.promise.Promise; + } + + interface IReductionFunction { + (accumulator: any, element: protractor.ElementFinder, index?: number, array?: protractor.ElementFinder[]): webdriver.promise.Promise; + } + + interface IElementArrayFinderThenFunction { + (promiseResult: ElementFinder[]): any; + } + + class LocatorWithColumn extends webdriver.Locator { + column(index: number): webdriver.Locator; + } + + class RepeaterLocator extends LocatorWithColumn { + row(index: number): LocatorWithColumn; + } + + interface IProtractorLocatorStrategy extends webdriver.ILocatorStrategy { + /** + * Add a locator to this instance of ProtractorBy. This locator can then be + * used with element(by.()). + * + * @param {string} name + * @param {function|string} script A script to be run in the context of + * the browser. This script will be passed an array of arguments + * that begins with the element scoping the search, and then + * contains any args passed into the locator. It should return + * an array of elements. + */ + addLocator(name: string, script: any): void; + + /** + * Usage: + * {{status}} + * var status = element(by.binding('{{status}}')); + * + * @param {string} bindingDescriptor + * @return {webdriver.Locator} + */ + binding(bindingDescriptor: string): webdriver.Locator; + + /** + * Find an element by exact binding. + * + * {{ person.name }} + * + * {{person_phone|uppercase}} + * + * expect(element(by.exactBinding('person.name')).isPresent()).toBe(true); + * expect(element(by.exactBinding('person-email')).isPresent()).toBe(true); + * expect(element(by.exactBinding('person')).isPresent()).toBe(false); + * expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true); + * expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(true); + * expect(element(by.exactBinding('phone')).isPresent()).toBe(false); + * + * @param {string} bindingDescriptor + * @return {webdriver.Locator} + */ + exactBinding(bindingDescriptor: string): webdriver.Locator; + + /** + * + * Find an element by ng-model expression. + * + * Usage: + * + * var input = element(by.model('person.name')); + * input.sendKeys('123'); + * expect(input.getAttribute('value')).toBe('Foo123'); + * + * @param {string} model ng-model expression. + * @return {webdriver.Locator} + */ + model(model: string): webdriver.Locator; + + /** + * Find a button by text. + * + * Usage: + * + * element(by.buttonText('Save')); + * + * @param {string} searchText + * @return {webdriver.Locator} + */ + buttonText(searchText: string): webdriver.Locator; + + + /** + * Find a button by partial text. + * + * Usage: + * + * element(by.partialButtonText('Save')); + * + * @param {string} searchText + * @return {webdriver.Locator} + */ + partialButtonText(searchText: string): webdriver.Locator; + + /** + * Find elements inside an ng-repeat. + * + * Usage: + *
+ * {{cat.name}} + * {{cat.age}} + *
+ * + *
+ * {{$index}} + *
+ *
+ *

{{book.name}}

+ *

{{book.blurb}}

+ *
+ * + * // Returns the DIV for the second cat. + * var secondCat = element(by.repeater('cat in pets').row(1)); + * + * // Returns the SPAN for the first cat's name. + * var firstCatName = element(by.repeater('cat in pets'). + * row(0).column('{{cat.name}}')); + * + * // Returns a promise that resolves to an array of WebElements from a column + * var ages = element.all( + * by.repeater('cat in pets').column('{{cat.age}}')); + * + * // Returns a promise that resolves to an array of WebElements containing + * // all top level elements repeated by the repeater. For 2 pets rows resolves + * // to an array of 2 elements. + * var rows = element.all(by.repeater('cat in pets')); + * + * // Returns a promise that resolves to an array of WebElements containing all + * // the elements with a binding to the book's name. + * var divs = element.all(by.repeater('book in library').column('book.name')); + * + * // Returns a promise that resolves to an array of WebElements containing + * // the DIVs for the second book. + * var bookInfo = element.all(by.repeater('book in library').row(1)); + * + * // Returns the H4 for the first book's name. + * var firstBookName = element(by.repeater('book in library'). + * row(0).column('{{book.name}}')); + * + * // Returns a promise that resolves to an array of WebElements containing + * // all top level elements repeated by the repeater. For 2 books divs + * // resolves to an array of 4 elements. + * var divs = element.all(by.repeater('book in library')); + */ + repeater(repeatDescriptor: string): RepeaterLocator; + + /** + * Find elements by CSS which contain a certain string. + * + * @view + *
    + *
  • Dog
  • + *
  • Cat
  • + *
+ * + * @example + * // Returns the DIV for the dog, but not cat. + * var dog = element(by.cssContainingText('.pet', 'Dog')); + * + * @param cssSelector {string} + * @param searchText {string} + * @return {webdriver.Locator} + */ + cssContainingText(cssSelector: string, searchText: string): webdriver.Locator; + + /** + * Find an element by ng-options expression. + * + * Usage: + * + * + * var allOptions = element.all(by.options('c for c in colors')); + * expect(allOptions.count()).toEqual(2); + * var firstOption = allOptions.first(); + * expect(firstOption.getText()).toEqual('red'); + * + * @param {string} optionsDescriptor ng-options expression. + * @return {webdriver.Locator} + */ + options(optionsDescriptor: string): webdriver.Locator; + } + + var By: IProtractorLocatorStrategy; + + class Protractor extends webdriver.WebDriver { + + //region Constructors + + /** + * @param {webdriver.WebDriver} webdriver + * @param {string=} opt_baseUrl A base URL to run get requests against. + * @param {string=body} opt_rootElement Selector element that has an ng-app in + * scope. + * @constructor + */ + constructor(webdriver: webdriver.WebDriver, opt_baseUrl?: string, opt_rootElement?: string); + + //endregion + + //region Properties + + /** + * The wrapped webdriver instance. Use this to interact with pages that do + * not contain Angular (such as a log-in screen). + * + * @type {webdriver.WebDriver} + */ + driver: webdriver.WebDriver; + + /** + * All get methods will be resolved against this base URL. Relative URLs are = + * resolved the way anchor tags resolve. + * + * @type {string} + */ + baseUrl: string; + + /** + * The css selector for an element on which to find Angular. This is usually + * 'body' but if your ng-app is on a subsection of the page it may be + * a subelement. + * + * @type {string} + */ + rootEl: string; + + /** + * If true, Protractor will not attempt to synchronize with the page before + * performing actions. This can be harmful because Protractor will not wait + * until $timeouts and $http calls have been processed, which can cause + * tests to become flaky. This should be used only when necessary, such as + * when a page continuously polls an API using $timeout. + * + * @type {boolean} + */ + ignoreSynchronization: boolean; + + /** + * An object that holds custom test parameters. + * + * @type {Object} + */ + params: any; + + //endregion + + //region Methods + + /** + * Instruct webdriver to wait until Angular has finished rendering and has + * no outstanding $http calls before continuing. + * + * @return {!webdriver.promise.Promise} A promise that will resolve to the + * scripts return value. + */ + waitForAngular(): webdriver.promise.Promise; + + /** + * Waits for Angular to finish rendering before searching for elements. + * @see webdriver.WebDriver.findElement + * + * @param {webdriver.Locator} locator The locator used to find the element. + * @return {!webdriver.WebElement} + */ + findElement(locator: webdriver.Locator): protractor.WebElement; + + /** + * Waits for Angular to finish rendering before searching for elements. + * @see webdriver.WebDriver.findElements + * + * @param {webdriver.Locator} locator The locator used to find the elements. + * @return {!webdriver.promise.Promise} A promise that will be resolved to an + * array of the located {@link webdriver.WebElement}s. + */ + findElements(locator: webdriver.Locator): webdriver.promise.Promise; + + /** + * Tests if an element is present on the page. + * @see webdriver.WebDriver.isElementPresent + * @return {!webdriver.promise.Promise} A promise that will resolve to whether + * the element is present on the page. + */ + isElementPresent(locatorOrElement: webdriver.Locator): webdriver.promise.Promise; + isElementPresent(locatorOrElement: any): webdriver.promise.Promise; + + /** + * Helper function for finding elements. + * + * @type {function(webdriver.Locator): ElementFinder} + */ + element(locator: webdriver.Locator): ElementFinder; + + /** + * Helper function for finding elements by css. + * + * @type {function(string): ElementFinder} + */ + $(cssLocator: string): ElementFinder; + + /** + * Helper function for finding arrays of elements by css. + * + * @type {function(string): ElementArrayFinder} + */ + $$(cssLocator: string): ElementArrayFinder; + + /** + * Add a module to load before Angular whenever Protractor.get is called. + * Modules will be registered after existing modules already on the page, + * so any module registered here will override preexisting modules with the same + * name. + * + * @param {string} name The name of the module to load or override. + * @param {string|Function} script The JavaScript to load the module. + * @param {...*} varArgs Any additional arguments will be provided to + * the script and may be referenced using the `arguments` object. + */ + addMockModule(name: string, script: string, ...varArgs: any[]): void; + addMockModule(name: string, script: any, ...varArgs: any[]): void; + + /** + * Clear the list of registered mock modules. + */ + clearMockModules(): void; + + /** + * Remove a registered mock module. + * @param {!string} name The name of the module to remove. + */ + removeMockModule(name: string): void; + + /** + * See webdriver.WebDriver.get + * + * Navigate to the given destination and loads mock modules before + * Angular. Assumes that the page being loaded uses Angular. + * If you need to access a page which does not have Angular on load, use + * the wrapped webdriver directly. + * + * @param {string} destination Destination URL. + * @param {number=} opt_timeout Number of seconds to wait for Angular to start. + */ + get(destination: string, opt_timeout?: number): webdriver.promise.Promise; + + /** + * See webdriver.WebDriver.refresh + * + * Makes a full reload of the current page and loads mock modules before + * Angular. Assumes that the page being loaded uses Angular. + * If you need to access a page which does not have Angular on load, use + * the wrapped webdriver directly. + * + * @param {number=} opt_timeout Number of seconds to wait for Angular to start. + */ + refresh(opt_timeout?: number): void; + + /** + * Mixin navigation methods back into the navigation object so that + * they are invoked as before, i.e. driver.navigate().refresh() + */ + navigate(): webdriver.WebDriverNavigation; + + /** + * Browse to another page using in-page navigation. + * + * @param {string} url In page URL using the same syntax as $location.url() + * @returns {!webdriver.promise.Promise} A promise that will resolve once + * page has been changed. + */ + setLocation(url: string): webdriver.promise.Promise; + + /** + * Returns the current absolute url from AngularJS. + */ + getLocationAbsUrl(): webdriver.promise.Promise; + + /** + * Pauses the test and injects some helper functions into the browser, so that + * debugging may be done in the browser console. + * + * This should be used under node in debug mode, i.e. with + * protractor debug + * + * While in the debugger, commands can be scheduled through webdriver by + * entering the repl: + * debug> repl + * Press Ctrl + C to leave rdebug repl + * > ptor.findElement(protractor.By.input('user').sendKeys('Laura')); + * > ptor.debugger(); + * debug> c + * + * This will run the sendKeys command as the next task, then re-enter the + * debugger. + */ + debugger(): void; + + /** + * Beta (unstable) pause function for debugging webdriver tests. Use + * browser.pause() in your test to enter the protractor debugger from that + * point in the control flow. + * Does not require changes to the command line (no need to add 'debug'). + * + * @param {=number} opt_debugPort Optional port to use for the debugging process + */ + pause(opt_debugPort?: number): void; + + //endregion + } + + /** + * Create a new instance of Protractor by wrapping a webdriver instance. + * + * @param {webdriver.WebDriver} webdriver The configured webdriver instance. + * @param {string=} opt_baseUrl A URL to prepend to relative gets. + * @return {Protractor} + */ + function wrapDriver(webdriver: webdriver.WebDriver, opt_baseUrl?: string, opt_rootElement?: string): Protractor; + + /** + * Set a singleton instance of protractor. + * @param {Protractor} ptor + */ + function setInstance(ptor: Protractor): void; + + /** + * Get the singleton instance. + * @return {Protractor} + */ + function getInstance(): Protractor; + +} + +interface cssSelectorHelper { + (cssLocator: string): protractor.ElementFinder; +} + +interface cssArraySelectorHelper { + (cssLocator: string): protractor.ElementArrayFinder; +} + +declare var browser: protractor.Protractor; +declare var by: protractor.IProtractorLocatorStrategy; +declare var element: protractor.Element; +declare var $: cssSelectorHelper; +declare var $$: cssArraySelectorHelper; + +declare module 'protractor' { + export = protractor; +} diff --git a/selenium-webdriver/chrome.d.ts b/selenium-webdriver/chrome.d.ts index 1eef996ee..292551576 100644 --- a/selenium-webdriver/chrome.d.ts +++ b/selenium-webdriver/chrome.d.ts @@ -65,7 +65,7 @@ * extensions to add. * @return {!Options} A self reference. */ - addExtensions(...var_args): Options; + addExtensions(...var_args: any[]): Options; /** @@ -261,7 +261,7 @@ * @param {!remote.DriverService} service The service to use. * @throws {Error} If the default service is currently running. */ - function setDefaultService(service: any); + function setDefaultService(service: any): void; } declare module 'selenium-webdriver/chrome' { diff --git a/selenium-webdriver/firefox.d.ts b/selenium-webdriver/firefox.d.ts index 18d509dc9..c7666e6d4 100644 --- a/selenium-webdriver/firefox.d.ts +++ b/selenium-webdriver/firefox.d.ts @@ -15,7 +15,7 @@ * @param {...(string|!Array.)} var_args Either the arguments to add as * varargs, or the arguments as an array. */ - addArguments(...var_args: string[]); + addArguments(...var_args: string[]): void; /** @@ -130,7 +130,7 @@ * @param {string} extension Path to the extension to include, as either an * unpacked extension directory or the path to a xpi file. */ - addExtension(extension: string); + addExtension(extension: string): void; /** @@ -139,9 +139,9 @@ * @param {(string|number|boolean)} value The preference value. * @throws {Error} If attempting to set a frozen preference. */ - setPreference(key: string, value: string); - setPreference(key: string, value: number); - setPreference(key: string, value: boolean); + setPreference(key: string, value: string): void; + setPreference(key: string, value: number): void; + setPreference(key: string, value: boolean): void; /** @@ -167,7 +167,7 @@ * Sets the port to use for the WebDriver extension loaded by this profile. * @param {number} port The desired port, or 0 to use any free port. */ - setPort(port: number); + setPort(port: number): void; /** @@ -182,14 +182,14 @@ * certificates. * @param {boolean} value . */ - setAcceptUntrustedCerts(value: boolean); + setAcceptUntrustedCerts(value: boolean): void; /** * Sets whether to assume untrusted certificates come from untrusted issuers. * @param {boolean} value . */ - setAssumeUntrustedCertIssuer(value: boolean); + setAssumeUntrustedCertIssuer(value: boolean): void; /** @@ -203,7 +203,7 @@ * Sets whether to use native events with this profile. * @param {boolean} enabled . */ - setNativeEventsEnabled(enabled: boolean); + setNativeEventsEnabled(enabled: boolean): void; /** diff --git a/selenium-webdriver/legacy/selenium-webdriver-tests-2.39.0.ts b/selenium-webdriver/legacy/selenium-webdriver-2.39.0-tests.ts similarity index 99% rename from selenium-webdriver/legacy/selenium-webdriver-tests-2.39.0.ts rename to selenium-webdriver/legacy/selenium-webdriver-2.39.0-tests.ts index 52b317d96..c1cde5147 100644 --- a/selenium-webdriver/legacy/selenium-webdriver-tests-2.39.0.ts +++ b/selenium-webdriver/legacy/selenium-webdriver-2.39.0-tests.ts @@ -1,4 +1,4 @@ -/// +/// function TestAbstractBuilder() { var builder: webdriver.AbstractBuilder = new webdriver.AbstractBuilder(); diff --git a/selenium-webdriver/selenium-webdriver-tests.ts b/selenium-webdriver/selenium-webdriver-tests.ts index be359b886..4ec10bbb9 100644 --- a/selenium-webdriver/selenium-webdriver-tests.ts +++ b/selenium-webdriver/selenium-webdriver-tests.ts @@ -658,7 +658,10 @@ function TestWebElement() { } function TestLogging() { - webdriver.logging.Preferences['name'] = 'ABC'; + var preferences: webdriver.logging.Preferences = new webdriver.logging.Preferences(); + preferences.setLevel(webdriver.logging.Type.BROWSER, webdriver.logging.Level.ALL); + var prefs: any = preferences.toJSON(); + var level: webdriver.logging.ILevel = webdriver.logging.getLevel('OFF'); level = webdriver.logging.getLevel(1); diff --git a/selenium-webdriver/selenium-webdriver.d.ts b/selenium-webdriver/selenium-webdriver.d.ts index e38049e1d..37b3743e7 100644 --- a/selenium-webdriver/selenium-webdriver.d.ts +++ b/selenium-webdriver/selenium-webdriver.d.ts @@ -182,7 +182,7 @@ declare module webdriver { name: string; } - var Level: { + interface ILevelValues { ALL: ILevel; DEBUG: ILevel; INFO: ILevel; @@ -191,6 +191,8 @@ declare module webdriver { OFF: ILevel; } + var Level: ILevelValues; + /** * Converts a level name or value to a {@link webdriver.logging.Level} value. * If the name/value is not recognized, {@link webdriver.logging.Level.ALL} @@ -272,6 +274,262 @@ declare module webdriver { } module promise { + //region Functions + + /** + * Given an array of promises, will return a promise that will be fulfilled + * with the fulfillment values of the input array's values. If any of the + * input array's promises are rejected, the returned promise will be rejected + * with the same reason. + * + * @param {!Array.<(T|!webdriver.promise.Promise.)>} arr An array of + * promises to wait on. + * @return {!webdriver.promise.Promise.>} A promise that is + * fulfilled with an array containing the fulfilled values of the + * input array, or rejected with the same reason as the first + * rejected value. + * @template T + */ + function all(arr: Promise[]): Promise; + + /** + * Invokes the appropriate callback function as soon as a promised + * {@code value} is resolved. This function is similar to + * {@link webdriver.promise.when}, except it does not return a new promise. + * @param {*} value The value to observe. + * @param {Function} callback The function to call when the value is + * resolved successfully. + * @param {Function=} opt_errback The function to call when the value is + * rejected. + */ + function asap(value: any, callback: Function, opt_errback?: Function): void; + + /** + * @return {!webdriver.promise.ControlFlow} The currently active control flow. + */ + function controlFlow(): ControlFlow; + + /** + * Creates a new control flow. The provided callback will be invoked as the + * first task within the new flow, with the flow as its sole argument. Returns + * a promise that resolves to the callback result. + * @param {function(!webdriver.promise.ControlFlow)} callback The entry point + * to the newly created flow. + * @return {!webdriver.promise.Promise} A promise that resolves to the callback + * result. + */ + function createFlow(callback: (flow: ControlFlow) => R): Promise; + + /** + * Determines whether a {@code value} should be treated as a promise. + * Any object whose "then" property is a function will be considered a promise. + * + * @param {*} value The value to test. + * @return {boolean} Whether the value is a promise. + */ + function isPromise(value: any): boolean; + + /** + * Tests is a function is a generator. + * @param {!Function} fn The function to test. + * @return {boolean} Whether the function is a generator. + */ + function isGenerator(fn: Function): boolean; + + /** + * Creates a promise that will be resolved at a set time in the future. + * @param {number} ms The amount of time, in milliseconds, to wait before + * resolving the promise. + * @return {!webdriver.promise.Promise} The promise. + */ + function delayed(ms: number): Promise; + + /** + * Calls a function for each element in an array, and if the function returns + * true adds the element to a new array. + * + *

If the return value of the filter function is a promise, this function + * will wait for it to be fulfilled before determining whether to insert the + * element into the new array. + * + *

If the filter function throws or returns a rejected promise, the promise + * returned by this function will be rejected with the same reason. Only the + * first failure will be reported; all subsequent errors will be silently + * ignored. + * + * @param {!(Array.|webdriver.promise.Promise.>)} arr The + * array to iterator over, or a promise that will resolve to said array. + * @param {function(this: SELF, TYPE, number, !Array.): ( + * boolean|webdriver.promise.Promise.)} fn The function + * to call for each element in the array. + * @param {SELF=} opt_self The object to be used as the value of 'this' within + * {@code fn}. + * @template TYPE, SELF + */ + function filter(arr: T[], fn: (element: T, index: number, array: T[]) => any, opt_self?: any): Promise; + function filter(arr: Promise, fn: (element: T, index: number, array: T[]) => any, opt_self?: any): Promise + + /** + * Creates a new deferred object. + * @return {!webdriver.promise.Deferred} The new deferred object. + */ + function defer(): Deferred; + + /** + * Creates a promise that has been resolved with the given value. + * @param {*=} opt_value The resolved value. + * @return {!webdriver.promise.Promise} The resolved promise. + */ + function fulfilled(opt_value?: T): Promise; + + /** + * Calls a function for each element in an array and inserts the result into a + * new array, which is used as the fulfillment value of the promise returned + * by this function. + * + *

If the return value of the mapping function is a promise, this function + * will wait for it to be fulfilled before inserting it into the new array. + * + *

If the mapping function throws or returns a rejected promise, the + * promise returned by this function will be rejected with the same reason. + * Only the first failure will be reported; all subsequent errors will be + * silently ignored. + * + * @param {!(Array.|webdriver.promise.Promise.>)} arr The + * array to iterator over, or a promise that will resolve to said array. + * @param {function(this: SELF, TYPE, number, !Array.): ?} fn The + * function to call for each element in the array. This function should + * expect three arguments (the element, the index, and the array itself. + * @param {SELF=} opt_self The object to be used as the value of 'this' within + * {@code fn}. + * @template TYPE, SELF + */ + function map(arr: T[], fn: (element: T, index: number, array: T[]) => any, opt_self?: any): Promise + function map(arr: Promise, fn: (element: T, index: number, array: T[]) => any, opt_self?: any): Promise + + /** + * Creates a promise that has been rejected with the given reason. + * @param {*=} opt_reason The rejection reason; may be any value, but is + * usually an Error or a string. + * @return {!webdriver.promise.Promise} The rejected promise. + */ + function rejected(opt_reason?: any): Promise; + + /** + * Wraps a function that is assumed to be a node-style callback as its final + * argument. This callback takes two arguments: an error value (which will be + * null if the call succeeded), and the success value as the second argument. + * If the call fails, the returned promise will be rejected, otherwise it will + * be resolved with the result. + * @param {!Function} fn The function to wrap. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * result of the provided function's callback. + */ + function checkedNodeCall(fn: Function, ...var_args: any[]): Promise; + + /** + * Consumes a {@code GeneratorFunction}. Each time the generator yields a + * promise, this function will wait for it to be fulfilled before feeding the + * fulfilled value back into {@code next}. Likewise, if a yielded promise is + * rejected, the rejection error will be passed to {@code throw}. + * + *

Example 1: the Fibonacci Sequence. + *


+         * webdriver.promise.consume(function* fibonacci() {
+         *   var n1 = 1, n2 = 1;
+         *   for (var i = 0; i < 4; ++i) {
+         *     var tmp = yield n1 + n2;
+         *     n1 = n2;
+         *     n2 = tmp;
+         *   }
+         *   return n1 + n2;
+         * }).then(function(result) {
+         *   console.log(result);  // 13
+         * });
+         * 
+ * + *

Example 2: a generator that throws. + *


+         * webdriver.promise.consume(function* () {
+         *   yield webdriver.promise.delayed(250).then(function() {
+         *     throw Error('boom');
+         *   });
+         * }).thenCatch(function(e) {
+         *   console.log(e.toString());  // Error: boom
+         * });
+         * 
+ * + * @param {!Function} generatorFn The generator function to execute. + * @param {Object=} opt_self The object to use as "this" when invoking the + * initial generator. + * @param {...*} var_args Any arguments to pass to the initial generator. + * @return {!webdriver.promise.Promise.} A promise that will resolve to the + * generator's final result. + * @throws {TypeError} If the given function is not a generator. + */ + function consume(generatorFn: Function, opt_self?: any, ...var_args: any[]): Promise; + + /** + * Registers an observer on a promised {@code value}, returning a new promise + * that will be resolved when the value is. If {@code value} is not a promise, + * then the return promise will be immediately resolved. + * @param {*} value The value to observe. + * @param {Function=} opt_callback The function to call when the value is + * resolved successfully. + * @param {Function=} opt_errback The function to call when the value is + * rejected. + * @return {!webdriver.promise.Promise} A new promise. + */ + function when(value: T, opt_callback?: (value: T) => any, opt_errback?: (error: any) => any): Promise; + function when(value: Promise, opt_callback?: (value: T) => any, opt_errback?: (error: any) => any): Promise; + + /** + * Returns a promise that will be resolved with the input value in a + * fully-resolved state. If the value is an array, each element will be fully + * resolved. Likewise, if the value is an object, all keys will be fully + * resolved. In both cases, all nested arrays and objects will also be + * fully resolved. All fields are resolved in place; the returned promise will + * resolve on {@code value} and not a copy. + * + * Warning: This function makes no checks against objects that contain + * cyclical references: + * + * var value = {}; + * value['self'] = value; + * webdriver.promise.fullyResolved(value); // Stack overflow. + * + * @param {*} value The value to fully resolve. + * @return {!webdriver.promise.Promise} A promise for a fully resolved version + * of the input value. + */ + function fullyResolved(value: any): Promise; + + /** + * Changes the default flow to use when no others are active. + * @param {!webdriver.promise.ControlFlow} flow The new default flow. + * @throws {Error} If the default flow is not currently active. + */ + function setDefaultFlow(flow: ControlFlow): void; + + //endregion + + /** + * Error used when the computation of a promise is cancelled. + * + * @extends {goog.debug.Error} + * @final + */ + class CancellationError { + /** + * @param {string=} opt_msg The cancellation message. + * @constructor + */ + constructor(opt_msg?: string); + + name: string; + message: string; + } + interface IThenable { /** * Cancels the computation of this promise's value, rejecting the promise in the @@ -497,245 +755,6 @@ declare module webdriver { static isImplementation(object: any): boolean; } - //region Functions - - /** - * Given an array of promises, will return a promise that will be fulfilled - * with the fulfillment values of the input array's values. If any of the - * input array's promises are rejected, the returned promise will be rejected - * with the same reason. - * - * @param {!Array.<(T|!webdriver.promise.Promise.)>} arr An array of - * promises to wait on. - * @return {!webdriver.promise.Promise.>} A promise that is - * fulfilled with an array containing the fulfilled values of the - * input array, or rejected with the same reason as the first - * rejected value. - * @template T - */ - function all(arr: Promise[]): Promise; - - /** - * Invokes the appropriate callback function as soon as a promised - * {@code value} is resolved. This function is similar to - * {@link webdriver.promise.when}, except it does not return a new promise. - * @param {*} value The value to observe. - * @param {Function} callback The function to call when the value is - * resolved successfully. - * @param {Function=} opt_errback The function to call when the value is - * rejected. - */ - function asap(value: any, callback: Function, opt_errback?: Function): void; - - /** - * @return {!webdriver.promise.ControlFlow} The currently active control flow. - */ - function controlFlow(): ControlFlow; - - /** - * Creates a new control flow. The provided callback will be invoked as the - * first task within the new flow, with the flow as its sole argument. Returns - * a promise that resolves to the callback result. - * @param {function(!webdriver.promise.ControlFlow)} callback The entry point - * to the newly created flow. - * @return {!webdriver.promise.Promise} A promise that resolves to the callback - * result. - */ - function createFlow(callback: (flow: ControlFlow) => R): Promise; - - /** - * Determines whether a {@code value} should be treated as a promise. - * Any object whose "then" property is a function will be considered a promise. - * - * @param {*} value The value to test. - * @return {boolean} Whether the value is a promise. - */ - function isPromise(value: any): boolean; - - /** - * Tests is a function is a generator. - * @param {!Function} fn The function to test. - * @return {boolean} Whether the function is a generator. - */ - function isGenerator(fn: Function): boolean; - - /** - * Creates a promise that will be resolved at a set time in the future. - * @param {number} ms The amount of time, in milliseconds, to wait before - * resolving the promise. - * @return {!webdriver.promise.Promise} The promise. - */ - function delayed(ms: number): Promise; - - /** - * Calls a function for each element in an array, and if the function returns - * true adds the element to a new array. - * - *

If the return value of the filter function is a promise, this function - * will wait for it to be fulfilled before determining whether to insert the - * element into the new array. - * - *

If the filter function throws or returns a rejected promise, the promise - * returned by this function will be rejected with the same reason. Only the - * first failure will be reported; all subsequent errors will be silently - * ignored. - * - * @param {!(Array.|webdriver.promise.Promise.>)} arr The - * array to iterator over, or a promise that will resolve to said array. - * @param {function(this: SELF, TYPE, number, !Array.): ( - * boolean|webdriver.promise.Promise.)} fn The function - * to call for each element in the array. - * @param {SELF=} opt_self The object to be used as the value of 'this' within - * {@code fn}. - * @template TYPE, SELF - */ - function filter(arr: T[], fn: (element: T, index: number, array: T[]) => any, opt_self?: any): Promise; - function filter(arr: Promise, fn: (element: T, index: number, array: T[]) => any, opt_self?: any): Promise - - /** - * Creates a new deferred object. - * @return {!webdriver.promise.Deferred} The new deferred object. - */ - function defer(): Deferred; - - /** - * Creates a promise that has been resolved with the given value. - * @param {*=} opt_value The resolved value. - * @return {!webdriver.promise.Promise} The resolved promise. - */ - function fulfilled(opt_value?: T): Promise; - - /** - * Calls a function for each element in an array and inserts the result into a - * new array, which is used as the fulfillment value of the promise returned - * by this function. - * - *

If the return value of the mapping function is a promise, this function - * will wait for it to be fulfilled before inserting it into the new array. - * - *

If the mapping function throws or returns a rejected promise, the - * promise returned by this function will be rejected with the same reason. - * Only the first failure will be reported; all subsequent errors will be - * silently ignored. - * - * @param {!(Array.|webdriver.promise.Promise.>)} arr The - * array to iterator over, or a promise that will resolve to said array. - * @param {function(this: SELF, TYPE, number, !Array.): ?} fn The - * function to call for each element in the array. This function should - * expect three arguments (the element, the index, and the array itself. - * @param {SELF=} opt_self The object to be used as the value of 'this' within - * {@code fn}. - * @template TYPE, SELF - */ - function map(arr: T[], fn: (element: T, index: number, array: T[]) => any, opt_self?: any): Promise - function map(arr: Promise, fn: (element: T, index: number, array: T[]) => any, opt_self?: any): Promise - - /** - * Creates a promise that has been rejected with the given reason. - * @param {*=} opt_reason The rejection reason; may be any value, but is - * usually an Error or a string. - * @return {!webdriver.promise.Promise} The rejected promise. - */ - function rejected(opt_reason?: any): Promise; - - /** - * Wraps a function that is assumed to be a node-style callback as its final - * argument. This callback takes two arguments: an error value (which will be - * null if the call succeeded), and the success value as the second argument. - * If the call fails, the returned promise will be rejected, otherwise it will - * be resolved with the result. - * @param {!Function} fn The function to wrap. - * @return {!webdriver.promise.Promise} A promise that will be resolved with the - * result of the provided function's callback. - */ - function checkedNodeCall(fn: Function, ...var_args): Promise; - - /** - * Consumes a {@code GeneratorFunction}. Each time the generator yields a - * promise, this function will wait for it to be fulfilled before feeding the - * fulfilled value back into {@code next}. Likewise, if a yielded promise is - * rejected, the rejection error will be passed to {@code throw}. - * - *

Example 1: the Fibonacci Sequence. - *


-         * webdriver.promise.consume(function* fibonacci() {
-         *   var n1 = 1, n2 = 1;
-         *   for (var i = 0; i < 4; ++i) {
-         *     var tmp = yield n1 + n2;
-         *     n1 = n2;
-         *     n2 = tmp;
-         *   }
-         *   return n1 + n2;
-         * }).then(function(result) {
-         *   console.log(result);  // 13
-         * });
-         * 
- * - *

Example 2: a generator that throws. - *


-         * webdriver.promise.consume(function* () {
-         *   yield webdriver.promise.delayed(250).then(function() {
-         *     throw Error('boom');
-         *   });
-         * }).thenCatch(function(e) {
-         *   console.log(e.toString());  // Error: boom
-         * });
-         * 
- * - * @param {!Function} generatorFn The generator function to execute. - * @param {Object=} opt_self The object to use as "this" when invoking the - * initial generator. - * @param {...*} var_args Any arguments to pass to the initial generator. - * @return {!webdriver.promise.Promise.} A promise that will resolve to the - * generator's final result. - * @throws {TypeError} If the given function is not a generator. - */ - function consume(generatorFn: Function, opt_self?: any, ...var_args): Promise; - - /** - * Registers an observer on a promised {@code value}, returning a new promise - * that will be resolved when the value is. If {@code value} is not a promise, - * then the return promise will be immediately resolved. - * @param {*} value The value to observe. - * @param {Function=} opt_callback The function to call when the value is - * resolved successfully. - * @param {Function=} opt_errback The function to call when the value is - * rejected. - * @return {!webdriver.promise.Promise} A new promise. - */ - function when(value: T, opt_callback?: (value: T) => any, opt_errback?: (error: any) => any): Promise; - function when(value: Promise, opt_callback?: (value: T) => any, opt_errback?: (error: any) => any): Promise; - - /** - * Returns a promise that will be resolved with the input value in a - * fully-resolved state. If the value is an array, each element will be fully - * resolved. Likewise, if the value is an object, all keys will be fully - * resolved. In both cases, all nested arrays and objects will also be - * fully resolved. All fields are resolved in place; the returned promise will - * resolve on {@code value} and not a copy. - * - * Warning: This function makes no checks against objects that contain - * cyclical references: - * - * var value = {}; - * value['self'] = value; - * webdriver.promise.fullyResolved(value); // Stack overflow. - * - * @param {*} value The value to fully resolve. - * @return {!webdriver.promise.Promise} A promise for a fully resolved version - * of the input value. - */ - function fullyResolved(value: any): Promise; - - /** - * Changes the default flow to use when no others are active. - * @param {!webdriver.promise.ControlFlow} flow The new default flow. - * @throws {Error} If the default flow is not currently active. - */ - function setDefaultFlow(flow: ControlFlow): void; - - //endregion - /** * Represents the eventual value of a completed operation. Each promise may be * in one of three states: pending, resolved, or rejected. Each promise starts @@ -1273,9 +1292,9 @@ declare module webdriver { * @return {!until.Condition.} A new condition. */ function ableToSwitchToFrame(frame: number): Condition; - function ableToSwitchToFrame(frame: WebElement): Condition; + function ableToSwitchToFrame(frame: IWebElement): Condition; function ableToSwitchToFrame(frame: Locator): Condition; - function ableToSwitchToFrame(frame: (webdriver: WebDriver) => WebElement): Condition; + function ableToSwitchToFrame(frame: (webdriver: WebDriver) => IWebElement): Condition; function ableToSwitchToFrame(frame: any): Condition; /** @@ -1293,7 +1312,7 @@ declare module webdriver { * @return {!until.Condition.} The new condition. * @see webdriver.WebDriver#isEnabled */ - function elementIsDisabled(element: WebElement): Condition; + function elementIsDisabled(element: IWebElement): Condition; /** * Creates a condition that will wait for the given element to be enabled. @@ -1302,7 +1321,7 @@ declare module webdriver { * @return {!until.Condition.} The new condition. * @see webdriver.WebDriver#isEnabled */ - function elementIsEnabled(element: WebElement): Condition; + function elementIsEnabled(element: IWebElement): Condition; /** * Creates a condition that will wait for the given element to be deselected. @@ -1311,7 +1330,7 @@ declare module webdriver { * @return {!until.Condition.} The new condition. * @see webdriver.WebDriver#isSelected */ - function elementIsNotSelected(element: WebElement): Condition; + function elementIsNotSelected(element: IWebElement): Condition; /** * Creates a condition that will wait for the given element to be in the DOM, @@ -1321,7 +1340,7 @@ declare module webdriver { * @return {!until.Condition.} The new condition. * @see webdriver.WebDriver#isDisplayed */ - function elementIsNotVisible(element: WebElement): Condition; + function elementIsNotVisible(element: IWebElement): Condition; /** * Creates a condition that will wait for the given element to be selected. @@ -1329,7 +1348,7 @@ declare module webdriver { * @return {!until.Condition.} The new condition. * @see webdriver.WebDriver#isSelected */ - function elementIsSelected(element: WebElement): Condition; + function elementIsSelected(element: IWebElement): Condition; /** * Creates a condition that will wait for the given element to become visible. @@ -1338,7 +1357,7 @@ declare module webdriver { * @return {!until.Condition.} The new condition. * @see webdriver.WebDriver#isDisplayed */ - function elementIsVisible(element: WebElement): Condition; + function elementIsVisible(element: IWebElement): Condition; /** * Creates a condition that will loop until an element is @@ -1348,8 +1367,8 @@ declare module webdriver { * to use. * @return {!until.Condition.} The new condition. */ - function elementLocated(locator: Locator): Condition; - function elementLocated(locator: any): Condition; + function elementLocated(locator: Locator): Condition; + function elementLocated(locator: any): Condition; /** * Creates a condition that will wait for the given element's @@ -1361,7 +1380,7 @@ declare module webdriver { * @return {!until.Condition.} The new condition. * @see webdriver.WebDriver#getText */ - function elementTextContains(element: WebElement, substr: string): Condition; + function elementTextContains(element: IWebElement, substr: string): Condition; /** * Creates a condition that will wait for the given element's @@ -1373,7 +1392,7 @@ declare module webdriver { * @return {!until.Condition.} The new condition. * @see webdriver.WebDriver#getText */ - function elementTextIs(element: WebElement, text: string): Condition; + function elementTextIs(element: IWebElement, text: string): Condition; /** * Creates a condition that will wait for the given element's @@ -1385,7 +1404,7 @@ declare module webdriver { * @return {!until.Condition.} The new condition. * @see webdriver.WebDriver#getText */ - function elementTextMatches(element: WebElement, regex: RegExp): Condition; + function elementTextMatches(element: IWebElement, regex: RegExp): Condition; /** * Creates a condition that will loop until at least one element is @@ -1396,8 +1415,8 @@ declare module webdriver { * @return {!until.Condition.>} The new * condition. */ - function elementsLocated(locator: Locator): Condition; - function elementsLocated(locator: any): Condition; + function elementsLocated(locator: Locator): Condition; + function elementsLocated(locator: any): Condition; /** * Creates a condition that will wait for the given element to become stale. An @@ -1407,7 +1426,7 @@ declare module webdriver { * @param {!webdriver.WebElement} element The element that should become stale. * @return {!until.Condition.} The new condition. */ - function stalenessOf(element: WebElement): Condition; + function stalenessOf(element: IWebElement): Condition; /** * Creates a condition that will wait for the current page's title to contain @@ -1597,7 +1616,7 @@ declare module webdriver { * Defaults to (0, 0). * @return {!webdriver.ActionSequence} A self reference. */ - mouseMove(location: WebElement, opt_offset?: ILocation): ActionSequence; + mouseMove(location: IWebElement, opt_offset?: ILocation): ActionSequence; mouseMove(location: ILocation): ActionSequence; /** @@ -1622,7 +1641,7 @@ declare module webdriver { * first argument. * @return {!webdriver.ActionSequence} A self reference. */ - mouseDown(opt_elementOrButton?: WebElement, opt_button?: number): ActionSequence; + mouseDown(opt_elementOrButton?: IWebElement, opt_button?: number): ActionSequence; mouseDown(opt_elementOrButton?: number): ActionSequence; /** @@ -1645,7 +1664,7 @@ declare module webdriver { * first argument. * @return {!webdriver.ActionSequence} A self reference. */ - mouseUp(opt_elementOrButton?: WebElement, opt_button?: number): ActionSequence; + mouseUp(opt_elementOrButton?: IWebElement, opt_button?: number): ActionSequence; mouseUp(opt_elementOrButton?: number): ActionSequence; /** @@ -1657,8 +1676,8 @@ declare module webdriver { * location to drag to, either as another WebElement or an offset in pixels. * @return {!webdriver.ActionSequence} A self reference. */ - dragAndDrop(element: WebElement, location: WebElement): ActionSequence; - dragAndDrop(element: WebElement, location: ILocation): ActionSequence; + dragAndDrop(element: IWebElement, location: IWebElement): ActionSequence; + dragAndDrop(element: IWebElement, location: ILocation): ActionSequence; /** * Clicks a mouse button. @@ -1676,7 +1695,7 @@ declare module webdriver { * first argument. * @return {!webdriver.ActionSequence} A self reference. */ - click(opt_elementOrButton?: WebElement, opt_button?: number): ActionSequence; + click(opt_elementOrButton?: IWebElement, opt_button?: number): ActionSequence; click(opt_elementOrButton?: number): ActionSequence; /** @@ -1698,7 +1717,7 @@ declare module webdriver { * first argument. * @return {!webdriver.ActionSequence} A self reference. */ - doubleClick(opt_elementOrButton?: WebElement, opt_button?: number): ActionSequence; + doubleClick(opt_elementOrButton?: IWebElement, opt_button?: number): ActionSequence; doubleClick(opt_elementOrButton?: number): ActionSequence; /** @@ -3417,7 +3436,270 @@ declare module webdriver { * }); * */ - class WebElement { + + interface IWebElement { + //region Methods + + /** + * Schedules a command to click on this element. + * @return {!webdriver.promise.Promise} A promise that will be resolved when + * the click command has completed. + */ + click(): webdriver.promise.Promise; + + /** + * Schedules a command to type a sequence on the DOM element represented by this + * instance. + *

+ * Modifier keys (SHIFT, CONTROL, ALT, META) are stateful; once a modifier is + * processed in the keysequence, that key state is toggled until one of the + * following occurs: + *

    + *
  • The modifier key is encountered again in the sequence. At this point the + * state of the key is toggled (along with the appropriate keyup/down events). + *
  • + *
  • The {@code webdriver.Key.NULL} key is encountered in the sequence. When + * this key is encountered, all modifier keys current in the down state are + * released (with accompanying keyup events). The NULL key can be used to + * simulate common keyboard shortcuts: + * + * element.sendKeys("text was", + * webdriver.Key.CONTROL, "a", webdriver.Key.NULL, + * "now text is"); + * // Alternatively: + * element.sendKeys("text was", + * webdriver.Key.chord(webdriver.Key.CONTROL, "a"), + * "now text is"); + *
  • + *
  • The end of the keysequence is encountered. When there are no more keys + * to type, all depressed modifier keys are released (with accompanying keyup + * events). + *
  • + *
+ * Note: On browsers where native keyboard events are not yet + * supported (e.g. Firefox on OS X), key events will be synthesized. Special + * punctionation keys will be synthesized according to a standard QWERTY en-us + * keyboard layout. + * + * @param {...string} var_args The sequence of keys to + * type. All arguments will be joined into a single sequence (var_args is + * permitted for convenience). + * @return {!webdriver.promise.Promise} A promise that will be resolved when all + * keys have been typed. + */ + sendKeys(...var_args: string[]): webdriver.promise.Promise; + + /** + * Schedules a command to query for the tag/node name of this element. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * element's tag name. + */ + getTagName(): webdriver.promise.Promise; + + /** + * Schedules a command to query for the computed style of the element + * represented by this instance. If the element inherits the named style from + * its parent, the parent will be queried for its value. Where possible, color + * values will be converted to their hex representation (e.g. #00ff00 instead of + * rgb(0, 255, 0)). + *

+ * Warning: the value returned will be as the browser interprets it, so + * it may be tricky to form a proper assertion. + * + * @param {string} cssStyleProperty The name of the CSS style property to look + * up. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * requested CSS value. + */ + getCssValue(cssStyleProperty: string): webdriver.promise.Promise; + + /** + * Schedules a command to query for the value of the given attribute of the + * element. Will return the current value even if it has been modified after the + * page has been loaded. More exactly, this method will return the value of the + * given attribute, unless that attribute is not present, in which case the + * value of the property with the same name is returned. If neither value is + * set, null is returned. The "style" attribute is converted as best can be to a + * text representation with a trailing semi-colon. The following are deemed to + * be "boolean" attributes and will be returned as thus: + * + *

async, autofocus, autoplay, checked, compact, complete, controls, declare, + * defaultchecked, defaultselected, defer, disabled, draggable, ended, + * formnovalidate, hidden, indeterminate, iscontenteditable, ismap, itemscope, + * loop, multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open, + * paused, pubdate, readonly, required, reversed, scoped, seamless, seeking, + * selected, spellcheck, truespeed, willvalidate + * + *

Finally, the following commonly mis-capitalized attribute/property names + * are evaluated as expected: + *

    + *
  • "class" + *
  • "readonly" + *
+ * @param {string} attributeName The name of the attribute to query. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * attribute's value. + */ + getAttribute(attributeName: string): webdriver.promise.Promise; + + /** + * Get the visible (i.e. not hidden by CSS) innerText of this element, including + * sub-elements, without any leading or trailing whitespace. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * element's visible text. + */ + getText(): webdriver.promise.Promise; + + /** + * Schedules a command to compute the size of this element's bounding box, in + * pixels. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * element's size as a {@code {width:number, height:number}} object. + */ + getSize(): webdriver.promise.Promise; + + /** + * Schedules a command to compute the location of this element in page space. + * @return {!webdriver.promise.Promise} A promise that will be resolved to the + * element's location as a {@code {x:number, y:number}} object. + */ + getLocation(): webdriver.promise.Promise; + + /** + * Schedules a command to query whether the DOM element represented by this + * instance is enabled, as dicted by the {@code disabled} attribute. + * @return {!webdriver.promise.Promise} A promise that will be resolved with + * whether this element is currently enabled. + */ + isEnabled(): webdriver.promise.Promise; + + /** + * Schedules a command to query whether this element is selected. + * @return {!webdriver.promise.Promise} A promise that will be resolved with + * whether this element is currently selected. + */ + isSelected(): webdriver.promise.Promise; + + /** + * Schedules a command to submit the form containing this element (or this + * element if it is a FORM element). This command is a no-op if the element is + * not contained in a form. + * @return {!webdriver.promise.Promise} A promise that will be resolved when + * the form has been submitted. + */ + submit(): webdriver.promise.Promise; + + /** + * Schedules a command to clear the {@code value} of this element. This command + * has no effect if the underlying DOM element is neither a text INPUT element + * nor a TEXTAREA element. + * @return {!webdriver.promise.Promise} A promise that will be resolved when + * the element has been cleared. + */ + clear(): webdriver.promise.Promise; + + /** + * Schedules a command to test whether this element is currently displayed. + * @return {!webdriver.promise.Promise} A promise that will be resolved with + * whether this element is currently visible on the page. + */ + isDisplayed(): webdriver.promise.Promise; + + /** + * Schedules a command to retrieve the outer HTML of this element. + * @return {!webdriver.promise.Promise} A promise that will be resolved with + * the element's outer HTML. + */ + getOuterHtml(): webdriver.promise.Promise; + + /** + * @return {!webdriver.promise.Promise.} A promise + * that resolves to this element's JSON representation as defined by the + * WebDriver wire protocol. + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol + */ + getId(): webdriver.promise.Promise + + /** + * Schedules a command to retrieve the inner HTML of this element. + * @return {!webdriver.promise.Promise} A promise that will be resolved with the + * element's inner HTML. + */ + getInnerHtml(): webdriver.promise.Promise; + + //endregion + } + + interface IWebElementFinders { + /** + * Schedule a command to find a descendant of this element. If the element + * cannot be found, a {@code bot.ErrorCode.NO_SUCH_ELEMENT} result will + * be returned by the driver. Unlike other commands, this error cannot be + * suppressed. In other words, scheduling a command to find an element doubles + * as an assert that the element is present on the page. To test whether an + * element is present on the page, use {@code #isElementPresent} instead. + * + *

The search criteria for an element may be defined using one of the + * factories in the {@link webdriver.By} namespace, or as a short-hand + * {@link webdriver.By.Hash} object. For example, the following two statements + * are equivalent: + *

+         * var e1 = element.findElement(By.id('foo'));
+         * var e2 = element.findElement({id:'foo'});
+         * 
+ * + *

You may also provide a custom locator function, which takes as input + * this WebDriver instance and returns a {@link webdriver.WebElement}, or a + * promise that will resolve to a WebElement. For example, to find the first + * visible link on a page, you could write: + *

+         * var link = element.findElement(firstVisibleLink);
+         *
+         * function firstVisibleLink(element) {
+         *   var links = element.findElements(By.tagName('a'));
+         *   return webdriver.promise.filter(links, function(link) {
+         *     return links.isDisplayed();
+         *   }).then(function(visibleLinks) {
+         *     return visibleLinks[0];
+         *   });
+         * }
+         * 
+ * + * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The + * locator strategy to use when searching for the element. + * @return {!webdriver.WebElement} A WebElement that can be used to issue + * commands against the located element. If the element is not found, the + * element will be invalidated and all scheduled commands aborted. + */ + findElement(locator: Locator): WebElementPromise; + findElement(locator: any): WebElementPromise; + + /** + * Schedules a command to test if there is at least one descendant of this + * element that matches the given search criteria. + * + * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The + * locator strategy to use when searching for the element. + * @return {!webdriver.promise.Promise.} A promise that will be + * resolved with whether an element could be located on the page. + */ + isElementPresent(locator: Locator): webdriver.promise.Promise; + isElementPresent(locator: any): webdriver.promise.Promise; + + /** + * Schedules a command to find all of the descendants of this element that + * match the given search criteria. + * + * @param {!(webdriver.Locator|webdriver.By.Hash|Function)} locator The + * locator strategy to use when searching for the elements. + * @return {!webdriver.promise.Promise.>} A + * promise that will resolve to an array of WebElements. + */ + findElements(locator: Locator): webdriver.promise.Promise; + findElements(locator: any): webdriver.promise.Promise; + } + + class WebElement implements IWebElement, IWebElementFinders { //region Constructors /** @@ -3847,7 +4129,7 @@ declare module webdriver { className(value: string): Locator; css(value: string): Locator; id(value: string): Locator; - js(script: any, ...var_args): (WebDriver) => webdriver.promise.Promise; + js(script: any, ...var_args: any[]): (WebDriver: webdriver.WebDriver) => webdriver.promise.Promise; linkText(value: string): Locator; name(value: string): Locator; partialLinkText(value: string): Locator;