зеркало из https://github.com/microsoft/appium.git
Added new layer for iOS abstraction.
This commit is contained in:
Родитель
6db5be8069
Коммит
4c5583d450
103
app/appium.js
103
app/appium.js
|
@ -1,20 +1,15 @@
|
|||
// Appium webserver controller methods
|
||||
// https://github.com/hugs/appium/blob/master/appium/appium.py
|
||||
var routing = require('./routing')
|
||||
, path = require('path')
|
||||
, rimraf = require('rimraf')
|
||||
, instruments = require('../instruments/instruments');
|
||||
, ios = require('./ios');
|
||||
|
||||
var Appium = function(app, udid, verbose, removeTraceDir) {
|
||||
this.app = app;
|
||||
this.udid = udid;
|
||||
this.verbose = verbose;
|
||||
this.instruments = null;
|
||||
var Appium = function(args) {
|
||||
this.args = args;
|
||||
this.rest = null;
|
||||
this.queue = [];
|
||||
this.progress = 0;
|
||||
this.devices = {};
|
||||
this.active = null;
|
||||
this.device = null;
|
||||
this.sessionId = null;
|
||||
this.removeTraceDir = removeTraceDir;
|
||||
};
|
||||
|
||||
Appium.prototype.attachTo = function(rest, cb) {
|
||||
|
@ -33,91 +28,43 @@ Appium.prototype.start = function(cb) {
|
|||
this.sessionId = new Date().getTime();
|
||||
console.log('Creating new appium session ' + this.sessionId);
|
||||
|
||||
if (this.instruments === null) {
|
||||
this.instruments = instruments(
|
||||
this.rest
|
||||
, path.resolve(__dirname, '../' + this.app)
|
||||
, this.udid
|
||||
, path.resolve(__dirname, 'uiauto/bootstrap.js')
|
||||
, path.resolve(__dirname, 'uiauto/Automation.tracetemplate')
|
||||
);
|
||||
// in future all the blackberries go here.
|
||||
this.active = 'iOS';
|
||||
if (typeof this.devices[this.active] === 'undefined') {
|
||||
this.devices[this.active] = ios(this.rest, this.args.app, this.args.UDID, this.args.verbose, this.args.remove);
|
||||
}
|
||||
this.device = this.devices[this.active];
|
||||
|
||||
var me = this;
|
||||
me.instruments.launch(function() {
|
||||
console.log('Instruments launched. Starting poll loop for new commands.');
|
||||
me.instruments.setDebug(true);
|
||||
cb(null, me);
|
||||
}, function(code) {
|
||||
if (!code || code > 0) {
|
||||
me.stop();
|
||||
}
|
||||
this.device.start(function(err, device) {
|
||||
cb(err, device);
|
||||
});
|
||||
} else {
|
||||
cb('Session already in progress', null);
|
||||
}
|
||||
};
|
||||
|
||||
Appium.prototype.proxy = function(cmd, cb) {
|
||||
this.device.proxy(cmd, cb);
|
||||
};
|
||||
|
||||
Appium.prototype.stop = function(cb) {
|
||||
if (this.sessionId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var me = this;
|
||||
|
||||
console.log('Shutting down appium session ' + me.sessionId);
|
||||
this.instruments.shutdown(function(traceDir) {
|
||||
me.queue = [];
|
||||
me.progress = 0;
|
||||
this.device.stop(function() {
|
||||
console.log('Shutting down appium session.');
|
||||
me.sessionId = null;
|
||||
rimraf(traceDir, function() {
|
||||
if (cb) {
|
||||
cb();
|
||||
cb(me.sessionId);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Appium.prototype.proxy = function(command, cb) {
|
||||
// was thinking we should use a queue for commands instead of writing to a file
|
||||
this.push([command, cb]);
|
||||
console.log('Pushed command to appium work queue: ' + command);
|
||||
Appium.prototype.device = function() {
|
||||
return this.devices[this.active];
|
||||
};
|
||||
|
||||
Appium.prototype.push = function(elem) {
|
||||
this.queue.push(elem);
|
||||
var me = this;
|
||||
|
||||
var next = function() {
|
||||
if (me.queue.length <= 0 || me.progress > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var target = me.queue.shift();
|
||||
me.progress++;
|
||||
|
||||
me.instruments.sendCommand(target[0], function(result) {
|
||||
if (typeof target[1] === 'function') {
|
||||
if (result === 'undefined') {
|
||||
target[1]();
|
||||
} else {
|
||||
try {
|
||||
var jsonresult = JSON.parse(result);
|
||||
target[1](jsonresult);
|
||||
} catch (e) {
|
||||
target[1](result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maybe there's moar work to do
|
||||
me.progress--;
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
module.exports = function(app, udid, version) {
|
||||
return new Appium(app, udid, version);
|
||||
module.exports = function(args) {
|
||||
return new Appium(args);
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@ var findElement = function(req, res, ctx, many, cb) {
|
|||
|
||||
var command = [ctx, ".findElement", ext, "AndSetKey", ext, "('", value, "')"].join("");
|
||||
|
||||
req.appium.proxy(command, function(json) {
|
||||
req.device.proxy(command, function(json) {
|
||||
json = many ? json : json[0];
|
||||
cb({
|
||||
sessionId: req.appium.sessionId
|
||||
|
@ -33,7 +33,7 @@ exports.getStatus = function(req, res) {
|
|||
};
|
||||
|
||||
exports.createSession = function(req, res) {
|
||||
// we can talk to the appium client from here
|
||||
// we can talk to the device client from here
|
||||
req.appium.start(function(err, instance) {
|
||||
if (err) {
|
||||
// of course we need to deal with err according to the WDJP spec.
|
||||
|
@ -83,7 +83,7 @@ exports.executeScript = function(req, res) {
|
|||
var iosResponse ='';
|
||||
var requestData = req.body;
|
||||
try {
|
||||
iosResponse = appium.client.proxy(requestData.script, true);
|
||||
iosResponse = device.client.proxy(requestData.script, true);
|
||||
}
|
||||
catch (e) {
|
||||
var errObj = {sessionId: sessionId, 'status': 13, 'value': JSON.stringify(e)};
|
||||
|
@ -112,7 +112,7 @@ exports.setValue = function(req, res) {
|
|||
|
||||
var command = ["elements['", elementId, "'].setValue('", body, "')"].join('');
|
||||
|
||||
req.appium.proxy(command, function(json) {
|
||||
req.device.proxy(command, function(json) {
|
||||
res.send({
|
||||
sessionId: req.appium.sessionId
|
||||
, status: status
|
||||
|
@ -128,7 +128,7 @@ exports.doClick = function(req, res) {
|
|||
|
||||
var command = ["elements['", elementId, "'].tap()"].join('');
|
||||
|
||||
req.appium.proxy(command, function(json) {
|
||||
req.device.proxy(command, function(json) {
|
||||
res.send({
|
||||
sessionId: req.appium.sessionId
|
||||
, status: status
|
||||
|
@ -144,7 +144,7 @@ exports.getText = function(req, res) {
|
|||
|
||||
var command = ["elements['", elementId, "'].getText()"].join('');
|
||||
|
||||
req.appium.proxy(command, function(json) {
|
||||
req.device.proxy(command, function(json) {
|
||||
res.send({
|
||||
sessionId: req.appium.sessionId
|
||||
, status: status
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
var path = require('path')
|
||||
, rimraf = require('rimraf')
|
||||
, instruments = require('../instruments/instruments');
|
||||
|
||||
var IOS = function(rest, app, udid, verbose, removeTraceDir) {
|
||||
this.rest = rest;
|
||||
this.app = app;
|
||||
this.udid = udid;
|
||||
this.verbose = verbose;
|
||||
this.instruments = null;
|
||||
this.queue = [];
|
||||
this.progress = 0;
|
||||
this.removeTraceDir = removeTraceDir;
|
||||
};
|
||||
|
||||
IOS.prototype.start = function(cb) {
|
||||
if (this.instruments === null) {
|
||||
this.instruments = instruments(
|
||||
this.rest
|
||||
, path.resolve(__dirname, '../' + this.app)
|
||||
, this.udid
|
||||
, path.resolve(__dirname, 'uiauto/bootstrap.js')
|
||||
, path.resolve(__dirname, 'uiauto/Automation.tracetemplate')
|
||||
);
|
||||
}
|
||||
|
||||
var me = this;
|
||||
me.instruments.launch(function() {
|
||||
console.log('Instruments launched. Starting poll loop for new commands.');
|
||||
me.instruments.setDebug(true);
|
||||
cb(null, me);
|
||||
}, function(code) {
|
||||
if (!code || code > 0) {
|
||||
me.stop();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
IOS.prototype.stop = function(cb) {
|
||||
var me = this;
|
||||
|
||||
this.instruments.shutdown(function(traceDir) {
|
||||
me.queue = [];
|
||||
me.progress = 0;
|
||||
rimraf(traceDir, function() {
|
||||
if (cb) {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
IOS.prototype.proxy = function(command, cb) {
|
||||
// was thinking we should use a queue for commands instead of writing to a file
|
||||
this.push([command, cb]);
|
||||
console.log('Pushed command to appium work queue: ' + command);
|
||||
};
|
||||
|
||||
IOS.prototype.push = function(elem) {
|
||||
this.queue.push(elem);
|
||||
var me = this;
|
||||
|
||||
var next = function() {
|
||||
if (me.queue.length <= 0 || me.progress > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var target = me.queue.shift();
|
||||
me.progress++;
|
||||
|
||||
me.instruments.sendCommand(target[0], function(result) {
|
||||
if (typeof target[1] === 'function') {
|
||||
if (result === 'undefined') {
|
||||
target[1]();
|
||||
} else {
|
||||
try {
|
||||
var jsonresult = JSON.parse(result);
|
||||
target[1](jsonresult);
|
||||
} catch (e) {
|
||||
target[1](result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maybe there's moar work to do
|
||||
me.progress--;
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
module.exports = function(rest, app, udid, verbose, removeTraceDir) {
|
||||
return new IOS(rest, app, udid, verbose, removeTraceDir);
|
||||
};
|
|
@ -4,6 +4,7 @@ module.exports = function(appium) {
|
|||
var rest = appium.rest
|
||||
, inject = function(req, res, next) {
|
||||
req.appium = appium;
|
||||
req.device = appium.device;
|
||||
next();
|
||||
};
|
||||
|
||||
|
|
13
server.js
13
server.js
|
@ -9,10 +9,13 @@ var http = require('http')
|
|||
, appium = require('./app/appium')
|
||||
, parser = require('./app/parser');
|
||||
|
||||
var main = function(app, udid, verbose, port, address, remove, doneCb) {
|
||||
var main = function(args, doneCb) {
|
||||
if (typeof doneCb === "undefined") {
|
||||
doneCb = function() {};
|
||||
}
|
||||
// in case we'll support blackberry at some point
|
||||
args.device = 'iOS';
|
||||
|
||||
rest.configure(function() {
|
||||
var bodyParser = express.bodyParser()
|
||||
, parserWrap = function(req, res, next) {
|
||||
|
@ -31,12 +34,12 @@ var main = function(app, udid, verbose, port, address, remove, doneCb) {
|
|||
rest.use(rest.router);
|
||||
});
|
||||
// Instantiate the appium instance
|
||||
var appiumServer = appium(app, udid, verbose, remove);
|
||||
var appiumServer = appium(args);
|
||||
// Hook up REST http interface
|
||||
appiumServer.attachTo(rest);
|
||||
// Start the web server that receives all the commands
|
||||
server.listen(port, address, function() {
|
||||
var logMessage = "Appium REST http interface listener started on "+address+":"+port;
|
||||
server.listen(args.port, args.address, function() {
|
||||
var logMessage = "Appium REST http interface listener started on "+args.address+":"+args.port;
|
||||
console.log(logMessage.cyan);
|
||||
});
|
||||
server.on('close', doneCb);
|
||||
|
@ -45,7 +48,7 @@ var main = function(app, udid, verbose, port, address, remove, doneCb) {
|
|||
if (require.main === module) {
|
||||
// Parse the command line arguments
|
||||
var args = parser().parseArgs();
|
||||
main(args.app, args.UDID, args.verbose, args.port, args.address, args.remove);
|
||||
main(args);
|
||||
}
|
||||
|
||||
module.exports.run = main;
|
||||
|
|
Загрузка…
Ссылка в новой задаче