Path: blob/trunk/javascript/atoms/locators/locators.js
2884 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.locators.className');26goog.require('bot.locators.css');27goog.require('bot.locators.id');28goog.require('bot.locators.linkText');29goog.require('bot.locators.name');30goog.require('bot.locators.partialLinkText');31goog.require('bot.locators.relative');32goog.require('bot.locators.tagName');33goog.require('bot.locators.xpath');343536/**37* @typedef {{single:function(string,!(Document|Element)):Element,38* many:function(string,!(Document|Element)):!IArrayLike}}39*/40bot.locators.strategy;414243/**44* Known element location strategies. The returned objects have two45* methods on them, "single" and "many", for locating a single element46* or multiple elements, respectively.47*48* Note that the versions with spaces are synonyms for those without spaces,49* and are specified at:50* https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol51* @private {Object.<string,bot.locators.strategy>}52* @const53*/54bot.locators.STRATEGIES_ = {55'className': bot.locators.className,56'class name': bot.locators.className,5758'css': bot.locators.css,59'css selector': bot.locators.css,6061'relative': bot.locators.relative,6263'id': bot.locators.id,6465'linkText': bot.locators.linkText,66'link text': bot.locators.linkText,6768'name': bot.locators.name,6970'partialLinkText': bot.locators.partialLinkText,71'partial link text': bot.locators.partialLinkText,7273'tagName': bot.locators.tagName,74'tag name': bot.locators.tagName,7576'xpath': bot.locators.xpath77};787980/**81* Add or override an existing strategy for locating elements.82*83* @param {string} name The name of the strategy.84* @param {!bot.locators.strategy} strategy The strategy to use.85*/86bot.locators.add = function (name, strategy) {87bot.locators.STRATEGIES_[name] = strategy;88};899091/**92* Returns one key from the object map that is not present in the93* Object.prototype, if any exists.94*95* @param {Object} target The object to pick a key from.96* @return {?string} The key or null if the object is empty.97*/98bot.locators.getOnlyKey = function (target) {99for (var k in target) {100if (target.hasOwnProperty(k)) {101return k;102}103}104return null;105};106107108/**109* Find the first element in the DOM matching the target. The target110* object should have a single key, the name of which determines the111* locator strategy and the value of which gives the value to be112* searched for. For example {id: 'foo'} indicates that the first113* element on the DOM with the ID 'foo' should be returned.114*115* @param {!Object} target The selector to search for.116* @param {(Document|Element)=} opt_root The node from which to start the117* search. If not specified, will use `document` as the root.118* @return {Element} The first matching element found in the DOM, or null if no119* such element could be found.120*/121bot.locators.findElement = function (target, opt_root) {122var key = bot.locators.getOnlyKey(target);123124if (key) {125var strategy = bot.locators.STRATEGIES_[key];126if (strategy && goog.isFunction(strategy.single)) {127var root = opt_root || bot.getDocument();128return strategy.single(target[key], root);129}130}131throw new bot.Error(bot.ErrorCode.INVALID_ARGUMENT,132'Unsupported locator strategy: ' + key);133};134135136/**137* Find all elements in the DOM matching the target. The target object138* should have a single key, the name of which determines the locator139* strategy and the value of which gives the value to be searched140* for. For example {name: 'foo'} indicates that all elements with the141* 'name' attribute equal to 'foo' should be returned.142*143* @param {!Object} target The selector to search for.144* @param {(Document|Element)=} opt_root The node from which to start the145* search. If not specified, will use `document` as the root.146* @return {!IArrayLike.<Element>} All matching elements found in the147* DOM.148*/149bot.locators.findElements = function (target, opt_root) {150var key = bot.locators.getOnlyKey(target);151152if (key) {153var strategy = bot.locators.STRATEGIES_[key];154if (strategy && goog.isFunction(strategy.many)) {155var root = opt_root || bot.getDocument();156return strategy.many(target[key], root);157}158}159throw new bot.Error(bot.ErrorCode.INVALID_ARGUMENT,160'Unsupported locator strategy: ' + key);161};162163164