remove json page source in favor of xml

and fix a bug in android bootstrap's xpath that snuck in last time
This commit is contained in:
Jonathan Lipps
2014-04-09 18:07:02 -07:00
parent 958aac7e09
commit e2c6a9919b
10 changed files with 40 additions and 201 deletions

View File

@@ -106,7 +106,7 @@ var _pathFromDomNode = function (node) {
};
androidController.findUIElementsByXPath = function (selector, many, cb) {
this.getPageSourceXML(function (err, res) {
this.getPageSource(function (err, res) {
if (err || res.status !== status.codes.Success.code) return cb(err, res);
var dom, nodes;
var xmlSource = res.value;
@@ -366,63 +366,6 @@ var _buildClassNodeFromPlainNode = function (newDom, newParent, oldNode) {
};
androidController.getPageSource = function (cb) {
var xmlFile = temp.path({suffix: '.xml'});
var jsonFile = xmlFile + '.json';
var json = '';
var onDeviceXmlPath = this.dataDir + '/local/tmp/dump.xml';
async.series(
[
function (cb) {
this.proxy(["dumpWindowHierarchy"], cb);
}.bind(this),
function (cb) {
var cmd = this.adb.adbCmd + ' pull ' + onDeviceXmlPath + ' "' + xmlFile + '"';
logger.debug('transferPageSource command: ' + cmd);
exec(cmd, { maxBuffer: 524288 }, function (err, stdout, stderr) {
if (err) {
logger.warn(stderr);
return cb(err);
}
cb(null);
});
}.bind(this),
function (cb) {
var jar = path.resolve(__dirname, 'helpers', 'dump2json.jar');
var cmd = 'java -jar "' + jar + '" "' + xmlFile + '"';
logger.debug('json command: ' + cmd);
exec(cmd, { maxBuffer: 524288 }, function (err, stdout, stderr) {
if (err) {
logger.warn(stderr);
return cb(err);
}
cb(null);
});
},
function (cb) {
json = fs.readFileSync(jsonFile, 'utf8');
fs.unlinkSync(jsonFile);
fs.unlinkSync(xmlFile);
cb(null);
}
],
// Top level cb
function () {
warnDeprecatedCustom('page source', 'json',
"You got the source of the app using the page source command. This " +
"command is undergoing a large change which will be released in " +
"Appium 1.0. The change will include returning an XML document " +
"instead of a JSON object. If you depend on the page source command " +
"you should try the new version, which is accessible by doing " +
"`driver.execute_script('mobile: source', [{type: 'xml'}])`, or " +
"the equivalent in your language bindings.");
cb(null, {
status: status.codes.Success.code
, value: json
});
});
};
androidController.getPageSourceXML = function (cb) {
var xmlFile = temp.path({suffix: '.xml'});
var onDeviceXmlPath = this.dataDir + '/local/tmp/dump.xml';
async.series(

View File

@@ -76,15 +76,6 @@ public class Find extends CommandHandler {
}
final String contextId = (String) params.get("context");
final String text = (String) params.get("selector");
final Boolean multiple = (Boolean) params.get("multiple");
Logger.debug("Finding " + text + " using " + strategy.toString()
+ " with the contextId: " + contextId);
if (strategy == Strategy.INDEX_PATHS) {
return findElementsByIndexPaths(text, multiple);
}
if (strategy == Strategy.DYNAMIC) {
Logger.debug("Finding dynamic.");
@@ -194,6 +185,16 @@ public class Find extends CommandHandler {
}
}
final String text = (String) params.get("selector");
final Boolean multiple = (Boolean) params.get("multiple");
Logger.debug("Finding " + text + " using " + strategy.toString()
+ " with the contextId: " + contextId);
if (strategy == Strategy.INDEX_PATHS) {
return findElementsByIndexPaths(text, multiple);
}
try {
Object result = null;
final JSONArray array = new JSONArray();
@@ -432,8 +433,6 @@ public class Find extends CommandHandler {
sel = selectNameOrText(many, text);
selectors.add(sel);
break;
case XPATH:
break;
case ANDROID_UIAUTOMATOR:
try {
sel = uiSelectorParser.parse(text);

View File

@@ -251,7 +251,6 @@ Firefox.prototype.notImplementedCmds = function () {
, 'touchDown'
, 'touchUp'
, 'touchMove'
, 'getPageSourceXML'
, 'swipe'
, 'hideKeyboard'
, 'clear'

View File

@@ -1029,38 +1029,22 @@ iOSController.getPageSource = function (cb) {
this.processingRemoteCmd = false;
}.bind(this));
} else {
warnDeprecatedCustom('page source', 'json',
"You got the source of the app using the page source command. This " +
"command is undergoing a large change which will be released in " +
"Appium 1.0. The change will include returning an XML document " +
"instead of a JSON object. If you depend on the page source command " +
"you should try the new version, which is accessible by doing " +
"`driver.execute_script('mobile: source', [{type: 'xml'}])`, or " +
"the equivalent in your language bindings.");
this.proxy("au.mainApp().getPageSource()", cb);
this.getSourceForElementForXML(null, function (err, res) {
var xmlSource;
if (err || res.status !== 0) return cb(err, res);
try {
xmlSource = _xmlSourceFromJson(res.value);
} catch (e) {
return cb(e);
}
return cb(null, {
status: status.codes.Success.code
, value: xmlSource
});
}.bind(this));
}
};
iOSController.getPageSourceXML = function (cb) {
if (this.isWebContext()) {
return this.getPageSource(cb);
}
this.getSourceForElementForXML(null, function (err, res) {
var xmlSource;
if (err || res.status !== 0) return cb(err, res);
try {
xmlSource = _xmlSourceFromJson(res.value);
} catch (e) {
return cb(e);
}
return cb(null, {
status: status.codes.Success.code
, value: xmlSource
});
}.bind(this));
};
iOSController.waitForPageLoad = function (timeout, cb) {
this.proxy("au.waitForPageLoad(" + timeout + ")", cb);
};

View File

@@ -390,19 +390,6 @@ exports.mobileDrag = function (req, res) {
req.device.drag(startX, startY, endX, endY, duration, touchCount, element, destEl, getResponseHandler(req, res));
};
exports.mobileSource = function (req, res) {
var type = req.body.type;
if (checkMissingParams(res, {type: type})) {
logDeprecationWarning('parameter', 'type');
if (type.toLowerCase() === "xml") {
req.device.getPageSourceXML(getResponseHandler(req, res));
} else {
req.device.getPageSource(getResponseHandler(req, res));
}
}
};
exports.find = function (req, res) {
var strategy = "dynamic"
, selector = req.body
@@ -1113,7 +1100,6 @@ var mobileCmdMap = {
, 'background' : exports.background
, 'keyevent' : exports.keyevent
, 'fireEvent': exports.fireEvent
, 'source': exports.mobileSource
, 'find': exports.find
, 'waitForPageLoad': exports.waitForPageLoad
, 'currentActivity': exports.getCurrentActivity

View File

@@ -9,43 +9,28 @@ describe("apidemos - source -", function () {
var driver;
setup(this, desired).then(function (d) { driver = d; });
var assertSource = function (source) {
source.should.exist;
var dom = new XMLDom().parseFromString(source);
var nodes = xpath.select('//android.widget.TextView[@content-desc="App"]', dom);
nodes.length.should.equal(1);
};
it('should return the page source', function (done) {
driver
.elementByNameOrNull('Accessibility') // waiting for page to load
.source().then(function (source) {
source.should.exist;
source.should.include('android.widget.FrameLayout');
source.should.include('@class');
var obj = JSON.parse(source);
obj.should.exist;
// probably no need for so precise tests
//obj.hierarchy.node['@class'].should.equal("android.widget.FrameLayout");
//obj.hierarchy.node.node.node[0].node['@class'].should.equal("android.widget.FrameLayout");
}).nodeify(done);
});
it('should return the page source as xml', function (done) {
driver
.elementByNameOrNull('Accessibility') // waiting for page to load
.execute("mobile: source", [{type: 'xml'}]).then(function (source) {
source.should.exist;
var dom = new XMLDom().parseFromString(source);
var nodes = xpath.select('//android.widget.TextView[@content-desc="App"]', dom);
nodes.length.should.equal(1);
.source()
.then(function (source) {
assertSource(source);
}).nodeify(done);
});
it('should return the page source without crashing other commands', function (done) {
driver
.execute("mobile: find", [[[[3, "Animation"]]]])
.source().then(function (source) {
source.should.exist;
source.should.include('android.widget.FrameLayout');
source.should.include('@class');
var obj = JSON.parse(source);
obj.should.exist;
// probably no need for so precise tests
//obj.hierarchy.node['@class'].should.equal("android.widget.FrameLayout");
//obj.hierarchy.node.node.node[0].node['@class'].should.equal("android.widget.FrameLayout");
}).execute("mobile: find", [[[[3, "Animation"]]]])
assertSource(source);
})
.execute("mobile: find", [[[[3, "Animation"]]]])
.nodeify(done);
});
});

View File

@@ -107,16 +107,6 @@ describe('testapp - basic -', function () {
.nodeify(done);
});
it('should return app source', function (done) {
driver.source().then(function (source) {
var obj = JSON.parse(source);
obj.type.should.equal("UIAApplication");
obj.children[0].type.should.equal("UIAWindow");
obj.children[0].children[0].label.should.equal("TextField1");
["SumLabel", "0"].should.include(obj.children[0].children[3].name);
}).nodeify(done);
});
it('should interact with alert', function (done) {
driver.elementsByTagName('button').then(function (buttons) {
return buttons[1];

View File

@@ -9,20 +9,9 @@ describe('testapp - source -', function () {
var driver;
setup(this, desired).then(function (d) { driver = d; });
it('should return the page source as json', function (done) {
driver.source().then(function (source) {
var obj = JSON.parse(source);
obj.should.exist;
obj.type.should.equal("UIAApplication");
obj.children[0].type.should.equal("UIAWindow");
obj.children[0].children[2].name.should.equal("ComputeSumButton");
obj.children[0].children[3].rect.origin.x.should.equal(129);
obj.children[0].children[4].visible.should.be.ok;
}).nodeify(done);
});
it('should return page source as xml', function (done) {
driver.execute("mobile: source", [{type: "xml"}])
it('should return page source', function (done) {
driver
.source()
.then(function (source) {
var dom = new XMLDom().parseFromString(source);
var nodes = xpath.select('//UIAButton', dom);

View File

@@ -1,36 +0,0 @@
"use strict";
var controller = require('../../lib/server/controller.js')
, chai = require('chai')
, should = chai.should
, loggerjs = require('../../lib/server/logger')
, logger = loggerjs.get('appium')
, sinon = require('sinon');
describe('Controller', function () {
describe('##mobileSource', function () {
beforeEach(function () {
sinon.spy(logger, 'warn');
});
afterEach(function () {
logger.warn.restore();
});
it('should log a deprecation warning', function () {
var req = {
body: {
type: ''
},
device: {
getPageSource: function () {}
}
};
var expected_error = "[DEPRECATED] The type parameter has " +
"been deprecated and will be removed.";
var response = {};
controller.mobileSource(req, response);
logger.warn.args[0][0].should.equal(expected_error);
});
});
});