mirror of
https://github.com/appium/appium.git
synced 2026-02-06 09:38:53 -06:00
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:
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
Binary file not shown.
@@ -251,7 +251,6 @@ Firefox.prototype.notImplementedCmds = function () {
|
||||
, 'touchDown'
|
||||
, 'touchUp'
|
||||
, 'touchMove'
|
||||
, 'getPageSourceXML'
|
||||
, 'swipe'
|
||||
, 'hideKeyboard'
|
||||
, 'clear'
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user