import { Ability , ConfigurationError , LogicError , UsesAbilities } from '@serenity-js/core' ; import { ActionSequence , ElementArrayFinder , ElementFinder , Locator , ProtractorBrowser } from 'protractor' ; import { AlertPromise , Capabilities , Navigation , Options , WebElement , WebElementPromise } from 'selenium-webdriver' ; import { promiseOf } from '../../promiseOf' ; desc An  {@link @serenity-js/core/lib/screenplay~Ability} that enables the  Actor to interact with web front-ends using  protractor .
 *
 *  example see https public implements serenity-js see {@link @serenity-js/core/lib/screenplay/actor~Actor} export class BrowseTheWeb implements Ability { private private lastScriptExecutionSummary : LastScriptExecutionSummary ; private private originalWindowHandle : string ; desc param { ProtractorBrowser } browser returns { BrowseTheWeb } static using ( browser ) { return new BrowseTheWeb ( browser ) ; } desc Used to access the Actor's ability to  BrowseTheWeb from within the  Interaction classes,
     *  such as  Navigate .
     *
     *  param { UsesAbilities } actor return { BrowseTheWeb } static as ( actor ) { return actor . abilityTo ( BrowseTheWeb ) ; } param { ProtractorBrowser } browser constructor ( protected browser ) { } desc param { string } destination param { number ? } timeoutInMillis returns { Promise < void > } get ( destination , timeoutInMillis ? ) { return promiseOf ( this . browser . get ( destination , timeoutInMillis ) . then ( ( ) => this . browser . getWindowHandle ( ) ) . then ( handle => { this . originalWindowHandle = handle ; } ) ) ; } desc returns { Navigation } navigate ( ) { return this . browser . navigate ( ) ; } desc returns { ActionSequence } see https actions ( ) { return this . browser . actions ( ) ; } desc returns { Options } see https manage ( ) { return this . browser . manage ( ) ; } desc returns { AlertPromise } see https alert ( ) { return this . browser . switchTo ( ) . alert ( ) ; } desc Switches the focus to a [`frame`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/frame) or
     *  [`iframe`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) identified by `elementOrIndexOrName`,
     *  which can be specified either as  selenium-webdriver , the name of the frame, or its index.
     *
     *  param { number | string | WebElement } elementOrIndexOrName returns { Promise < void > } switchToFrame ( elementOrIndexOrName ) { return promiseOf ( this . browser . switchTo ( ) . frame ( elementOrIndexOrName as any ) ) ; } desc returns { Promise < void > } switchToParentFrame ( ) { return promiseOf ( this . browser . driver . switchToParentFrame ( ) ) ; } desc returns { Promise < void > } switchToDefaultContent ( ) { return promiseOf ( this . browser . switchTo ( ) . defaultContent ( ) ) ; } desc param { string | number } nameOrHandleOrIndex returns { Promise < void > } switchToWindow ( nameOrHandleOrIndex ) { return typeof nameOrHandleOrIndex === 'string' ? this . switchToWindowByNameOrHandle ( nameOrHandleOrIndex ) : this . switchToWindowByIndex ( nameOrHandleOrIndex ) ; } param { string } nameOrHandle private private switchToWindowByNameOrHandle ( nameOrHandle ) { return promiseOf ( this . browser . switchTo ( ) . window ( nameOrHandle ) ) ; } param { number } index private private switchToWindowByIndex ( index ) { return promiseOf ( this . browser . getAllWindowHandles ( ) . then ( handles => { const handle = handles [ index ] ; if ( ! handle ) { throw new LogicError ( `Window ${ index } doesn't exist` ) ; } return this . browser . switchTo ( ) . window ( handle ) ; } ) ) ; } desc Switches the window back to the original one that was used to call  get .
     *
     *  returns { Promise < void > } switchToOriginalWindow ( ) { return this . originalWindowHandle ? promiseOf ( this . browser . switchTo ( ) . window ( this . originalWindowHandle ) ) : Promise . resolve ( ) ; } desc returns { Promise < string > } see get getOriginalWindowHandle ( ) { return Promise . resolve ( this . originalWindowHandle ) ; } desc Returns the current window handle.
     *  Please note that the current handle changes with each browser window you  Switch to.
     *
     *  returns { Promise < string > } see get getCurrentWindowHandle ( ) { return promiseOf ( this . browser . getWindowHandle ( ) ) ; } desc returns { Promise < string [ ] > } getAllWindowHandles ( ) { return promiseOf ( this . browser . getAllWindowHandles ( ) ) ; } desc returns { Promise < void > } closeCurrentWindow ( ) { return promiseOf ( this . browser . close ( ) ) ; } desc param { Locator } locator returns { ElementFinder } locate ( locator ) { return this . browser . element ( locator ) ; } desc param { Locator } locator returns { ElementArrayFinder } locateAll ( locator ) { return this . browser . element . all ( locator ) ; } desc example param { boolean } enable returns { Promise < boolean > } enableAngularSynchronisation ( enable ) { return promiseOf ( this . browser . waitForAngularEnabled ( enable ) ) ; } desc example see https see https param { string } description param { string | Function } script param { any [ ] } args returns { Promise < any > } see BrowseTheWeb executeScript ( description , script , ... args ) { return promiseOf ( this . browser . executeScriptWithDescription ( script , description , ... args ) ) . then ( result => { this . lastScriptExecutionSummary = new LastScriptExecutionSummary ( result ) ; return result ; } ) ; } desc A simplified version of  BrowseTheWeb that doesn't affect  LastScriptExecution . result .
     *
     *  param { Function } fn param { Parameters < fn > } args returns { Promise < ReturnType < fn > > } executeFunction < F extends ( ... args : any [ ] ) => any > ( fn , ... args ) { return promiseOf ( this . browser . executeScriptWithDescription ( fn , fn . name , ... args ) ) ; } desc Schedules a command to execute asynchronous JavaScript in the context of the currently selected frame or window.
     *  The script fragment will be executed as the body of an anonymous function.
     *  If the script is provided as a function object, that function will be converted to a string for injection
     *  into the target window.
     *
     *  Any arguments provided in addition to the script will be included as script arguments and may be referenced
     *  using the `arguments` object. Arguments may be a `boolean`, `number`, `string` or `WebElement`
     *  Arrays and objects may also be used as script arguments as long as each item adheres
     *  to the types previously mentioned.
     *
     *  Unlike executing synchronous JavaScript with  BrowseTheWeb ,
     *  scripts executed with this function must explicitly signal they are finished by invoking the provided callback.
     *
     *  This callback will always be injected into the executed function as the last argument,
     *  and thus may be referenced with `arguments[arguments.length - 1]`.
     *
     *  The following steps will be taken for resolving this functions return value against
     *  the first argument to the script's callback function:
     *
     *  - For a HTML element, the value will resolve to a WebElement
     *  - Null and undefined return values will resolve to null
     *  - Booleans, numbers, and strings will resolve as is
     *  - Functions will resolve to their string representation
     *  - For arrays and objects, each member item will be converted according to the rules above
     *
     *  example example see https see https param { string | Function } script param { any [ ] } args returns { Promise < any > } see BrowseTheWeb executeAsyncScript ( script , ... args ) { return promiseOf ( this . browser . executeAsyncScript ( script , ... args ) ) . then ( result => { this . lastScriptExecutionSummary = new LastScriptExecutionSummary ( result ) ; return result ; } ) ; } desc return { Promise < string > } takeScreenshot ( ) { return promiseOf ( this . browser . takeScreenshot ( ) ) ; } desc see https returns { Promise < string > } getTitle ( ) { return promiseOf ( this . browser . getTitle ( ) ) ; } desc returns { Promise < string > } getCurrentUrl ( ) { return promiseOf ( this . browser . getCurrentUrl ( ) ) ; } desc returns { Promise < Capabilities > } getCapabilities ( ) { return promiseOf ( this . browser . getCapabilities ( ) ) ; } desc param { number } millis returns { Promise < void > } sleep ( millis ) { return promiseOf ( this . browser . sleep ( millis ) ) ; } desc param { function ( ) : Promise < boolean > } condition param { number } timeoutInMillis returns { Promise < boolean > } wait ( condition , timeoutInMillis ) { return promiseOf ( this . browser . wait ( condition , timeoutInMillis ) ) ; } desc Returns the last result of calling  BrowseTheWeb *  or  BrowseTheWeb returns { any } getLastScriptExecutionResult ( ) { if ( ! this . lastScriptExecutionSummary ) { throw new LogicError ( `Make sure to execute a script before checking on the result` ) ; } return this . lastScriptExecutionSummary . result ; } desc example example example param { string } path returns { T } throws param < T = any > ( path ) { return path . split ( '.' ) . reduce ( ( config , segment ) => { if ( ! ( config && config [ segment ] !== undefined ) ) { throw new ConfigurationError ( `Protractor param '${ path }' is undefined` ) ; } return config [ segment ] ; } , this . browser . params ) ; } } package class LastScriptExecutionSummary { constructor ( public readonly result ) { } }