UNPKG

@theintern/leadfoot

Version:

Leadfoot. A JavaScript client library that brings cross-platform consistency to the Selenium WebDriver API.

1,208 lines (1,207 loc) 60.9 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __spreadArray = (this && this.__spreadArray) || function (to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = require("./lib/util"); var common_1 = require("@theintern/common"); var Session_1 = __importDefault(require("./Session")); var Locator_1 = __importDefault(require("./lib/Locator")); /** * The Command class is a chainable, subclassable object type that can be used * to execute commands serially against a remote WebDriver environment. The * standard Command class includes methods from the [[Session]] and [[Element]] * classes, so you can perform all standard session and element operations that * come with Leadfoot without being forced to author long promise chains. * * In order to use the Command class, you first need to pass it a [[Session]] * instance for it to use: * * ```js * const command = new Command(session); * ``` * * Once you have created the Command, you can then start chaining methods, and * they will execute in order one after another: * * ```js * command.get('http://example.com') * .findByTagName('h1') * .getVisibleText() * .then(function (text) { * assert.strictEqual(text, 'Example Domain'); * }); * ``` * * Because these operations are asynchronous, you need to use a `then` callback * in order to retrieve the value from the last method. Command objects are * PromiseLikes, which means that they can be used with any Promises/A+ or * ES6-conformant Promises implementation, though there are some specific * differences in the arguments and context that are provided to callbacks; see * [[Command.Command.then]] for more details. * * Because Commands are promise-like, they may also be used with `async/await`: * * ```js * const page = await command.get('http://example.com'); * const h1 = await page.findByTagName('h1'); * const text = await h1.getVisibleText(); * assert.strictEqual(text, 'Example Domain'); * ``` * * --- * * Each call on a Command generates a new Command object, which means that * certain operations can be parallelised: * * ```js * command = command.get('http://example.com'); * Promise.all([ * command.getPageTitle(), * command.findByTagName('h1').getVisibleText() * ]).then(results => { * assert.strictEqual(results[0], results[1]); * }); * ``` * * In this example, the commands on line 3 and 4 both depend upon the `get` * call completing successfully but are otherwise independent of each other and * so execute here in parallel. This is different from commands in Intern 1 * which were always chained onto the last called method within a given test. * * --- * * Command objects actually encapsulate two different types of interaction: * *session* interactions, which operate against the entire browser session, * and *element* interactions, which operate against specific elements taken * from the currently loaded page. Things like navigating the browser, moving * the mouse cursor, and executing scripts are session interactions; things * like getting text displayed on the page, typing into form fields, and * getting element attributes are element interactions. * * Session interactions can be performed at any time, from any Command. On the * other hand, to perform element interactions, you first need to retrieve one * or more elements to interact with. This can be done using any of the `find` * or `findAll` methods, by the `getActiveElement` method, or by returning * elements from `execute` or `executeAsync` calls. The retrieved elements are * stored internally as the *element context* of all chained Commands. When an * element method is called on a chained Command with a single element context, * the result will be returned as-is: * * ```js * command = command.get('http://example.com') * // finds one element -> single element context * .findByTagName('h1') * .getVisibleText() * .then(text => { * // `text` is the text from the element context * assert.strictEqual(text, 'Example Domain'); * }); * ``` * * When an element method is called on a chained Command with a multiple * element context, the result will be returned as an array: * * ```js * command = command.get('http://example.com') * // finds multiple elements -> multiple element context * .findAllByTagName('p') * .getVisibleText() * .then(texts => { * // `texts` is an array of text from each of the `p` elements * assert.deepEqual(texts, [ * 'This domain is established to be used for […]', * 'More information...' * ]); * }); * ``` * * The `find` and `findAll` methods are special and change their behaviour * based on the current element filtering state of a given command. If a * command has been filtered by element, the `find` and `findAll` commands will * only find elements *within* the currently filtered set of elements. * Otherwise, they will find elements throughout the page. * * Some method names, like `click`, are identical for both Session and Element * APIs; in this case, the element APIs are suffixed with the word `Element` in * order to identify them uniquely. * * --- * * Commands can be subclassed in order to add additional functionality without * making direct modifications to the default Command prototype that might * break other parts of the system: * * ```ts * class CustomCommand extends Command { * login(username: string, password: string) { * return new this.constructor(this, function () { * return this.parent * .findById('username') * .click() * .type(username) * .end() * * .findById('password') * .click() * .type(password) * .end() * * .findById('login') * .click() * .end(); * }); * } * } * ``` * * > ⚠️Note that returning `this`, or a command chain starting from `this`, * from a callback or command initialiser will deadlock the Command, as it * waits for itself to settle before settling. */ var Command = /** @class */ (function (_super) { __extends(Command, _super); /** * @param parent The parent command that this command is chained to, or a * [[Sesssion]] object if this is the first command in a command chain. * * @param initialiser A function that will be executed when all parent * commands have completed execution. This function can create a new * context for this command by calling the passed `setContext` function any * time prior to resolving the Promise that it returns. If no context is * explicitly provided, the context from the parent command will be used. * * @param errback A function that will be executed if any parent commands * failed to complete successfully. This function can create a new context * for the current command by calling the passed `setContext` function any * time prior to resolving the Promise that it returns. If no context is * explicitly provided, the context from the parent command will be used. */ // TODO: Need to show that parent is mixed into this Command function Command(parentOrSession, initialiser, errback) { var _this = _super.call(this) || this; var self = _this; var session; var trace = {}; function setContext(contextValue) { var context; if (!Array.isArray(contextValue)) { context = [contextValue]; context.isSingle = true; } else { context = contextValue; } var parent = parentOrSession; // If the context being set has depth, then it is coming from // `Command#end`, or someone smart knows what they are doing; do // not change the depth if (!('depth' in context)) { context.depth = parent ? parent.context.depth + 1 : 0; } self._context = context; } function fixStack(error) { error.stack = error.stack + util_1.trimStack(trace.stack); throw error; } if (parentOrSession instanceof Command) { _this._parent = parentOrSession; session = _this._session = parentOrSession.session; } else if (parentOrSession instanceof Session_1.default) { session = _this._session = parentOrSession; parentOrSession = null; } else { throw new Error('A parent Command or Session must be provided to a new Command'); } // Add any custom functions from the session to this command object so // they can be accessed automatically using the fluid interfaces // TODO: Test util_1.getMethods(session).forEach(function (name) { var key = name; if (session[key] !== Session_1.default.prototype[key]) { Command.addSessionMethod(_this, key, session[key]); } }); Error.captureStackTrace(trace, Command); // parentCommand will be null if parentOrSession was a session var parentCommand = parentOrSession; _this._task = (parentCommand ? parentCommand.promise : common_1.Task.resolve(undefined)) .then(function (returnValue) { self._context = parentCommand ? parentCommand.context : TOP_CONTEXT; return returnValue; }, function (error) { self._context = parentCommand ? parentCommand.context : TOP_CONTEXT; throw error; }) .then(initialiser && function (returnValue) { return common_1.Task.resolve(returnValue) .then(initialiser.bind(self, setContext)) .catch(fixStack); }, errback && function (error) { return common_1.Task.reject(error) .catch(errback.bind(self, setContext)) .catch(fixStack); }); return _this; } /** * Augments `target` with a conversion of the `originalFn` method that * enables its use with a Command object. This can be used to easily add * new methods from any custom object that implements the Session API to * any target object that implements the Command API. * * Functions that are copied may have the following extra properties in * order to change the way that Command works with these functions: * * * `createsContext` (boolean): If this property is specified, the return * value from the function will be used as the new context for the * returned Command. * * `usesElement` (boolean): If this property is specified, element(s) * from the current context will be used as the first argument to the * function, if the explicitly specified first argument is not already an * element. * * @param {module:leadfoot/Command} target * @param {string} key * @param {Function} originalFn */ Command.addSessionMethod = function (target, key, originalFn) { // Checking for private/non-functions here deduplicates this logic; // otherwise it would need to exist in both the Command constructor // (for copying functions from sessions) as well as the Command factory // below if (key.charAt(0) !== '_' && !target[key] && typeof originalFn === 'function') { // Regarding typing, <U, P, S> is the generic type of the Command that // will be created. <P, any, S> is the type of *this* command, which will // be the parent of the created Command. target[key] = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return new this.constructor(this, function (setContext) { var parentContext = this._context; var session = this._session; var promise; // The function may have come from a session object // prototype but have been overridden on the actual session // instance; in such a case, the overridden function should // be used instead of the one from the original source // object. The original source object may still be used, // however, if the function is being added like a mixin and // does not exist on the actual session object for this // session var fn = session[key] || originalFn; if (fn.usesElement && parentContext.length && (!args[0] || !args[0].elementId)) { // Defer converting arguments into an array until it is // necessary to avoid overhead args = Array.prototype.slice.call(args, 0); if (parentContext.isSingle) { promise = fn.apply(session, [parentContext[0]].concat(args)); } else { promise = common_1.Task.all(parentContext.map(function (element) { return fn.apply(session, [element].concat(args)); })); } } else { promise = fn.apply(session, args); } if (fn.createsContext) { promise = promise.then(function (newContext) { setContext(newContext); return newContext; }); } return promise; }); }; } }; /** * Augments `target` with a method that will call `key` on all context * elements stored within `target`. This can be used to easily add new * methods from any custom object that implements the Element API to any * target object that implements the Command API. * * Functions that are copied may have the following extra properties in * order to change the way that Command works with these functions: * * * `createsContext` (boolean): If this property is specified, the return * value from the function will be used as the new context for the * returned Command. * * @param {module:leadfoot/Command} target * @param {string} key */ Command.addElementMethod = function (target, key) { var anyTarget = target; if (key.charAt(0) !== '_') { // some methods, like `click`, exist on both Session and Element; // deduplicate these methods by appending the element ones with // 'Element' var targetKey = key + (anyTarget[key] ? 'Element' : ''); anyTarget[targetKey] = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return new this.constructor(this, function (setContext) { var parentContext = this._context; var promise; var fn = parentContext[0] && parentContext[0][key]; if (parentContext.isSingle) { promise = fn.apply(parentContext[0], args); } else { promise = common_1.Task.all(parentContext.map(function (element) { return element[key].apply(element, args); })); } if (fn && fn.createsContext) { promise = promise.then(function (newContext) { setContext(newContext); return newContext; }); } return promise; }); }; } }; Object.defineProperty(Command.prototype, "parent", { /** * The parent Command of the Command, if one exists. This will be defined * for all commands but the top-level Session command (i.e., in most * contexts user code will call it). */ get: function () { return this._parent; }, enumerable: false, configurable: true }); Object.defineProperty(Command.prototype, "session", { /** * The parent Session of the Command. */ get: function () { return this._session; }, enumerable: false, configurable: true }); Object.defineProperty(Command.prototype, "context", { /** * The filtered elements that will be used if an element-specific method is * invoked. Note that this property is not valid until the parent Command * has been settled. The context array also has two additional properties: * * * `isSingle` (boolean): If true, the context will always contain a * single element. This is used to differentiate between methods that * should still return scalar values (`find`) and methods that should * return arrays of values even if there is only one element in the * context (`findAll`). * * `depth` (number): The depth of the context within the command chain. * This is used to prevent traversal into higher filtering levels by * [[Command.Command.end]]. */ get: function () { return this._context; }, enumerable: false, configurable: true }); Object.defineProperty(Command.prototype, "promise", { /** * The underlying Promise for the Command. * * @readonly */ get: function () { return this._task; }, enumerable: false, configurable: true }); /** * Pauses execution of the next command in the chain for `ms` milliseconds. * * @param ms Time to delay, in milliseconds. */ Command.prototype.sleep = function (ms) { return new this.constructor(this, function () { return util_1.sleep(ms); }); }; /** * Ends the most recent filtering operation in the current Command chain * and returns the set of matched elements to the previous state. This is * equivalent to the `jQuery#end` method. * * ```js * command * .findById('parent') // sets filter to #parent * .findByClassName('child') // sets filter to all .child inside #parent * .getVisibleText() * .then(function (visibleTexts) { * // all the visible texts from the children * }) * .end() // resets filter to #parent * .end(); // resets filter to nothing (the whole document) * ``` * * @param numCommandsToPop The number of element contexts to pop. Defaults * to 1. */ Command.prototype.end = function (numCommandsToPop) { if (numCommandsToPop === void 0) { numCommandsToPop = 1; } return new this.constructor(this, function (setContext) { var command = this; var depth = this.context.depth; while (depth && numCommandsToPop && (command = command.parent)) { if (command.context.depth != null && command.context.depth < depth) { --numCommandsToPop; depth = command.context.depth; } } setContext(command.context); }); }; /** * Adds a callback to be invoked once the previously chained operation has * completed. * * This method is compatible with the `Promise#then` API, with two * important differences: * * 1. The context (`this`) of the callback is set to the Command object, * rather than being `undefined`. This allows promise helpers to be * created that can retrieve the appropriate session and element * contexts for execution. * 2. A second non-standard `setContext` argument is passed to the * callback. This `setContext` function can be called at any time before * the callback fulfills its return value and expects either a single * [[Element]] or an array of Elements to be provided as its only * argument. The provided element(s) will be used as the context for * subsequent element method invocations (`click`, etc.). If the * `setContext` method is not called, the element context from the * parent will be passed through unmodified. */ Command.prototype.then = function (callback, errback) { function runCallback(newCommand, callback, errback, value, setContext) { var returnValue = callback ? callback.call(newCommand, value, setContext) : errback.call(newCommand, value); // If someone returns `this` (or a chain starting from `this`) from // the callback, it will cause a deadlock where the child command // is waiting for the child command to resolve if (returnValue instanceof Command) { // maybeCommand can be a Session or a Command, both of which // inherit from Locator var maybeCommand = returnValue; do { if (maybeCommand === newCommand) { throw new Error('Deadlock: do not use `return this` from a Command callback'); } } while ((maybeCommand = getParent(maybeCommand))); } return returnValue; } return new this.constructor(this, callback ? function (setContext, value) { return runCallback(this, callback, undefined, value, setContext); } : undefined, errback ? function (setContext, value) { return runCallback(this, undefined, errback, value, setContext); } : undefined); }; /** * Adds a callback to be invoked when any of the previously chained * operations have failed. */ Command.prototype.catch = function (errback) { return this.then(null, errback); }; /** * Adds a callback to be invoked once the previously chained operations * have resolved. */ Command.prototype.finally = function (callback) { this._task = this._task.finally(callback); return this; }; /** * Cancels all outstanding chained operations of the Command. Calling this * method will cause this command and all subsequent chained commands to * fail with a CancelError. */ Command.prototype.cancel = function () { this._task.cancel(); return this; }; Command.prototype.find = function (strategy, value) { return this._callFindElementMethod('find', strategy, value); }; Command.prototype.findAll = function (strategy, value) { return this._callFindElementMethod('findAll', strategy, value); }; Command.prototype.findDisplayed = function (strategy, value) { return this._callFindElementMethod('findDisplayed', strategy, value); }; Command.prototype._callFindElementMethod = function (method, strategy, value) { return new this.constructor(this, function (setContext) { var parentContext = this._context; var task; if (parentContext.length && parentContext.isSingle) { task = parentContext[0][method](strategy, value); } else if (parentContext.length) { task = common_1.Task.all(parentContext.map(function (element) { return element[method](strategy, value); }) // findAll against an array context will result in arrays // of arrays; flatten into a single array of elments. It // would also be possible to resort in document order but // other parallel operations could not be sorted so we just // don't do it anywhere and say not to rely on a particular // order for results ).then(function (elements) { return Array.prototype.concat.apply([], elements); }); } else { task = this.session[method](strategy, value); } return task.then(function (newContext) { setContext(newContext); return newContext; }); }); }; Command.prototype._callElementMethod = function (method) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } return new this.constructor(this, function (setContext) { var parentContext = this._context; var task; var fn = parentContext[0] && parentContext[0][method]; if (parentContext.isSingle) { task = fn.apply(parentContext[0], args); } else { task = common_1.Task.all(parentContext.map(function (element) { return element[method].apply(element, args); })).then(function (values) { return Array.prototype.concat.apply([], values); }); } if (fn && fn.createsContext) { task = task.then(function (newContext) { setContext(newContext); return newContext; }); } return task; }); }; Command.prototype._callSessionMethod = function (method) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } return new this.constructor(this, function (setContext) { var parentContext = this._context; var session = this._session; var task; // The function may have come from a session object prototype but // have been overridden on the actual session instance; in such a // case, the overridden function should be used instead of the one // from the original source object. The original source object may // still be used, however, if the function is being added like a // mixin and does not exist on the actual session object for this // session var sessionMethod = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return session[method].apply(session, args); }; if (session[method].usesElement && parentContext.length && (!args[0] || !args[0].elementId)) { if (parentContext.isSingle) { task = sessionMethod.apply(void 0, __spreadArray([parentContext[0]], args)); } else { task = common_1.Task.all(parentContext.map(function (element) { return sessionMethod.apply(void 0, __spreadArray([element], args)); })).then(function (values) { return Array.prototype.concat.apply([], values); }); } } else { task = sessionMethod.apply(void 0, args); } if (session[method].createsContext) { task = task.then(function (newContext) { setContext(newContext); return newContext; }); } return task; }); }; // Session methods /** * Gets the current value of a timeout for the session. * * @param type The type of timeout to retrieve. One of 'script', * 'implicit', or 'page load'. * @returns The timeout, in milliseconds. */ Command.prototype.getTimeout = function (type) { return this._callSessionMethod('getTimeout', type); }; /** * Sets the value of a timeout for the session. * * @param type The type of timeout to set. One of 'script', 'implicit', or * 'page load'. * * @param ms The length of time to use for the timeout, in milliseconds. A * value of 0 will cause operations to time out immediately. */ Command.prototype.setTimeout = function (type, ms) { return this._callSessionMethod('setTimeout', type, ms); }; /** * Gets the identifier for the window that is currently focused. * * @returns A window handle identifier that can be used with other window * handling functions. */ Command.prototype.getCurrentWindowHandle = function () { return this._callSessionMethod('getCurrentWindowHandle'); }; /** * Gets a list of identifiers for all currently open windows. */ Command.prototype.getAllWindowHandles = function () { return this._callSessionMethod('getAllWindowHandles'); }; /** * Gets the URL that is loaded in the focused window/frame. */ Command.prototype.getCurrentUrl = function () { return this._callSessionMethod('getCurrentUrl'); }; /** * Navigates the focused window/frame to a new URL. */ Command.prototype.get = function (url) { return this._callSessionMethod('get', url); }; /** * Navigates the focused window/frame forward one page using the browser’s * navigation history. */ Command.prototype.goForward = function () { return this._callSessionMethod('goForward'); }; /** * Navigates the focused window/frame back one page using the browser’s * navigation history. */ Command.prototype.goBack = function () { return this._callSessionMethod('goBack'); }; /** * Reloads the current browser window/frame. */ Command.prototype.refresh = function () { return this._callSessionMethod('refresh'); }; /** * Executes JavaScript code within the focused window/frame. The code * should return a value synchronously. * * See [[Command.Command.executeAsync]] to execute code that returns values * asynchronously. * * @param script The code to execute. This function will always be * converted to a string, sent to the remote environment, and reassembled * as a new anonymous function on the remote end. This means that you * cannot access any variables through closure. If your code needs to get * data from variables on the local end, they should be passed using * `args`. * * @param args An array of arguments that will be passed to the executed * code. Only values that can be serialised to JSON, plus [[Element]] * objects, can be specified as arguments. * * @returns The value returned by the remote code. Only values that can be * serialised to JSON, plus DOM elements, can be returned. */ Command.prototype.execute = function (script, args) { return this._callSessionMethod('execute', script, args); }; /** * Executes JavaScript code within the focused window/frame. The code must * invoke the provided callback in order to signal that it has completed * execution. * * See [[Command.Command.execute]] to execute code that returns values * synchronously. * * See [[Command.Command.setExecuteAsyncTimeout]] to set the time until an * asynchronous script is considered timed out. * * @param script The code to execute. This function will always be * converted to a string, sent to the remote environment, and reassembled * as a new anonymous function on the remote end. This means that you * cannot access any variables through closure. If your code needs to get * data from variables on the local end, they should be passed using * `args`. * * @param args An array of arguments that will be passed to the executed * code. Only values that can be serialised to JSON, plus [[Element]] * objects, can be specified as arguments. In addition to these arguments, * a callback function will always be passed as the final argument to the * function specified in `script`. This callback function must be invoked * in order to signal that execution has completed. The return value of the * execution, if any, should be passed to this callback function. * * @returns The value returned by the remote code. Only values that can be * serialised to JSON, plus DOM elements, can be returned. */ Command.prototype.executeAsync = function (script, args) { return this._callSessionMethod('executeAsync', script, args); }; /** * Gets a screenshot of the focused window and returns it in PNG format. */ Command.prototype.takeScreenshot = function () { return this._callSessionMethod('takeScreenshot'); }; /** * Gets a list of input method editor engines available to the remote * environment. As of April 2014, no known remote environments support IME * functions. */ Command.prototype.getAvailableImeEngines = function () { return this._callSessionMethod('getAvailableImeEngines'); }; /** * Gets the currently active input method editor for the remote environment. * As of April 2014, no known remote environments support IME functions. */ Command.prototype.getActiveImeEngine = function () { return this._callSessionMethod('getActiveImeEngine'); }; /** * Returns whether or not an input method editor is currently active in the * remote environment. As of April 2014, no known remote environments * support IME functions. */ Command.prototype.isImeActivated = function () { return this._callSessionMethod('isImeActivated'); }; /** * Deactivates any active input method editor in the remote environment. * As of April 2014, no known remote environments support IME functions. */ Command.prototype.deactivateIme = function () { return this._callSessionMethod('deactivateIme'); }; /** * Activates an input method editor in the remote environment. * As of April 2014, no known remote environments support IME functions. * * @param engine The type of IME to activate. */ Command.prototype.activateIme = function (engine) { return this._callSessionMethod('activateIme', engine); }; /** * Switches the currently focused frame to a new frame. * * @param id The frame to switch to. In most environments, a number or * string value corresponds to a key in the `window.frames` object of the * currently active frame. If `null`, the topmost (default) frame will be * used. If an Element is provided, it must correspond to a `<frame>` or * `<iframe>` element. */ Command.prototype.switchToFrame = function (id) { return this._callSessionMethod('switchToFrame', id); }; /** * Switches the currently focused window to a new window. * * In environments using the JsonWireProtocol, this value corresponds to * the `window.name` property of a window. * * @param handle The handle of the window to switch to. In mobile * environments and environments based on the W3C WebDriver standard, this * should be a handle as returned by * [[Command.Command.getAllWindowHandles]]. */ Command.prototype.switchToWindow = function (handle) { return this._callSessionMethod('switchToWindow', handle); }; /** * Switches the currently focused frame to the parent of the currently * focused frame. */ Command.prototype.switchToParentFrame = function () { return this._callSessionMethod('switchToParentFrame'); }; /** * Closes the currently focused window. In most environments, after the * window has been closed, it is necessary to explicitly switch to whatever * window is now focused. */ Command.prototype.closeCurrentWindow = function () { return this._callSessionMethod('closeCurrentWindow'); }; Command.prototype.setWindowSize = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return this._callSessionMethod.apply(this, __spreadArray(['setWindowSize'], args)); }; /** * Gets the dimensions of a window. * * @param windowHandle The name of the window to query. See * [[Command.Command.switchToWindow]] to learn about valid window names. * Omit this argument to query the currently focused window. * * @returns An object describing the width and height of the window, in CSS * pixels. */ Command.prototype.getWindowSize = function (_windowHandle) { return this._callSessionMethod('getWindowSize'); }; Command.prototype.setWindowPosition = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return this._callSessionMethod.apply(this, __spreadArray(['setWindowPosition'], args)); }; /** * Gets the position of a window. * * Note that this method is not part of the W3C WebDriver standard. * * @param windowHandle The name of the window to query. See * [[Command.Command.switchToWindow]] to learn about valid window names. * Omit this argument to query the currently focused window. * * @returns An object describing the position of the window, in CSS pixels, * relative to the top-left corner of the primary monitor. If a secondary * monitor exists above or to the left of the primary monitor, these values * will be negative. */ Command.prototype.getWindowPosition = function (windowHandle) { return this._callSessionMethod('getWindowPosition', windowHandle); }; /** * Maximises a window according to the platform’s window system behaviour. * * @param windowHandle The name of the window to resize. See * [[Command.Command.switchToWindow] to learn about valid window names. * Omit this argument to resize the currently focused window. */ Command.prototype.maximizeWindow = function (windowHandle) { return this._callSessionMethod('maximizeWindow', windowHandle); }; /** * Gets all cookies set on the current page. */ Command.prototype.getCookies = function () { return this._callSessionMethod('getCookies'); }; /** * Sets a cookie on the current page. */ Command.prototype.setCookie = function (cookie) { return this._callSessionMethod('setCookie', cookie); }; /** * Clears all cookies for the current page. */ Command.prototype.clearCookies = function () { return this._callSessionMethod('clearCookies'); }; /** * Deletes a cookie on the current page. * * @param name The name of the cookie to delete. */ Command.prototype.deleteCookie = function (name) { return this._callSessionMethod('deleteCookie', name); }; /** * Gets the HTML loaded in the focused window/frame. This markup is * serialised by the remote environment so may not exactly match the HTML * provided by the Web server. */ Command.prototype.getPageSource = function () { return this._callSessionMethod('getPageSource'); }; /** * Gets the title of the top-level browsing context of the current window * or tab. */ Command.prototype.getPageTitle = function () { return this._callSessionMethod('getPageTitle'); }; /** * Gets the currently focused element from the focused window/frame. */ Command.prototype.getActiveElement = function () { return this._callSessionMethod('getActiveElement'); }; /** * Types into the focused window/frame/element. * * @param keys The text to type in the remote environment. It is possible * to type keys that do not have normal character representations (modifier * keys, function keys, etc.) as well as keys that have two different * representations on a typical US-ASCII keyboard (numpad keys); use the * values from [[keys]] to type these special characters. Any modifier keys * that are activated by this call will persist until they are deactivated. * To deactivate a modifier key, type the same modifier key a second time, * or send `\uE000` ('NULL') to deactivate all currently active modifier * keys. */ Command.prototype.pressKeys = function (keys) { return this._callSessionMethod('pressKeys', keys); }; /** * Gets the current screen orientation. */ Command.prototype.getOrientation = function () { return this._callSessionMethod('getOrientation'); }; /** * Sets the screen orientation. * * @param orientation Either 'portrait' or 'landscape'. */ Command.prototype.setOrientation = function (orientation) { return this._callSessionMethod('setOrientation', orientation); }; /** * Gets the text displayed in the currently active alert pop-up. */ Command.prototype.getAlertText = function () { return this._callSessionMethod('getAlertText'); }; /** * Types into the currently active prompt pop-up. * * @param text The text to type into the pop-up’s input box. */ Command.prototype.typeInPrompt = function (text) { return this._callSessionMethod('typeInPrompt', text); }; /** * Accepts an alert, prompt, or confirmation pop-up. Equivalent to clicking * the 'OK' button. */ Command.prototype.acceptAlert = function () { return this._callSessionMethod('acceptAlert'); }; /** * Dismisses an alert, prompt, or confirmation pop-up. Equivalent to * clicking the 'OK' button of an alert pop-up or the 'Cancel' button of a * prompt or confirmation pop-up. */ Command.prototype.dismissAlert = function () { return this._callSessionMethod('dismissAlert'); }; Command.prototype.moveMouseTo = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return this._callSessionMethod.apply(this, __spreadArray(['moveMouseTo'], args)); }; /** * Clicks a mouse button at the point where the mouse cursor is currently * positioned. This method may fail to execute with an error if the mouse * has not been moved anywhere since the page was loaded. * * @param button The button to click. 0 corresponds to the primary mouse * button, 1 to the middle mouse button, 2 to the secondary mouse button. * Numbers above 2 correspond to any additional buttons a mouse might * provide. */ Command.prototype.clickMouseButton = function (button) { return this._callSessionMethod('clickMouseButton', button); }; /** * Depresses a mouse button without releasing it. * * @param button The button to press. See [[Command.Command.click]] for * available options. */ Command.prototype.pressMouseButton = function (button) { return this._callSessionMethod('pressMouseButton', button); }; /** * Releases a previously depressed mouse button. * * @param button The button to press. See [[Command.Command.click]] for * available options. */ Command.prototype.releaseMouseButton = function (button) { return this._callSessionMethod('releaseMouseButton', button); }; /** * Double-clicks the primary mouse button. */ Command.prototype.doubleClick = function () { return this._callSessionMethod('doubleClick'); }; /** * Taps an element on a touch screen device. If the element is outside of * the viewport, the remote driver will attempt to scroll it into view * automatically. * * @param element The element to tap. */ Command.prototype.tap = function (element) { return this._callSessionMethod('tap', element); }; /** * Depresses a new finger at the given point on a touch screen device * without releasing it. * * @param x The screen x-coordinate to press, maybe in device pixels. * @param y The screen y-coordinate to press, maybe in device pixels. */ Command.prototype.pressFinger = function (x, y) { return this._callSessionMethod('pressFinger', x, y); }; /** * Releases whatever finger exists at the given point on a touch screen * device. * * @param x The screen x-coordinate where a finger is pressed, maybe in * device pixels. * @param y The screen y-coordinate where a finger is pressed, maybe in * device pixels. */ Command.prototype.releaseFinger = function (x, y) { return this._callSessionMethod('releaseFinger', x, y); }; /** * Moves the last depressed finger to a new point on the touch screen. * * @param x The screen x-coordinate to move to, maybe in device pixels. * @param y The screen y-coordinate to move to, maybe in device pixels. */ Command.prototype.moveFinger = function (x, y) { return this._callSessionMethod('moveFinger', x, y); }; Command.prototype.touchScroll = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return this._callSessionMethod.apply(this, __spreadArray(['touchScroll'], args)); }; /** * Performs a double-tap gesture on an element. * * @method * @param element The element to double-tap. */ Command.prototype.doubleTap = function (element) { return this._callSessionMethod('doubleTap', element); }; /** * Performs a long-tap gesture on an element. * * @method * @param element The element to long-tap. */ Command.prototype.longTap = function (element) { return this._callSessionMethod('longTap', element); }; Command.prototype.flickFinger = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return this._callSessionMethod.apply(this, __spreadArray(['flickFinger'], args)); }; /** * Gets the current geographical location of the remote environment. * * @returns a [[interfaces.Geolocation]] value with latitude and longitude * specified using standard WGS84 decimal latitude/longitude. Altitude is * specified as meters above the WGS84 ellipsoid. Not all environments * support altitude. */ Command.prototype.getGeolocation = function () { return this._callSessionMethod('getGeolocation'); }; /** * Sets the geographical location of the remote environment. * * @param location Latitude and longitude are specified using standard * WGS84 decimal latitude/longitude. Altitude is specified as meters above * the WGS84 ellipsoid. Not all environments support altitude. */ Command.prototype.setGeolocation = function (location) { return this._callSessionMethod('setGeolocation', location); }; /** * Gets all logs from the remote environment of the given type. The logs in * the remote environment are cleared once they have been retrieved. * * @param type The type of log entries to retrieve. Available log types * differ between remote environments. Use * [[Command.Command.getAvailableLogTypes]] to learn what log types are * currently available. Not all environments support all possible log * types. * * @returns An array of log entry objects. Timestamps in log entries are * Unix timestamps, in seconds. */