selenium-webdriver 0.0.14 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +12 -0
- data/chrome/src/rb/lib/selenium/webdriver/chrome/command_executor.rb +5 -1
- data/common/src/js/core/scripts/htmlutils.js +404 -76
- data/common/src/js/core/scripts/rpc-optimizing-user-extension.js +5206 -0
- data/common/src/js/core/scripts/selenium-api.js +10 -15
- data/common/src/js/core/scripts/selenium-browserbot.js +26 -21
- data/common/src/rb/lib/selenium/webdriver/child_process.rb +62 -8
- data/common/src/rb/lib/selenium/webdriver/find.rb +12 -11
- data/common/src/rb/lib/selenium/webdriver/platform.rb +34 -36
- data/common/src/rb/lib/selenium/webdriver/target_locator.rb +8 -0
- data/firefox/prebuilt/linux/Release/libwebdriver-firefox.so +0 -0
- data/firefox/src/extension/components/badCertListener.js +121 -19
- data/firefox/src/extension/components/screenshooter.js +1 -1
- data/firefox/src/extension/components/utils.js +19 -10
- data/firefox/src/extension/components/wrappedElement.js +8 -8
- data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +8 -1
- data/firefox/src/rb/lib/selenium/webdriver/firefox/binary.rb +1 -1
- data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +12 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +1 -1
- data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +4 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +18 -9
- data/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll +0 -0
- data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +4 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie/util.rb +3 -2
- data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +4 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +1 -1
- metadata +3 -2
@@ -54,6 +54,10 @@ module Selenium
|
|
54
54
|
:name => id
|
55
55
|
end
|
56
56
|
|
57
|
+
def switchToDefaultContent
|
58
|
+
execute :request => "switchToDefaultContent"
|
59
|
+
end
|
60
|
+
|
57
61
|
def quit
|
58
62
|
begin
|
59
63
|
execute :request => 'quit'
|
@@ -177,6 +181,14 @@ module Selenium
|
|
177
181
|
find_elements_by 'xpath', xpath, parent
|
178
182
|
end
|
179
183
|
|
184
|
+
def findElementByCssSelector(parent, selector)
|
185
|
+
find_element_by 'css selector', selector, parent
|
186
|
+
end
|
187
|
+
|
188
|
+
def findElementsByCssSelector(parent, selector)
|
189
|
+
find_elements_by 'css selector', selector, parent
|
190
|
+
end
|
191
|
+
|
180
192
|
|
181
193
|
#
|
182
194
|
# Element functions
|
@@ -6,7 +6,7 @@ module Selenium
|
|
6
6
|
JSON_TEMPLATE = "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n%s"
|
7
7
|
|
8
8
|
def initialize
|
9
|
-
@server = TCPServer.new(
|
9
|
+
@server = TCPServer.new(localhost, 0)
|
10
10
|
@queue = Queue.new
|
11
11
|
|
12
12
|
@accepted_any = false
|
@@ -49,6 +49,10 @@ module Selenium
|
|
49
49
|
|
50
50
|
private
|
51
51
|
|
52
|
+
def localhost
|
53
|
+
Platform.ironruby? ? "localhost" : "0.0.0.0" # yeah, weird..
|
54
|
+
end
|
55
|
+
|
52
56
|
def start_run_loop
|
53
57
|
while(@listening) do
|
54
58
|
socket = @server.accept
|
@@ -1072,6 +1072,394 @@ function parse_locator(locator)
|
|
1072
1072
|
return { type: 'implicit', string: locator };
|
1073
1073
|
}
|
1074
1074
|
|
1075
|
+
/**
|
1076
|
+
* An interface definition for XPath engine implementations; an instance of
|
1077
|
+
* XPathEngine should be their prototype. Sub-implementations need only define
|
1078
|
+
* overrides of the methods provided here.
|
1079
|
+
*/
|
1080
|
+
function XPathEngine() {
|
1081
|
+
// public
|
1082
|
+
this.doc = null;
|
1083
|
+
|
1084
|
+
/**
|
1085
|
+
* Returns whether the current runtime environment supports the use of this
|
1086
|
+
* engine. Needs override.
|
1087
|
+
*/
|
1088
|
+
this.isAvailable = function() { return false; };
|
1089
|
+
|
1090
|
+
/**
|
1091
|
+
* Sets the document to be used for evaluation. Always returns the current
|
1092
|
+
* engine object so as to be chainable.
|
1093
|
+
*/
|
1094
|
+
this.setDocument = function(newDocument) {
|
1095
|
+
this.doc = newDocument;
|
1096
|
+
return this;
|
1097
|
+
};
|
1098
|
+
|
1099
|
+
/**
|
1100
|
+
* Returns a possibly-empty list of nodes. Needs override.
|
1101
|
+
*/
|
1102
|
+
this.selectNodes = function(xpath, contextNode, namespaceResolver) {
|
1103
|
+
return [];
|
1104
|
+
};
|
1105
|
+
|
1106
|
+
/**
|
1107
|
+
* Returns a single node, or null if no nodes were selected. This default
|
1108
|
+
* implementation simply returns the first result of selectNodes(), or
|
1109
|
+
* null.
|
1110
|
+
*/
|
1111
|
+
this.selectSingleNode = function(xpath, contextNode, namespaceResolver) {
|
1112
|
+
var nodes = this.selectNodes(xpath, contextNode, namespaceResolver);
|
1113
|
+
return (nodes.length > 0 ? nodes[0] : null);
|
1114
|
+
};
|
1115
|
+
|
1116
|
+
/**
|
1117
|
+
* Returns the number of matching nodes. This default implementation simply
|
1118
|
+
* returns the length of the result of selectNodes(), which should be
|
1119
|
+
* adequate for most sub-implementations.
|
1120
|
+
*/
|
1121
|
+
this.countNodes = function(xpath, contextNode, namespaceResolver) {
|
1122
|
+
return this.selectNodes(xpath, contextNode, namespaceResolver).length;
|
1123
|
+
};
|
1124
|
+
|
1125
|
+
/**
|
1126
|
+
* An optimization; likely to be a no-op for many implementations. Always
|
1127
|
+
* returns the current engine object so as to be chainable.
|
1128
|
+
*/
|
1129
|
+
this.setIgnoreAttributesWithoutValue = function(ignore) { return this; };
|
1130
|
+
}
|
1131
|
+
|
1132
|
+
/**
|
1133
|
+
* Implements XPathEngine.
|
1134
|
+
*/
|
1135
|
+
function NativeEngine() {
|
1136
|
+
// public
|
1137
|
+
// Override
|
1138
|
+
this.isAvailable = function() {
|
1139
|
+
if (browserVersion && browserVersion.isIE) {
|
1140
|
+
// javascript-xpath can fake out the check otherwise
|
1141
|
+
return false;
|
1142
|
+
}
|
1143
|
+
|
1144
|
+
return this.doc && this.doc.evaluate;
|
1145
|
+
};
|
1146
|
+
|
1147
|
+
// Override
|
1148
|
+
this.selectNodes = function(xpath, contextNode, namespaceResolver) {
|
1149
|
+
if (contextNode != this.doc) {
|
1150
|
+
xpath = '.' + xpath;
|
1151
|
+
}
|
1152
|
+
|
1153
|
+
var nodes = [];
|
1154
|
+
|
1155
|
+
try {
|
1156
|
+
var xpathResult = this.doc.evaluate(xpath, contextNode,
|
1157
|
+
namespaceResolver, 0, null);
|
1158
|
+
}
|
1159
|
+
catch (e) {
|
1160
|
+
var msg = extractExceptionMessage(e);
|
1161
|
+
throw new SeleniumError("Invalid xpath [1]: " + msg);
|
1162
|
+
}
|
1163
|
+
finally {
|
1164
|
+
if (xpathResult == null) {
|
1165
|
+
// If the result is null, we should still throw an Error.
|
1166
|
+
throw new SeleniumError("Invalid xpath [2]: " + xpath);
|
1167
|
+
}
|
1168
|
+
}
|
1169
|
+
|
1170
|
+
var node = xpathResult.iterateNext();
|
1171
|
+
|
1172
|
+
while (node) {
|
1173
|
+
nodes.push(node);
|
1174
|
+
node = xpathResult.iterateNext();
|
1175
|
+
}
|
1176
|
+
|
1177
|
+
return nodes;
|
1178
|
+
};
|
1179
|
+
}
|
1180
|
+
|
1181
|
+
NativeEngine.prototype = new XPathEngine();
|
1182
|
+
|
1183
|
+
/**
|
1184
|
+
* Implements XPathEngine.
|
1185
|
+
*/
|
1186
|
+
function AjaxsltEngine() {
|
1187
|
+
// private
|
1188
|
+
var ignoreAttributesWithoutValue = false;
|
1189
|
+
|
1190
|
+
function selectLogic(xpath, contextNode, namespaceResolver, firstMatch) {
|
1191
|
+
// DGF set xpathdebug = true (using getEval, if you like) to turn on JS
|
1192
|
+
// XPath debugging
|
1193
|
+
//xpathdebug = true;
|
1194
|
+
var context;
|
1195
|
+
|
1196
|
+
if (contextNode == this.doc) {
|
1197
|
+
context = new ExprContext(this.doc);
|
1198
|
+
}
|
1199
|
+
else {
|
1200
|
+
// provide false values to get the default constructor values
|
1201
|
+
context = new ExprContext(contextNode, false, false,
|
1202
|
+
contextNode.parentNode);
|
1203
|
+
}
|
1204
|
+
|
1205
|
+
context.setCaseInsensitive(true);
|
1206
|
+
context.setIgnoreAttributesWithoutValue(ignoreAttributesWithoutValue);
|
1207
|
+
context.setReturnOnFirstMatch(firstMatch);
|
1208
|
+
|
1209
|
+
try {
|
1210
|
+
var xpathObj = xpathParse(xpath);
|
1211
|
+
}
|
1212
|
+
catch (e) {
|
1213
|
+
var msg = extractExceptionMessage(e);
|
1214
|
+
throw new SeleniumError("Invalid xpath [3]: " + msg);
|
1215
|
+
}
|
1216
|
+
|
1217
|
+
var nodes = []
|
1218
|
+
var xpathResult = xpathObj.evaluate(context);
|
1219
|
+
|
1220
|
+
if (xpathResult && xpathResult.value) {
|
1221
|
+
for (var i = 0; i < xpathResult.value.length; ++i) {
|
1222
|
+
nodes.push(xpathResult.value[i]);
|
1223
|
+
}
|
1224
|
+
}
|
1225
|
+
|
1226
|
+
return nodes;
|
1227
|
+
}
|
1228
|
+
|
1229
|
+
// public
|
1230
|
+
// Override
|
1231
|
+
this.isAvailable = function() { return true; };
|
1232
|
+
|
1233
|
+
// Override
|
1234
|
+
this.selectNodes = function(xpath, contextNode, namespaceResolver) {
|
1235
|
+
return selectLogic(xpath, contextNode, namespaceResolver, false);
|
1236
|
+
};
|
1237
|
+
|
1238
|
+
// Override
|
1239
|
+
this.selectSingleNode = function(xpath, contextNode, namespaceResolver) {
|
1240
|
+
var nodes = selectLogic(xpath, contextNode, namespaceResolver, true);
|
1241
|
+
return (nodes.length > 0 ? nodes[0] : null);
|
1242
|
+
};
|
1243
|
+
|
1244
|
+
// Override
|
1245
|
+
this.setIgnoreAttributesWithoutValue = function(ignore) {
|
1246
|
+
ignoreAttributesWithoutValue = ignore;
|
1247
|
+
return this;
|
1248
|
+
};
|
1249
|
+
}
|
1250
|
+
|
1251
|
+
AjaxsltEngine.prototype = new XPathEngine();
|
1252
|
+
|
1253
|
+
/**
|
1254
|
+
* Implements XPathEngine.
|
1255
|
+
*/
|
1256
|
+
function JavascriptXPathEngine() {
|
1257
|
+
// private
|
1258
|
+
var engineDoc = document;
|
1259
|
+
|
1260
|
+
// public
|
1261
|
+
// Override
|
1262
|
+
this.isAvailable = function() { return true; };
|
1263
|
+
|
1264
|
+
// Override
|
1265
|
+
this.selectNodes = function(xpath, contextNode, namespaceResolver) {
|
1266
|
+
if (contextNode != this.doc) {
|
1267
|
+
// Regarding use of the second argument to document.evaluate():
|
1268
|
+
// http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/a59ce20639c74ba1/a9d9f53e88e5ebb5
|
1269
|
+
xpath = '.' + xpath;
|
1270
|
+
}
|
1271
|
+
|
1272
|
+
var nodes = [];
|
1273
|
+
|
1274
|
+
try {
|
1275
|
+
// When using the new and faster javascript-xpath library, we'll
|
1276
|
+
// use the TestRunner's document object, not the App-Under-Test's
|
1277
|
+
// document. The new library only modifies the TestRunner document
|
1278
|
+
// with the new functionality.
|
1279
|
+
var xpathResult = engineDoc.evaluate(xpath, contextNode,
|
1280
|
+
namespaceResolver, 0, null);
|
1281
|
+
}
|
1282
|
+
catch (e) {
|
1283
|
+
var msg = extractExceptionMessage(e);
|
1284
|
+
throw new SeleniumError("Invalid xpath [1]: " + msg);
|
1285
|
+
}
|
1286
|
+
finally {
|
1287
|
+
if (xpathResult == null) {
|
1288
|
+
// If the result is null, we should still throw an Error.
|
1289
|
+
throw new SeleniumError("Invalid xpath [2]: " + xpath);
|
1290
|
+
}
|
1291
|
+
}
|
1292
|
+
|
1293
|
+
var node = xpathResult.iterateNext();
|
1294
|
+
|
1295
|
+
while (node) {
|
1296
|
+
nodes.push(node);
|
1297
|
+
node = xpathResult.iterateNext();
|
1298
|
+
}
|
1299
|
+
|
1300
|
+
return nodes;
|
1301
|
+
};
|
1302
|
+
}
|
1303
|
+
|
1304
|
+
JavascriptXPathEngine.prototype = new XPathEngine();
|
1305
|
+
|
1306
|
+
/**
|
1307
|
+
* An object responsible for handling XPath logic. New XPath engines can be
|
1308
|
+
* registered to this evaluator on the fly.
|
1309
|
+
*
|
1310
|
+
* @param newDefaultEngineName the name of the default XPath engine. Must be
|
1311
|
+
* a non-native engine that is always available.
|
1312
|
+
* Defaults to 'ajaxslt'.
|
1313
|
+
*/
|
1314
|
+
function XPathEvaluator(newDefaultEngineName) {
|
1315
|
+
// private
|
1316
|
+
var nativeEngine = new NativeEngine();
|
1317
|
+
var defaultEngineName = newDefaultEngineName || 'ajaxslt';
|
1318
|
+
var engines = {
|
1319
|
+
'ajaxslt' : new AjaxsltEngine(),
|
1320
|
+
'javascript-xpath': new JavascriptXPathEngine(),
|
1321
|
+
'native' : nativeEngine
|
1322
|
+
};
|
1323
|
+
|
1324
|
+
var currentEngineName = defaultEngineName;
|
1325
|
+
var allowNativeXPath = true;
|
1326
|
+
var ignoreAttributesWithoutValue = true;
|
1327
|
+
|
1328
|
+
function preprocess(xpath) {
|
1329
|
+
// Trim any trailing "/": not valid xpath, and remains from attribute
|
1330
|
+
// locator.
|
1331
|
+
if (xpath.charAt(xpath.length - 1) == '/') {
|
1332
|
+
xpath = xpath.slice(0, -1);
|
1333
|
+
}
|
1334
|
+
// HUGE hack - remove namespace from xpath for IE
|
1335
|
+
if (browserVersion && browserVersion.isIE) {
|
1336
|
+
xpath = xpath.replace(/x:/g, '')
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
return xpath;
|
1340
|
+
}
|
1341
|
+
|
1342
|
+
/**
|
1343
|
+
* Returns the most sensible engine given the settings and the document
|
1344
|
+
* object.
|
1345
|
+
*/
|
1346
|
+
function getEngineFor(inDocument) {
|
1347
|
+
if (allowNativeXPath &&
|
1348
|
+
nativeEngine.setDocument(inDocument).isAvailable()) {
|
1349
|
+
return nativeEngine;
|
1350
|
+
}
|
1351
|
+
|
1352
|
+
var currentEngine = engines[currentEngineName];
|
1353
|
+
|
1354
|
+
if (currentEngine &&
|
1355
|
+
currentEngine.setDocument(inDocument).isAvailable()) {
|
1356
|
+
return currentEngine;
|
1357
|
+
}
|
1358
|
+
|
1359
|
+
return engines[defaultEngineName].setDocument(inDocument);
|
1360
|
+
}
|
1361
|
+
|
1362
|
+
/**
|
1363
|
+
* Dispatches an XPath evaluation method on the relevant engine for the
|
1364
|
+
* given document, and returns the result
|
1365
|
+
*/
|
1366
|
+
function dispatch(methodName, inDocument, xpath, contextNode, namespaceResolver) {
|
1367
|
+
xpath = preprocess(xpath);
|
1368
|
+
|
1369
|
+
if (! contextNode) {
|
1370
|
+
contextNode = inDocument;
|
1371
|
+
}
|
1372
|
+
|
1373
|
+
return getEngineFor(inDocument)
|
1374
|
+
.setIgnoreAttributesWithoutValue(ignoreAttributesWithoutValue)
|
1375
|
+
[methodName](xpath, contextNode, namespaceResolver);
|
1376
|
+
}
|
1377
|
+
|
1378
|
+
// public
|
1379
|
+
/**
|
1380
|
+
* Registers a new engine by name, and returns whether the registration was
|
1381
|
+
* successful. Each registered engine must be an instance of XPathEngine.
|
1382
|
+
* The engines registered by default - "ajaxslt", "javascript-xpath",
|
1383
|
+
* "native", and "default" - can't be overwritten.
|
1384
|
+
*/
|
1385
|
+
this.registerEngine = function(name, engine) {
|
1386
|
+
// can't overwrite one of these
|
1387
|
+
if (name == 'ajaxslt' ||
|
1388
|
+
name == 'javascript-xpath' ||
|
1389
|
+
name == 'native' ||
|
1390
|
+
name == 'default') {
|
1391
|
+
return false;
|
1392
|
+
}
|
1393
|
+
|
1394
|
+
if (! (engine instanceof XPathEngine)) {
|
1395
|
+
return false;
|
1396
|
+
}
|
1397
|
+
|
1398
|
+
engines[name] = engine;
|
1399
|
+
return true;
|
1400
|
+
}
|
1401
|
+
|
1402
|
+
this.getRegisteredEngine = function(name) {
|
1403
|
+
return engines[name];
|
1404
|
+
};
|
1405
|
+
|
1406
|
+
this.setCurrentEngine = function(name) {
|
1407
|
+
if (name == 'default') {
|
1408
|
+
currentEngineName = defaultEngineName;
|
1409
|
+
}
|
1410
|
+
else if (! engines[name]) {
|
1411
|
+
return;
|
1412
|
+
}
|
1413
|
+
else {
|
1414
|
+
currentEngineName = name;
|
1415
|
+
}
|
1416
|
+
};
|
1417
|
+
|
1418
|
+
this.getCurrentEngine = function() {
|
1419
|
+
return currentEngineName || defaultEngineName;
|
1420
|
+
};
|
1421
|
+
|
1422
|
+
this.setAllowNativeXPath = function(allow) {
|
1423
|
+
allowNativeXPath = allow;
|
1424
|
+
}
|
1425
|
+
|
1426
|
+
this.isAllowNativeXPath = function() {
|
1427
|
+
return allowNativeXPath;
|
1428
|
+
}
|
1429
|
+
|
1430
|
+
this.setIgnoreAttributesWithoutValue = function(ignore) {
|
1431
|
+
ignoreAttributesWithoutValue = ignore;
|
1432
|
+
};
|
1433
|
+
|
1434
|
+
this.isIgnoreAttributesWithoutValue = function() {
|
1435
|
+
return ignoreAttributesWithoutValue;
|
1436
|
+
};
|
1437
|
+
|
1438
|
+
this.selectNodes = function(inDocument, xpath, contextNode, namespaceResolver) {
|
1439
|
+
return dispatch('selectNodes', inDocument, xpath, contextNode,
|
1440
|
+
namespaceResolver);
|
1441
|
+
};
|
1442
|
+
|
1443
|
+
this.selectSingleNode = function(inDocument, xpath, contextNode, namespaceResolver) {
|
1444
|
+
return dispatch('selectSingleNode', inDocument, xpath, contextNode,
|
1445
|
+
namespaceResolver);
|
1446
|
+
};
|
1447
|
+
|
1448
|
+
this.countNodes = function(inDocument, xpath, contextNode, namespaceResolver) {
|
1449
|
+
return dispatch('countNodes', inDocument, xpath, contextNode,
|
1450
|
+
namespaceResolver);
|
1451
|
+
};
|
1452
|
+
|
1453
|
+
// initialization
|
1454
|
+
this.init();
|
1455
|
+
};
|
1456
|
+
|
1457
|
+
/**
|
1458
|
+
* Gives the user an overridable hook for registering new XPath engines, for
|
1459
|
+
* example from user extensions.
|
1460
|
+
*/
|
1461
|
+
XPathEvaluator.prototype.init = function() {};
|
1462
|
+
|
1075
1463
|
/**
|
1076
1464
|
* Evaluates an xpath on a document, and returns a list containing nodes in the
|
1077
1465
|
* resulting nodeset. The browserbot xpath methods are now backed by this
|
@@ -1114,9 +1502,10 @@ function parse_locator(locator)
|
|
1114
1502
|
*/
|
1115
1503
|
function eval_xpath(xpath, inDocument, opts)
|
1116
1504
|
{
|
1117
|
-
if (!opts) {
|
1505
|
+
if (! opts) {
|
1118
1506
|
var opts = {};
|
1119
1507
|
}
|
1508
|
+
|
1120
1509
|
var contextNode = opts.contextNode
|
1121
1510
|
? opts.contextNode : inDocument;
|
1122
1511
|
var namespaceResolver = opts.namespaceResolver
|
@@ -1130,87 +1519,26 @@ function eval_xpath(xpath, inDocument, opts)
|
|
1130
1519
|
var returnOnFirstMatch = (opts.returnOnFirstMatch != undefined)
|
1131
1520
|
? opts.returnOnFirstMatch : false;
|
1132
1521
|
|
1133
|
-
|
1134
|
-
|
1135
|
-
if (xpath.charAt(xpath.length - 1) == '/') {
|
1136
|
-
xpath = xpath.slice(0, -1);
|
1137
|
-
}
|
1138
|
-
// HUGE hack - remove namespace from xpath for IE
|
1139
|
-
if (browserVersion && browserVersion.isIE) {
|
1140
|
-
xpath = xpath.replace(/x:/g, '')
|
1522
|
+
if (! eval_xpath.xpathEvaluator) {
|
1523
|
+
eval_xpath.xpathEvaluator = new XPathEvaluator();
|
1141
1524
|
}
|
1142
1525
|
|
1143
|
-
var
|
1144
|
-
var useNativeXpath = allowNativeXpath && nativeXpathAvailable;
|
1145
|
-
var useDocumentEvaluate = useNativeXpath;
|
1146
|
-
|
1147
|
-
// When using the new and faster javascript-xpath library,
|
1148
|
-
// we'll use the TestRunner's document object, not the App-Under-Test's document.
|
1149
|
-
// The new library only modifies the TestRunner document with the new
|
1150
|
-
// functionality.
|
1151
|
-
if (xpathLibrary == 'javascript-xpath' && !useNativeXpath) {
|
1152
|
-
documentForXpath = document;
|
1153
|
-
useDocumentEvaluate = true;
|
1154
|
-
} else {
|
1155
|
-
documentForXpath = inDocument;
|
1156
|
-
}
|
1157
|
-
var results = [];
|
1526
|
+
var xpathEvaluator = eval_xpath.xpathEvaluator;
|
1158
1527
|
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
contextNode, namespaceResolver, 0, null);
|
1167
|
-
}
|
1168
|
-
catch (e) {
|
1169
|
-
throw new SeleniumError("Invalid xpath [1]: " + extractExceptionMessage(e));
|
1170
|
-
}
|
1171
|
-
finally{
|
1172
|
-
if (xpathResult == null) {
|
1173
|
-
// If the result is null, we should still throw an Error.
|
1174
|
-
throw new SeleniumError("Invalid xpath [2]: " + xpath);
|
1175
|
-
}
|
1176
|
-
}
|
1177
|
-
var result = xpathResult.iterateNext();
|
1178
|
-
while (result) {
|
1179
|
-
results.push(result);
|
1180
|
-
result = xpathResult.iterateNext();
|
1181
|
-
}
|
1182
|
-
return results;
|
1183
|
-
}
|
1184
|
-
|
1185
|
-
// If not, fall back to slower JavaScript implementation
|
1186
|
-
// DGF set xpathdebug = true (using getEval, if you like) to turn on JS XPath debugging
|
1187
|
-
//xpathdebug = true;
|
1188
|
-
var context;
|
1189
|
-
if (contextNode == inDocument) {
|
1190
|
-
context = new ExprContext(inDocument);
|
1528
|
+
xpathEvaluator.setCurrentEngine(xpathLibrary);
|
1529
|
+
xpathEvaluator.setAllowNativeXPath(allowNativeXpath);
|
1530
|
+
xpathEvaluator.setIgnoreAttributesWithoutValue(ignoreAttributesWithoutValue);
|
1531
|
+
|
1532
|
+
if (returnOnFirstMatch) {
|
1533
|
+
var result = xpathEvaluator.selectSingleNode(inDocument, xpath,
|
1534
|
+
contextNode, namespaceResolver);
|
1191
1535
|
}
|
1192
1536
|
else {
|
1193
|
-
|
1194
|
-
|
1195
|
-
contextNode.parentNode);
|
1196
|
-
}
|
1197
|
-
context.setCaseInsensitive(true);
|
1198
|
-
context.setIgnoreAttributesWithoutValue(ignoreAttributesWithoutValue);
|
1199
|
-
context.setReturnOnFirstMatch(returnOnFirstMatch);
|
1200
|
-
var xpathObj;
|
1201
|
-
try {
|
1202
|
-
xpathObj = xpathParse(xpath);
|
1203
|
-
}
|
1204
|
-
catch (e) {
|
1205
|
-
throw new SeleniumError("Invalid xpath [3]: " + extractExceptionMessage(e));
|
1537
|
+
var result = xpathEvaluator.selectNodes(inDocument, xpath, contextNode,
|
1538
|
+
namespaceResolver);
|
1206
1539
|
}
|
1207
|
-
|
1208
|
-
|
1209
|
-
for (var i = 0; i < xpathResult.value.length; ++i) {
|
1210
|
-
results.push(xpathResult.value[i]);
|
1211
|
-
}
|
1212
|
-
}
|
1213
|
-
return results;
|
1540
|
+
|
1541
|
+
return result;
|
1214
1542
|
}
|
1215
1543
|
|
1216
1544
|
/**
|