更新时间:2022-06-16 00:07:45
var http = require('http')
, express = require('express')
, ...
, routing = require('./routing.js')
可以看到routing是在main.js所在目录的routing.js文件里导出来的,我们打开该文件:
var controller = require('./controller.js');
module.exports = function (appium) {
var rest = appium.rest;
var globalBeforeFilter = controller.getGlobalBeforeFilter(appium);
// Make appium available to all REST http requests.
rest.all('/wd/*', globalBeforeFilter);
routeNotYetImplemented(rest);
rest.all('/wd/hub/session/*', controller.sessionBeforeFilter);
rest.get('/wd/hub/status', controller.getStatus);
rest.post('/wd/hub/session', controller.createSession);
rest.get('/wd/hub/session/:sessionId?', controller.getSession);
rest.delete('/wd/hub/session/:sessionId?', controller.deleteSession);
rest.get('/wd/hub/sessions', controller.getSessions);
rest.get('/wd/hub/session/:sessionId?/context', controller.getCurrentContext);
rest.post('/wd/hub/session/:sessionId?/context', controller.setContext);
rest.get('/wd/hub/session/:sessionId?/contexts', controller.getContexts);
rest.post('/wd/hub/session/:sessionId?/element', controller.findElement);
rest.post('/wd/hub/session/:sessionId?/elements', controller.findElements);
rest.post('/wd/hub/session/:sessionId?/element/:elementId?/value', controller.setValue);
rest.post('/wd/hub/session/:sessionId?/element/:elementId?/click', controller.doClick);
...
|
Appium.prototype.start = function (desiredCaps, cb) {
var configureAndStart = function () {
this.desiredCapabilities = new Capabilities(desiredCaps);
this.updateResetArgsFromCaps();
this.args.webSocket = this.webSocket; // allow to persist over many sessions
this.configure(this.args, this.desiredCapabilities, function (err) {
if (err) {
logger.debug("Got configuration error, not starting session");
this.cleanupSession();
cb(err, null);
} else {
this.invoke(cb);
}
}.bind(this));
}.bind(this);
if (this.sessionId === null) {
configureAndStart();
} else if (this.sessionOverride) {
logger.info("Found an existing session to clobber, shutting it down " +
"first...");
this.stop(function (err) {
if (err) return cb(err);
logger.info("Old session shut down OK, proceeding to new session");
configureAndStart();
});
} else {
return cb(new Error("Requested a new session but one was in progress"));
}
};
|
Appium.prototype.getNewDevice = function (deviceType) {
var DeviceClass = (function () {
switch (deviceType) {
case DT_IOS:
return IOS;
case DT_SAFARI:
return Safari;
case DT_ANDROID:
return Android;
case DT_CHROME:
return Chrome;
case DT_SELENDROID:
return Selendroid;
case DT_FIREFOX_OS:
return FirefoxOs;
default:
throw new Error("Tried to start a device that doesn't exist: " +
deviceType);
}
})();
return new DeviceClass();
};
|
Android.prototype.initQueue = function () {
this.queue = async.queue(function (task, cb) {
var action = task.action,
params = task.params;
this.cbForCurrentCmd = cb;
if (this.adb && !this.shuttingDown) {
this.uiautomator.sendAction(action, params, function (response) {
this.cbForCurrentCmd = null;
if (typeof cb === 'function') {
this.respond(response, cb);
}
}.bind(this));
} else {
this.cbForCurrentCmd = null;
var msg = "Tried to send command to non-existent Android device, " +
"maybe it shut down?";
if (this.shuttingDown) {
msg = "We're in the middle of shutting down the Android device, " +
"so your request won't be executed. Sorry!";
}
this.respond({
status: status.codes.UnknownError.code
, value: msg
}, cb);
}
}.bind(this), 1);
};
|
Appium.prototype.invoke = function (cb) {
this.sessionId = UUID.create().hex;
logger.debug('Creating new appium session ' + this.sessionId);
if (this.device.args.autoLaunch === false) {
...
} else {
// the normal case, where we launch the device for folks
var onStart = function (err, sessionIdOverride) {
if (sessionIdOverride) {
this.sessionId = sessionIdOverride;
logger.debug("Overriding session id with " +
JSON.stringify(sessionIdOverride));
}
if (err) return this.cleanupSession(err, cb);
logger.debug("Device launched! Ready for commands");
this.setCommandTimeout(this.desiredCapabilities.newCommandTimeout);
cb(null, this.device);
}.bind(this);
this.device.start(onStart, _.once(this.cleanupSession.bind(this)));
}
};
|
Android.prototype.start = function (cb, onDie) {
this.launchCb = cb;
this.uiautomatorExitCb = onDie;
logger.info("Starting android appium");
if (this.adb === null) {
this.adb = new ADB(this.args);
}
if (this.uiautomator === null) {
this.uiautomator = new UiAutomator(this.adb, this.args);
this.uiautomator.setExitHandler(this.onUiautomatorExit.bind(this));
}
logger.debug("Using fast reset? " + this.args.fastReset);
async.series([
this.prepareDevice.bind(this),
this.packageAndLaunchActivityFromManifest.bind(this),
this.checkApiLevel.bind(this),
this.pushStrings.bind(this),
this.processFromManifest.bind(this),
this.uninstallApp.bind(this),
this.installAppForTest.bind(this),
this.forwardPort.bind(this),
this.pushAppium.bind(this),
this.initUnicode.bind(this),
this.pushSettingsApp.bind(this),
this.pushUnlock.bind(this),
this.uiautomator.start.bind(this.uiautomator),
this.wakeUp.bind(this),
this.unlock.bind(this),
this.getDataDir.bind(this),
this.setupCompressedLayoutHierarchy.bind(this),
this.startAppUnderTest.bind(this),
this.initAutoWebview.bind(this)
], function (err) {
if (err) {
this.shutdown(function () {
this.launchCb(err);
}.bind(this));
} else {
this.didLaunch = true;
this.launchCb(null, this.proxySessionId);
}
}.bind(this));
};
|
UiAutomator.prototype.start = function (readyCb) {
logger.info("Starting App");
this.adb.killProcessesByName('uiautomator', function (err) {
if (err) return readyCb(err);
logger.debug("Running bootstrap");
var args = ["shell", "uiautomator", "runtest", "AppiumBootstrap.jar", "-c",
"io.appium.android.bootstrap.Bootstrap"];
this.alreadyExited = false;
this.onSocketReady = readyCb;
this.proc = this.adb.spawn(args);
this.proc.on("error", function (err) {
logger.error("Unable to spawn adb: " + err.message);
if (!this.alreadyExited) {
this.alreadyExited = true;
readyCb(new Error("Unable to start Android Debug Bridge: " +
err.message));
}
}.bind(this));
this.proc.stdout.on('data', this.outputStreamHandler.bind(this));
this.proc.stderr.on('data', this.errorStreamHandler.bind(this));
this.proc.on('exit', this.exitHandler.bind(this));
}.bind(this));
};
|
Android.prototype.initQueue = function () {
this.queue = async.queue(function (task, cb) {
var action = task.action,
params = task.params;
this.cbForCurrentCmd = cb;
if (this.adb && !this.shuttingDown) {
this.uiautomator.sendAction(action, params, function (response) {
this.cbForCurrentCmd = null;
if (typeof cb === 'function') {
this.respond(response, cb);
}
}.bind(this));
} else {
this.cbForCurrentCmd = null;
var msg = "Tried to send command to non-existent Android device, " +
"maybe it shut down?";
if (this.shuttingDown) {
msg = "We're in the middle of shutting down the Android device, " +
"so your request won't be executed. Sorry!";
}
this.respond({
status: status.codes.UnknownError.code
, value: msg
}, cb);
}
}.bind(this), 1);
};
|
UiAutomator.prototype.sendCommand = function (type, extra, cb) {
...
else if (this.socketClient) {
...
var cmd = {cmd: type};
cmd = _.extend(cmd, extra);
var cmdJson = JSON.stringify(cmd) + "\n";
this.cmdCb = cb;
var logCmd = cmdJson.trim();
if (logCmd.length > 1000) {
logCmd = logCmd.substr(0, 1000) + "...";
}
this.debug("Sending command to android: " + logCmd);
this.socketClient.write(cmdJson);
}
...
}
|