mirror of
https://github.com/appium/appium.git
synced 2026-02-10 03:38:49 -06:00
Merge pull request #3271 from Jonahss/instance
fix for xpath, uses ClassName and Instance instead of Index
This commit is contained in:
@@ -94,13 +94,7 @@ androidController.findElementsFromElement = function (element, strategy, selecto
|
||||
};
|
||||
|
||||
var _pathFromDomNode = function (node) {
|
||||
var path = "";
|
||||
_.each(node.attributes, function (attrObj) {
|
||||
if (attrObj.name === "index") {
|
||||
path = _pathFromDomNode(node.parentNode) + "/" + attrObj.value;
|
||||
}
|
||||
});
|
||||
return path;
|
||||
return node.getAttribute("class") + ':' + node.getAttribute("instance");
|
||||
};
|
||||
|
||||
androidController.findUIElementsByXPath = function (selector, many, cb) {
|
||||
@@ -308,7 +302,7 @@ var _updateSourceXMLNodeNames = function (source) {
|
||||
var newSource;
|
||||
var origDom = new XMLDom.DOMParser().parseFromString(source);
|
||||
var newDom = new XMLDom.DOMImplementation().createDocument(null);
|
||||
_buildClassNodeFromPlainNode(newDom, newDom, origDom);
|
||||
_annotateXmlNodes(newDom, newDom, origDom);
|
||||
newSource = new XMLDom.XMLSerializer().serializeToString(newDom);
|
||||
return newSource;
|
||||
};
|
||||
@@ -329,19 +323,29 @@ var _copyNodeAttributes = function (oldNode, newNode) {
|
||||
});
|
||||
};
|
||||
|
||||
var _buildClassNodeFromPlainNode = function (newDom, newParent, oldNode) {
|
||||
// recursively annotate xml nodes. Update tag name to be Android UIElement class name. Add an "instance" identifier which increments for each class separately.
|
||||
var _annotateXmlNodes = function (newDom, newParent, oldNode, instances) {
|
||||
if (!instances) {
|
||||
instances = {};
|
||||
}
|
||||
var newNode;
|
||||
var nodeClass = _getNodeClass(oldNode);
|
||||
if (nodeClass) {
|
||||
newNode = newDom.createElement(nodeClass);
|
||||
_copyNodeAttributes(oldNode, newNode);
|
||||
|
||||
// we keep track of the number of instances of each className. We use these to create queries on the bootstrap side.
|
||||
if (!instances[nodeClass]) {
|
||||
instances[nodeClass] = 0;
|
||||
}
|
||||
newNode.setAttribute('instance', instances[nodeClass]++);
|
||||
} else {
|
||||
newNode = oldNode.cloneNode(false);
|
||||
}
|
||||
newParent.appendChild(newNode);
|
||||
if (oldNode.hasChildNodes()) {
|
||||
_.each(oldNode.childNodes, function (childNode) {
|
||||
_buildClassNodeFromPlainNode(newDom, newNode, childNode);
|
||||
_annotateXmlNodes(newDom, newNode, childNode, instances);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -279,20 +279,16 @@ public class Find extends CommandHandler {
|
||||
* @throws ElementNotFoundException
|
||||
* @throws JSONException
|
||||
*/
|
||||
private JSONObject fetchElementByIndexPath(final String indexPath)
|
||||
private JSONObject fetchElementByClassAndInstance(final String indexPath)
|
||||
throws ElementNotFoundException, JSONException {
|
||||
UiSelector sel = new UiSelector().index(0);
|
||||
Integer curIndex;
|
||||
List<String> paths = Arrays.asList(indexPath.split("/"));
|
||||
// throw away the first element since it will be empty, and the second
|
||||
// element, since it will refer to the root element, which we already have
|
||||
paths = paths.subList(2, paths.size());
|
||||
for (final String index : paths) {
|
||||
curIndex = Integer.valueOf(index);
|
||||
// get a new selector which selects the current selector's child at the
|
||||
// correct index
|
||||
sel = sel.childSelector(new UiSelector().index(curIndex));
|
||||
}
|
||||
|
||||
// path looks like "className:instanceNumber" eg: "android.widget.Button:2"
|
||||
String[] classInstancePair = indexPath.split(":");
|
||||
String androidClass = classInstancePair[0];
|
||||
String instance = classInstancePair[1];
|
||||
|
||||
UiSelector sel = new UiSelector().className(androidClass).instance(Integer.parseInt(instance));
|
||||
|
||||
return fetchElement(sel, "");
|
||||
}
|
||||
|
||||
@@ -342,7 +338,7 @@ public class Find extends CommandHandler {
|
||||
JSONObject resEl = new JSONObject();
|
||||
for (final String indexPath : indexPaths) {
|
||||
try {
|
||||
resEl = fetchElementByIndexPath(indexPath);
|
||||
resEl = fetchElementByClassAndInstance(indexPath);
|
||||
resArray.put(resEl);
|
||||
} catch (final JSONException e) {
|
||||
return new AndroidCommandResult(WDStatus.UNKNOWN_ERROR, e.getMessage());
|
||||
|
||||
Reference in New Issue
Block a user