blob: 422e707d1323bccbf51fafeb486b95093169dd3a [file] [log] [blame] [edit]
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
/**
* @fileoverview Synthetic events for fun and profit.
*/
goog.provide('webdriver.atoms.inputs');
goog.require('bot.Keyboard');
goog.require('bot.Mouse');
goog.require('bot.action');
goog.require('bot.dom');
goog.require('goog.dom');
goog.require('goog.math.Coordinate');
goog.require('goog.style');
goog.require('webdriver.atoms.element');
/**
* Send keyboard input to a particular element.
*
* @param {?Element} element The element to send the keyboard input to, or
* `null` to use the document's active element.
* @param {!Array.<string>} keys The keys to type on the element.
* @param {bot.Keyboard.State=} opt_state The predefined keyboard state to use.
* @param {boolean=} opt_persistModifiers Whether modifier keys should remain
* pressed when this function ends.
* @return {bot.Keyboard.State} The keyboard state.
*/
webdriver.atoms.inputs.sendKeys = function(
element, keys, opt_state, opt_persistModifiers) {
var keyboard = new bot.Keyboard(opt_state);
if (!element) {
element = bot.dom.getActiveElement(document);
}
if (!element) {
throw Error('No element to send keys to');
}
webdriver.atoms.element.type(element, keys, keyboard, opt_persistModifiers);
return keyboard.getState();
};
/**
* Click on an element.
*
* @param {?Element} element The element to click.
* @param {bot.Mouse.State=} opt_state The serialized state of the mouse.
* @return {!bot.Mouse.State} The mouse state.
*/
webdriver.atoms.inputs.click = function(element, opt_state) {
var mouse = new bot.Mouse(opt_state);
if (!element) {
element = mouse.getState().element;
}
if (!element) {
throw Error('No element to send keys to');
}
bot.action.click(element, null, mouse);
return mouse.getState();
};
/**
* Move the mouse to a specific element and/or coordinate location.
*
* @param {?Element} element The element to move the mouse to.
* @param {?number} xOffset The x coordinate to use as an offset.
* @param {?number} yOffset The y coordinate to use as an offset.
* @param {bot.Mouse.State=} opt_state The serialized state of the mouse.
* @return {!bot.Mouse.State} The mouse state.
* @suppress {reportUnknownTypes}
*/
webdriver.atoms.inputs.mouseMove = function(element, xOffset, yOffset,
opt_state) {
var mouse = new bot.Mouse(opt_state);
var target = element || mouse.getState()['element'];
var offsetSpecified = (xOffset != null) && (yOffset != null);
xOffset = xOffset || 0;
yOffset = yOffset || 0;
// If we have specified an element and no offset, we should
// move the mouse to the center of the specified element.
if (element) {
if (!offsetSpecified) {
var size = bot.action.getInteractableSize(element);
xOffset = Math.floor(size.width / 2);
yOffset = Math.floor(size.height / 2);
}
} else {
// Moving to an absolute offset from the current target element,
// so we have to account for the existing offset of the current
// mouse position to the element origin (upper-left corner).
var pos = goog.style.getClientPosition(target);
xOffset += (mouse.getState()['clientXY']['x'] - pos.x);
yOffset += (mouse.getState()['clientXY']['y'] - pos.y);
}
var doc = goog.dom.getOwnerDocument(target);
goog.dom.getWindow(doc);
bot.action.scrollIntoView(
target, new goog.math.Coordinate(xOffset, yOffset));
var coords = new goog.math.Coordinate(xOffset, yOffset);
mouse.move(target, coords);
return mouse.getState();
};
/**
* Presses the primary mouse button at the current location.
*
* @param {bot.Mouse.State=} opt_state The serialized state of the mouse.
* @return {!bot.Mouse.State} The mouse state.
*/
webdriver.atoms.inputs.mouseButtonDown = function(opt_state) {
var mouse = new bot.Mouse(opt_state);
mouse.pressButton(bot.Mouse.Button.LEFT);
return mouse.getState();
};
/**
* Releases the primary mouse button at the current location.
*
* @param {bot.Mouse.State=} opt_state The serialized state of the mouse.
* @return {!bot.Mouse.State} The mouse state.
*/
webdriver.atoms.inputs.mouseButtonUp = function(opt_state) {
var mouse = new bot.Mouse(opt_state);
mouse.releaseButton();
return mouse.getState();
};
/**
* Double-clicks primary mouse button at the current location.
*
* @param {bot.Mouse.State=} opt_state The state of the mouse.
* @return {!bot.Mouse.State} The mouse state.
*/
webdriver.atoms.inputs.doubleClick = function(opt_state) {
var mouse = new bot.Mouse(opt_state);
mouse.pressButton(bot.Mouse.Button.LEFT);
mouse.releaseButton();
mouse.pressButton(bot.Mouse.Button.LEFT);
mouse.releaseButton();
return mouse.getState();
};
/**
* Right-clicks mouse button at the current location.
*
* @param {bot.Mouse.State=} opt_state The serialized state of the mouse.
* @return {!bot.Mouse.State} The mouse state.
* @deprecated Use {@link webdriver.atoms.inputs.mouseClick}.
*/
webdriver.atoms.inputs.rightClick = function(opt_state) {
var mouse = new bot.Mouse(opt_state);
mouse.pressButton(bot.Mouse.Button.RIGHT);
mouse.releaseButton();
return mouse.getState();
};
/**
* Executes a mousedown/up with the given button at the current mouse
* location.
*
* @param {bot.Mouse.Button} button The button to press.
* @param {bot.Mouse.State=} opt_state The state of the mouse.
* @return {!bot.Mouse.State} The mouse state.
* @suppress {reportUnknownTypes}
*/
webdriver.atoms.inputs.mouseClick = function(button, opt_state) {
// If no target element is specified, try to find it from the
// client (x, y) location. No, this is not exact.
if (opt_state && opt_state['clientXY'] && !opt_state['element'] &&
document.elementFromPoint) {
opt_state['element'] = document.elementFromPoint(
opt_state['clientXY']['x'], opt_state['clientXY']['y']);
}
var mouse = new bot.Mouse(opt_state);
mouse.pressButton(button);
mouse.releaseButton();
return mouse.getState();
};