Path: blob/trunk/javascript/atoms/locators/locators.js
4504 views
// Licensed to the Software Freedom Conservancy (SFC) under one1// or more contributor license agreements. See the NOTICE file2// distributed with this work for additional information3// regarding copyright ownership. The SFC licenses this file4// to you under the Apache License, Version 2.0 (the5// "License"); you may not use this file except in compliance6// with the License. You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing,11// software distributed under the License is distributed on an12// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13// KIND, either express or implied. See the License for the14// specific language governing permissions and limitations15// under the License.1617/**18* @fileoverview Element locator functions.19*/202122goog.provide('bot.locators');2324goog.require('bot');25goog.require('bot.Error');26goog.require('bot.ErrorCode');27goog.require('bot.locators.className');28goog.require('bot.locators.css');29goog.require('bot.locators.id');30goog.require('bot.locators.linkText');31goog.require('bot.locators.name');32goog.require('bot.locators.partialLinkText');33goog.require('bot.locators.relative');34goog.require('bot.locators.tagName');35goog.require('bot.locators.xpath');363738/**39* @typedef {{single:function(string,!(Document|Element)):Element,40* many:function(string,!(Document|Element)):!IArrayLike}}41*/42bot.locators.strategy;434445/**46* Known element location strategies. The returned objects have two47* methods on them, "single" and "many", for locating a single element48* or multiple elements, respectively.49*50* Note that the versions with spaces are synonyms for those without spaces,51* and are specified at:52* https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol53* @private {Object.<string,bot.locators.strategy>}54* @const55*/56bot.locators.STRATEGIES_ = {57'className': bot.locators.className,58'class name': bot.locators.className,5960'css': bot.locators.css,61'css selector': bot.locators.css,6263'relative': bot.locators.relative,6465'id': bot.locators.id,6667'linkText': bot.locators.linkText,68'link text': bot.locators.linkText,6970'name': bot.locators.name,7172'partialLinkText': bot.locators.partialLinkText,73'partial link text': bot.locators.partialLinkText,7475'tagName': bot.locators.tagName,76'tag name': bot.locators.tagName,7778'xpath': bot.locators.xpath79};808182/**83* Add or override an existing strategy for locating elements.84*85* @param {string} name The name of the strategy.86* @param {!bot.locators.strategy} strategy The strategy to use.87*/88bot.locators.add = function (name, strategy) {89bot.locators.STRATEGIES_[name] = strategy;90};919293/**94* Returns one key from the object map that is not present in the95* Object.prototype, if any exists.96*97* @param {Object} target The object to pick a key from.98* @return {?string} The key or null if the object is empty.99*/100bot.locators.getOnlyKey = function (target) {101for (var k in target) {102if (target.hasOwnProperty(k)) {103return k;104}105}106return null;107};108109110/**111* Find the first element in the DOM matching the target. The target112* object should have a single key, the name of which determines the113* locator strategy and the value of which gives the value to be114* searched for. For example {id: 'foo'} indicates that the first115* element on the DOM with the ID 'foo' should be returned.116*117* @param {!Object} target The selector to search for.118* @param {(Document|Element)=} opt_root The node from which to start the119* search. If not specified, will use `document` as the root.120* @return {Element} The first matching element found in the DOM, or null if no121* such element could be found.122*/123bot.locators.findElement = function (target, opt_root) {124var key = bot.locators.getOnlyKey(target);125126if (key) {127var strategy = bot.locators.STRATEGIES_[key];128if (strategy && typeof strategy.single === 'function') {129var root = opt_root || bot.getDocument();130return strategy.single(target[key], root);131}132}133throw new bot.Error(bot.ErrorCode.INVALID_ARGUMENT,134'Unsupported locator strategy: ' + key);135};136137138/**139* Find all elements in the DOM matching the target. The target object140* should have a single key, the name of which determines the locator141* strategy and the value of which gives the value to be searched142* for. For example {name: 'foo'} indicates that all elements with the143* 'name' attribute equal to 'foo' should be returned.144*145* @param {!Object} target The selector to search for.146* @param {(Document|Element)=} opt_root The node from which to start the147* search. If not specified, will use `document` as the root.148* @return {!IArrayLike.<Element>} All matching elements found in the149* DOM.150*/151bot.locators.findElements = function (target, opt_root) {152var key = bot.locators.getOnlyKey(target);153154if (key) {155var strategy = bot.locators.STRATEGIES_[key];156if (strategy && typeof strategy.many === 'function') {157var root = opt_root || bot.getDocument();158return strategy.many(target[key], root);159}160}161throw new bot.Error(bot.ErrorCode.INVALID_ARGUMENT,162'Unsupported locator strategy: ' + key);163};164165166