mirror of
https://github.com/appium/appium.git
synced 2026-02-14 14:00:03 -06:00
added adb controller in node and some grunt utilities
This commit is contained in:
14
Gruntfile.js
14
Gruntfile.js
@@ -7,6 +7,8 @@ var path = require('path')
|
||||
, tail = gruntHelpers.tail
|
||||
, buildApp = gruntHelpers.buildApp
|
||||
, signApp = gruntHelpers.signApp
|
||||
, setupAndroidBootstrap = gruntHelpers.setupAndroidBootstrap
|
||||
, buildAndroidBootstrap = gruntHelpers.buildAndroidBootstrap
|
||||
, runTestsWithServer = gruntHelpers.runTestsWithServer;
|
||||
|
||||
module.exports = function(grunt) {
|
||||
@@ -90,4 +92,16 @@ module.exports = function(grunt) {
|
||||
grunt.registerTask('log', "Tail appium.log", function() {
|
||||
tail(grunt, path.resolve(__dirname, "appium.log"), this.async());
|
||||
});
|
||||
grunt.registerTask('configAndroidBootstrap', function() {
|
||||
var cb = this.async();
|
||||
setupAndroidBootstrap(grunt, function(exitCode) {
|
||||
cb(exitCode === 0);
|
||||
});
|
||||
});
|
||||
grunt.registerTask('buildAndroidBootstrap', function() {
|
||||
var cb = this.async();
|
||||
buildAndroidBootstrap(grunt, function(exitCode) {
|
||||
cb(exitCode === 0);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -245,3 +245,54 @@ module.exports.downloadUICatalog = function(cb) {
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.setupAndroidBootstrap = function(grunt, cb) {
|
||||
if (!process.env.ANDROID_HOME) {
|
||||
grunt.fatal("Could not find Android SDK, make sure to export ANDROID_HOME");
|
||||
}
|
||||
var cmd = path.resolve(process.env.ANDROID_HOME, "tools", "android");
|
||||
var projPath = path.resolve(__dirname, "uiautomator", "bootstrap");
|
||||
var args = ["create", "uitest-project", "-n", "AppiumBootstrap", "-t",
|
||||
"android-17", "-p", "."];
|
||||
|
||||
var proc = spawn(cmd, args, {cwd: projPath});
|
||||
proc.stdout.setEncoding('utf8');
|
||||
proc.stderr.setEncoding('utf8');
|
||||
proc.stdout.on('data', function(data) {
|
||||
grunt.log.write(data);
|
||||
});
|
||||
proc.stderr.on('data', function(data) {
|
||||
grunt.log.write(data);
|
||||
});
|
||||
proc.on('exit', function(code) {
|
||||
cb(code);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.buildAndroidBootstrap = function(grunt, cb) {
|
||||
exec('which ant', function(err, stdout) {
|
||||
if (err) {
|
||||
grunt.fatal(err);
|
||||
} else {
|
||||
if (stdout) {
|
||||
var ant = stdout.trim();
|
||||
grunt.log.write("Using ant found at " + ant);
|
||||
var projPath = path.resolve(__dirname, "uiautomator", "bootstrap");
|
||||
var proc = spawn(ant, ["build"], {cwd: projPath});
|
||||
proc.stdout.setEncoding('utf8');
|
||||
proc.stderr.setEncoding('utf8');
|
||||
proc.stdout.on('data', function(data) {
|
||||
grunt.log.write(data);
|
||||
});
|
||||
proc.stderr.on('data', function(data) {
|
||||
grunt.log.write(data);
|
||||
});
|
||||
proc.on('exit', function(code) {
|
||||
cb(code);
|
||||
});
|
||||
} else {
|
||||
grunt.fatal("Could not find ant installed; please make sure it's on PATH");
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
115
uiautomator/adb.js
Normal file
115
uiautomator/adb.js
Normal file
@@ -0,0 +1,115 @@
|
||||
"use strict";
|
||||
|
||||
var spawn = require('child_process').spawn
|
||||
, exec = require('child_process').exec
|
||||
, path = require('path')
|
||||
, logger = require('../logger').get('appium')
|
||||
, _ = require('underscore');
|
||||
|
||||
var ADB = function(opts, cb) {
|
||||
if (!opts) {
|
||||
opts = {};
|
||||
}
|
||||
if (typeof opts.sdkRoot === "undefined") {
|
||||
opts.sdkRoot = process.env.ANDROID_HOME || '';
|
||||
}
|
||||
this.sdkRoot = opts.sdkRoot;
|
||||
this.avdName = opts.avdName;
|
||||
this.adb = "adb";
|
||||
this.curDeviceId = null;
|
||||
if (this.sdkRoot) {
|
||||
this.adb = path.resolve(this.sdkRoot, "platform-tools", "adb");
|
||||
logger.info("Using adb from " + this.adb);
|
||||
cb(null, this);
|
||||
} else {
|
||||
exec("which adb", _.bind(function(err, stdout) {
|
||||
if (stdout) {
|
||||
logger.info("Using adb from " + stdout);
|
||||
this.adb = stdout;
|
||||
cb(null, this);
|
||||
} else {
|
||||
cb("Could not find adb; do you have android SDK installed?", null);
|
||||
}
|
||||
}, this));
|
||||
}
|
||||
};
|
||||
|
||||
ADB.prototype.getConnectedDevices = function(cb) {
|
||||
logger.info("Getting connected devices...");
|
||||
exec(this.adb + " devices", _.bind(function(err, stdout) {
|
||||
if (err) {
|
||||
logger.error(err);
|
||||
cb(err);
|
||||
} else {
|
||||
var output = stdout.replace("List of devices attached", "").trim();
|
||||
var devices = [];
|
||||
_.each(output.split("\n"), function(device) {
|
||||
if (device) {
|
||||
devices.push(device.split("\t"));
|
||||
}
|
||||
});
|
||||
logger.info("\t" + devices.length + " device(s) connected");
|
||||
if (devices.length) {
|
||||
this.curDeviceId = devices[0][0];
|
||||
}
|
||||
cb(null, devices);
|
||||
}
|
||||
}, this));
|
||||
};
|
||||
|
||||
ADB.prototype.forwardPort = function(systemPort, devicePort) {
|
||||
};
|
||||
|
||||
ADB.prototype.isDeviceConnected = function(cb) {
|
||||
this.getConnectedDevices(function(err, devices) {
|
||||
if (err) {
|
||||
cb(err);
|
||||
} else {
|
||||
cb(null, devices.length > 0);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ADB.prototype.setDeviceId = function(deviceId) {
|
||||
this.curDeviceId = deviceId;
|
||||
};
|
||||
|
||||
ADB.prototype.requireDeviceId = function() {
|
||||
if (!this.curDeviceId) {
|
||||
throw new Error("This method requires that a device ID is set. " +
|
||||
"Call getConnectedDevices or setDeviceId");
|
||||
}
|
||||
};
|
||||
|
||||
ADB.prototype.waitForDevice = function(cb) {
|
||||
this.requireDeviceId();
|
||||
logger.info("Waiting for device " + this.curDeviceId + " to be ready");
|
||||
exec(this.adb + " -s " + this.curDeviceId + " wait-for-device", function(err) {
|
||||
if (err) {
|
||||
logger.error(err);
|
||||
cb(err);
|
||||
} else {
|
||||
logger.info("\tready!");
|
||||
cb(null);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ADB.prototype.pushAppium = function(cb) {
|
||||
logger.info("Pushing appium bootstrap to device...");
|
||||
var binPath = path.resolve(__dirname, "bootstrap", "bin", "AppiumBootstrap.jar");
|
||||
var remotePath = "/data/local/tmp";
|
||||
exec(this.adb + " push " + binPath + " " + remotePath, function(err) {
|
||||
if (err) {
|
||||
logger.error(err);
|
||||
cb(err);
|
||||
} else {
|
||||
logger.info("\tdone");
|
||||
cb(null);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = function(opts, cb) {
|
||||
return new ADB(opts, cb);
|
||||
};
|
||||
Binary file not shown.
21
uiautomator/example.js
Normal file
21
uiautomator/example.js
Normal file
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
var makeAdb = require('./adb');
|
||||
var adbOpts = {
|
||||
sdkRoot: process.env.ANDROID_HOME
|
||||
, avd: "jlipps1"
|
||||
};
|
||||
|
||||
makeAdb(adbOpts, function(err, adb) {
|
||||
adb.getConnectedDevices(function(err, devices) {
|
||||
if (devices.length) {
|
||||
adb.waitForDevice(function(err) {
|
||||
adb.pushAppium(function(err) {
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.log("Can't proceed without a connected device!");
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user