Skip to content

Commit

Permalink
Selecting all elements via XPath no longer mistakenly includes the ro…
Browse files Browse the repository at this point in the history
…ot <hierarchy> node, which was causing appium to error. Fixes #2548
  • Loading branch information
Jonahss committed Aug 5, 2014
1 parent b4041d6 commit 9ee0b15
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 7 deletions.
30 changes: 23 additions & 7 deletions lib/devices/android/android-controller.js
Expand Up @@ -93,8 +93,17 @@ androidController.findElementsFromElement = function (element, strategy, selecto
this.findUIElementOrElements(strategy, selector, true, element, cb);
};

var _pathFromDomNode = function (node) {
return node.getAttribute("class") + ':' + node.getAttribute("instance");
var _instanceAndClassFromDomNode = function (node) {
var androidClass = node.getAttribute("class");
var instance = node.getAttribute("instance");

// if we can't get the class and instance, return nothing, since we cannot select the node
// this should only happen for the wrapping <hierarchy> tag.
if (!androidClass || !instance) {
return null;
}

return {class: androidClass, instance: instance};
};

androidController.findUIElementsByXPath = function (selector, many, cb) {
Expand All @@ -109,25 +118,32 @@ androidController.findUIElementsByXPath = function (selector, many, cb) {
logger.error(e);
return cb(e);
}
if (!many) nodes = nodes.slice(0, 1);
var indexPaths = _.map(nodes, _pathFromDomNode);
if (!many && indexPaths.length < 1) {
var instanceClassPairs = _.map(nodes, _instanceAndClassFromDomNode);
instanceClassPairs = _.compact(instanceClassPairs);

if (!many) instanceClassPairs = instanceClassPairs.slice(0, 1);

if (!many && instanceClassPairs.length < 1) {
// if we don't have any matching nodes, and we wanted at least one, fail
return cb(null, {
status: status.codes.NoSuchElement.code,
value: null
});
} else if (indexPaths.length < 1) {
} else if (instanceClassPairs.length < 1) {
// and if we don't have any matching nodes, return the empty array
return cb(null, {
status: status.codes.Success.code,
value: []
});
}

var selectorString = instanceClassPairs.map(function (pair) {
return pair.class + ":" + pair.instance;
}).join(",");

var findParams = {
strategy: "index paths",
selector: indexPaths.join(","),
selector: selectorString,
multiple: many
};
this.proxy(["find", findParams], cb);
Expand Down
14 changes: 14 additions & 0 deletions test/functional/android/apidemos/find/by-xpath-specs.js
Expand Up @@ -55,4 +55,18 @@ describe("apidemo - find - by xpath", function () {
.should.become("App")
.nodeify(done);
});
it('should find all elements', function (done) {
driver
.elementsByXPath("//*").then(function (els) {
els.length.should.be.above(2);
})
.nodeify(done);
});
it('should find the first element when searching for all elements', function (done) {
driver
.elementByXPath("//*").then(function (el) {
return el.should.be.ok;
})
.nodeify(done);
});
});

0 comments on commit 9ee0b15

Please sign in to comment.