Skip to content

Commit 4c5583d

Browse files
committed
Added new layer for iOS abstraction.
1 parent 6db5be8 commit 4c5583d

File tree

5 files changed

+138
-91
lines changed

5 files changed

+138
-91
lines changed

app/appium.js

+27-80
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
// Appium webserver controller methods
22
// https://github.com/hugs/appium/blob/master/appium/appium.py
33
var routing = require('./routing')
4-
, path = require('path')
5-
, rimraf = require('rimraf')
6-
, instruments = require('../instruments/instruments');
4+
, ios = require('./ios');
75

8-
var Appium = function(app, udid, verbose, removeTraceDir) {
9-
this.app = app;
10-
this.udid = udid;
11-
this.verbose = verbose;
12-
this.instruments = null;
6+
var Appium = function(args) {
7+
this.args = args;
138
this.rest = null;
14-
this.queue = [];
15-
this.progress = 0;
9+
this.devices = {};
10+
this.active = null;
11+
this.device = null;
1612
this.sessionId = null;
17-
this.removeTraceDir = removeTraceDir;
1813
};
1914

2015
Appium.prototype.attachTo = function(rest, cb) {
@@ -33,91 +28,43 @@ Appium.prototype.start = function(cb) {
3328
this.sessionId = new Date().getTime();
3429
console.log('Creating new appium session ' + this.sessionId);
3530

36-
if (this.instruments === null) {
37-
this.instruments = instruments(
38-
this.rest
39-
, path.resolve(__dirname, '../' + this.app)
40-
, this.udid
41-
, path.resolve(__dirname, 'uiauto/bootstrap.js')
42-
, path.resolve(__dirname, 'uiauto/Automation.tracetemplate')
43-
);
31+
// in future all the blackberries go here.
32+
this.active = 'iOS';
33+
if (typeof this.devices[this.active] === 'undefined') {
34+
this.devices[this.active] = ios(this.rest, this.args.app, this.args.UDID, this.args.verbose, this.args.remove);
4435
}
36+
this.device = this.devices[this.active];
4537

46-
var me = this;
47-
me.instruments.launch(function() {
48-
console.log('Instruments launched. Starting poll loop for new commands.');
49-
me.instruments.setDebug(true);
50-
cb(null, me);
51-
}, function(code) {
52-
if (!code || code > 0) {
53-
me.stop();
54-
}
38+
this.device.start(function(err, device) {
39+
cb(err, device);
5540
});
56-
} else {
57-
cb('Session already in progress', null);
5841
}
5942
};
6043

44+
Appium.prototype.proxy = function(cmd, cb) {
45+
this.device.proxy(cmd, cb);
46+
};
47+
6148
Appium.prototype.stop = function(cb) {
6249
if (this.sessionId === null) {
6350
return;
6451
}
52+
6553
var me = this;
6654

67-
console.log('Shutting down appium session ' + me.sessionId);
68-
this.instruments.shutdown(function(traceDir) {
69-
me.queue = [];
70-
me.progress = 0;
55+
this.device.stop(function() {
56+
console.log('Shutting down appium session.');
7157
me.sessionId = null;
72-
rimraf(traceDir, function() {
73-
if (cb) {
74-
cb();
75-
}
76-
});
58+
if (cb) {
59+
cb(me.sessionId);
60+
}
7761
});
7862
};
7963

80-
Appium.prototype.proxy = function(command, cb) {
81-
// was thinking we should use a queue for commands instead of writing to a file
82-
this.push([command, cb]);
83-
console.log('Pushed command to appium work queue: ' + command);
84-
};
85-
86-
Appium.prototype.push = function(elem) {
87-
this.queue.push(elem);
88-
var me = this;
89-
90-
var next = function() {
91-
if (me.queue.length <= 0 || me.progress > 0) {
92-
return;
93-
}
94-
95-
var target = me.queue.shift();
96-
me.progress++;
97-
98-
me.instruments.sendCommand(target[0], function(result) {
99-
if (typeof target[1] === 'function') {
100-
if (result === 'undefined') {
101-
target[1]();
102-
} else {
103-
try {
104-
var jsonresult = JSON.parse(result);
105-
target[1](jsonresult);
106-
} catch (e) {
107-
target[1](result);
108-
}
109-
}
110-
}
111-
112-
// maybe there's moar work to do
113-
me.progress--;
114-
next();
115-
});
116-
};
117-
118-
next();
64+
Appium.prototype.device = function() {
65+
return this.devices[this.active];
11966
};
12067

121-
module.exports = function(app, udid, version) {
122-
return new Appium(app, udid, version);
68+
module.exports = function(args) {
69+
return new Appium(args);
12370
};

app/controller.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ var findElement = function(req, res, ctx, many, cb) {
88

99
var command = [ctx, ".findElement", ext, "AndSetKey", ext, "('", value, "')"].join("");
1010

11-
req.appium.proxy(command, function(json) {
11+
req.device.proxy(command, function(json) {
1212
json = many ? json : json[0];
1313
cb({
1414
sessionId: req.appium.sessionId
@@ -33,7 +33,7 @@ exports.getStatus = function(req, res) {
3333
};
3434

3535
exports.createSession = function(req, res) {
36-
// we can talk to the appium client from here
36+
// we can talk to the device client from here
3737
req.appium.start(function(err, instance) {
3838
if (err) {
3939
// of course we need to deal with err according to the WDJP spec.
@@ -83,7 +83,7 @@ exports.executeScript = function(req, res) {
8383
var iosResponse ='';
8484
var requestData = req.body;
8585
try {
86-
iosResponse = appium.client.proxy(requestData.script, true);
86+
iosResponse = device.client.proxy(requestData.script, true);
8787
}
8888
catch (e) {
8989
var errObj = {sessionId: sessionId, 'status': 13, 'value': JSON.stringify(e)};
@@ -112,7 +112,7 @@ exports.setValue = function(req, res) {
112112

113113
var command = ["elements['", elementId, "'].setValue('", body, "')"].join('');
114114

115-
req.appium.proxy(command, function(json) {
115+
req.device.proxy(command, function(json) {
116116
res.send({
117117
sessionId: req.appium.sessionId
118118
, status: status
@@ -128,7 +128,7 @@ exports.doClick = function(req, res) {
128128

129129
var command = ["elements['", elementId, "'].tap()"].join('');
130130

131-
req.appium.proxy(command, function(json) {
131+
req.device.proxy(command, function(json) {
132132
res.send({
133133
sessionId: req.appium.sessionId
134134
, status: status
@@ -144,7 +144,7 @@ exports.getText = function(req, res) {
144144

145145
var command = ["elements['", elementId, "'].getText()"].join('');
146146

147-
req.appium.proxy(command, function(json) {
147+
req.device.proxy(command, function(json) {
148148
res.send({
149149
sessionId: req.appium.sessionId
150150
, status: status

app/ios.js

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
var path = require('path')
2+
, rimraf = require('rimraf')
3+
, instruments = require('../instruments/instruments');
4+
5+
var IOS = function(rest, app, udid, verbose, removeTraceDir) {
6+
this.rest = rest;
7+
this.app = app;
8+
this.udid = udid;
9+
this.verbose = verbose;
10+
this.instruments = null;
11+
this.queue = [];
12+
this.progress = 0;
13+
this.removeTraceDir = removeTraceDir;
14+
};
15+
16+
IOS.prototype.start = function(cb) {
17+
if (this.instruments === null) {
18+
this.instruments = instruments(
19+
this.rest
20+
, path.resolve(__dirname, '../' + this.app)
21+
, this.udid
22+
, path.resolve(__dirname, 'uiauto/bootstrap.js')
23+
, path.resolve(__dirname, 'uiauto/Automation.tracetemplate')
24+
);
25+
}
26+
27+
var me = this;
28+
me.instruments.launch(function() {
29+
console.log('Instruments launched. Starting poll loop for new commands.');
30+
me.instruments.setDebug(true);
31+
cb(null, me);
32+
}, function(code) {
33+
if (!code || code > 0) {
34+
me.stop();
35+
}
36+
});
37+
};
38+
39+
IOS.prototype.stop = function(cb) {
40+
var me = this;
41+
42+
this.instruments.shutdown(function(traceDir) {
43+
me.queue = [];
44+
me.progress = 0;
45+
rimraf(traceDir, function() {
46+
if (cb) {
47+
cb();
48+
}
49+
});
50+
});
51+
};
52+
53+
IOS.prototype.proxy = function(command, cb) {
54+
// was thinking we should use a queue for commands instead of writing to a file
55+
this.push([command, cb]);
56+
console.log('Pushed command to appium work queue: ' + command);
57+
};
58+
59+
IOS.prototype.push = function(elem) {
60+
this.queue.push(elem);
61+
var me = this;
62+
63+
var next = function() {
64+
if (me.queue.length <= 0 || me.progress > 0) {
65+
return;
66+
}
67+
68+
var target = me.queue.shift();
69+
me.progress++;
70+
71+
me.instruments.sendCommand(target[0], function(result) {
72+
if (typeof target[1] === 'function') {
73+
if (result === 'undefined') {
74+
target[1]();
75+
} else {
76+
try {
77+
var jsonresult = JSON.parse(result);
78+
target[1](jsonresult);
79+
} catch (e) {
80+
target[1](result);
81+
}
82+
}
83+
}
84+
85+
// maybe there's moar work to do
86+
me.progress--;
87+
next();
88+
});
89+
};
90+
91+
next();
92+
};
93+
94+
module.exports = function(rest, app, udid, verbose, removeTraceDir) {
95+
return new IOS(rest, app, udid, verbose, removeTraceDir);
96+
};

app/routing.js

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module.exports = function(appium) {
44
var rest = appium.rest
55
, inject = function(req, res, next) {
66
req.appium = appium;
7+
req.device = appium.device;
78
next();
89
};
910

server.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ var http = require('http')
99
, appium = require('./app/appium')
1010
, parser = require('./app/parser');
1111

12-
var main = function(app, udid, verbose, port, address, remove, doneCb) {
12+
var main = function(args, doneCb) {
1313
if (typeof doneCb === "undefined") {
1414
doneCb = function() {};
1515
}
16+
// in case we'll support blackberry at some point
17+
args.device = 'iOS';
18+
1619
rest.configure(function() {
1720
var bodyParser = express.bodyParser()
1821
, parserWrap = function(req, res, next) {
@@ -31,12 +34,12 @@ var main = function(app, udid, verbose, port, address, remove, doneCb) {
3134
rest.use(rest.router);
3235
});
3336
// Instantiate the appium instance
34-
var appiumServer = appium(app, udid, verbose, remove);
37+
var appiumServer = appium(args);
3538
// Hook up REST http interface
3639
appiumServer.attachTo(rest);
3740
// Start the web server that receives all the commands
38-
server.listen(port, address, function() {
39-
var logMessage = "Appium REST http interface listener started on "+address+":"+port;
41+
server.listen(args.port, args.address, function() {
42+
var logMessage = "Appium REST http interface listener started on "+args.address+":"+args.port;
4043
console.log(logMessage.cyan);
4144
});
4245
server.on('close', doneCb);
@@ -45,7 +48,7 @@ var main = function(app, udid, verbose, port, address, remove, doneCb) {
4548
if (require.main === module) {
4649
// Parse the command line arguments
4750
var args = parser().parseArgs();
48-
main(args.app, args.UDID, args.verbose, args.port, args.address, args.remove);
51+
main(args);
4952
}
5053

5154
module.exports.run = main;

0 commit comments

Comments
 (0)