Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/javascript/atoms/locators/locators.js
4005 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License. You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied. See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
/**
19
* @fileoverview Element locator functions.
20
*/
21
22
23
goog.provide('bot.locators');
24
25
goog.require('bot');
26
goog.require('bot.Error');
27
goog.require('bot.ErrorCode');
28
goog.require('bot.locators.className');
29
goog.require('bot.locators.css');
30
goog.require('bot.locators.id');
31
goog.require('bot.locators.linkText');
32
goog.require('bot.locators.name');
33
goog.require('bot.locators.partialLinkText');
34
goog.require('bot.locators.relative');
35
goog.require('bot.locators.tagName');
36
goog.require('bot.locators.xpath');
37
38
39
/**
40
* @typedef {{single:function(string,!(Document|Element)):Element,
41
* many:function(string,!(Document|Element)):!IArrayLike}}
42
*/
43
bot.locators.strategy;
44
45
46
/**
47
* Known element location strategies. The returned objects have two
48
* methods on them, "single" and "many", for locating a single element
49
* or multiple elements, respectively.
50
*
51
* Note that the versions with spaces are synonyms for those without spaces,
52
* and are specified at:
53
* https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
54
* @private {Object.<string,bot.locators.strategy>}
55
* @const
56
*/
57
bot.locators.STRATEGIES_ = {
58
'className': bot.locators.className,
59
'class name': bot.locators.className,
60
61
'css': bot.locators.css,
62
'css selector': bot.locators.css,
63
64
'relative': bot.locators.relative,
65
66
'id': bot.locators.id,
67
68
'linkText': bot.locators.linkText,
69
'link text': bot.locators.linkText,
70
71
'name': bot.locators.name,
72
73
'partialLinkText': bot.locators.partialLinkText,
74
'partial link text': bot.locators.partialLinkText,
75
76
'tagName': bot.locators.tagName,
77
'tag name': bot.locators.tagName,
78
79
'xpath': bot.locators.xpath
80
};
81
82
83
/**
84
* Add or override an existing strategy for locating elements.
85
*
86
* @param {string} name The name of the strategy.
87
* @param {!bot.locators.strategy} strategy The strategy to use.
88
*/
89
bot.locators.add = function (name, strategy) {
90
bot.locators.STRATEGIES_[name] = strategy;
91
};
92
93
94
/**
95
* Returns one key from the object map that is not present in the
96
* Object.prototype, if any exists.
97
*
98
* @param {Object} target The object to pick a key from.
99
* @return {?string} The key or null if the object is empty.
100
*/
101
bot.locators.getOnlyKey = function (target) {
102
for (var k in target) {
103
if (target.hasOwnProperty(k)) {
104
return k;
105
}
106
}
107
return null;
108
};
109
110
111
/**
112
* Find the first element in the DOM matching the target. The target
113
* object should have a single key, the name of which determines the
114
* locator strategy and the value of which gives the value to be
115
* searched for. For example {id: 'foo'} indicates that the first
116
* element on the DOM with the ID 'foo' should be returned.
117
*
118
* @param {!Object} target The selector to search for.
119
* @param {(Document|Element)=} opt_root The node from which to start the
120
* search. If not specified, will use `document` as the root.
121
* @return {Element} The first matching element found in the DOM, or null if no
122
* such element could be found.
123
*/
124
bot.locators.findElement = function (target, opt_root) {
125
var key = bot.locators.getOnlyKey(target);
126
127
if (key) {
128
var strategy = bot.locators.STRATEGIES_[key];
129
if (strategy && typeof strategy.single === 'function') {
130
var root = opt_root || bot.getDocument();
131
return strategy.single(target[key], root);
132
}
133
}
134
throw new bot.Error(bot.ErrorCode.INVALID_ARGUMENT,
135
'Unsupported locator strategy: ' + key);
136
};
137
138
139
/**
140
* Find all elements in the DOM matching the target. The target object
141
* should have a single key, the name of which determines the locator
142
* strategy and the value of which gives the value to be searched
143
* for. For example {name: 'foo'} indicates that all elements with the
144
* 'name' attribute equal to 'foo' should be returned.
145
*
146
* @param {!Object} target The selector to search for.
147
* @param {(Document|Element)=} opt_root The node from which to start the
148
* search. If not specified, will use `document` as the root.
149
* @return {!IArrayLike.<Element>} All matching elements found in the
150
* DOM.
151
*/
152
bot.locators.findElements = function (target, opt_root) {
153
var key = bot.locators.getOnlyKey(target);
154
155
if (key) {
156
var strategy = bot.locators.STRATEGIES_[key];
157
if (strategy && typeof strategy.many === 'function') {
158
var root = opt_root || bot.getDocument();
159
return strategy.many(target[key], root);
160
}
161
}
162
throw new bot.Error(bot.ErrorCode.INVALID_ARGUMENT,
163
'Unsupported locator strategy: ' + key);
164
};
165
166