mirror of
https://github.com/appium/appium.git
synced 2026-05-01 07:51:30 -05:00
311 lines
11 KiB
JavaScript
311 lines
11 KiB
JavaScript
"use strict";
|
|
var path = require('path')
|
|
, fs = require('fs')
|
|
, env = process.env
|
|
, exec = require('child_process').exec
|
|
, async = require('async');
|
|
|
|
require("./common.js");
|
|
|
|
function IOSChecker(log) {
|
|
this.log = log;
|
|
this.osVersion = null;
|
|
}
|
|
exports.IOSChecker = IOSChecker;
|
|
|
|
IOSChecker.prototype.runAllChecks = function (cb) {
|
|
async.series([
|
|
this.getMacOSXVersion.bind(this),
|
|
this.checkForXcode.bind(this),
|
|
this.checkForXcodeCommandLineTools.bind(this),
|
|
this.checkDevToolsSecurity.bind(this),
|
|
this.checkAuthorizationDB.bind(this),
|
|
this.checkForNodeBinary.bind(this)
|
|
], cb);
|
|
};
|
|
|
|
IOSChecker.prototype.getMacOSXVersion = function (cb) {
|
|
exec("sw_vers -productVersion", function (err, stdout) {
|
|
if (err === null) {
|
|
if (stdout.match('10.8') !== null) {
|
|
this.osVersion = '10.8';
|
|
cb(null, "Mac OS X 10.8 is installed.");
|
|
} else if (stdout.match('10.9') !== null) {
|
|
this.osVersion = '10.9';
|
|
cb(null, "Mac OS X 10.9 is installed.");
|
|
} else {
|
|
this.log.fail("Could not detect Mac OS X Version", cb);
|
|
}
|
|
} else {
|
|
this.log.fail("Unknown SW Version Command: " + err, cb);
|
|
}
|
|
}.bind(this));
|
|
};
|
|
|
|
IOSChecker.prototype.checkForXcode = function (cb) {
|
|
var msg;
|
|
exec("xcode-select --print-path", { maxBuffer: 524288}, function (err, stdout) {
|
|
if (err === null) {
|
|
var xcodePath = stdout.replace("\n", "");
|
|
if (fs.existsSync(xcodePath)) {
|
|
this.log.pass("Xcode is installed at " + xcodePath, cb);
|
|
} else {
|
|
msg = "Xcode is not installed.";
|
|
this.log.fail(msg);
|
|
this.log.promptToFix("Xcode is not installed.", function () {
|
|
this.installXcode(cb);
|
|
}.bind(this), function () {
|
|
cb(msg, msg);
|
|
});
|
|
}
|
|
} else {
|
|
msg = "Xcode is not installed: " + err;
|
|
this.log.fail(msg);
|
|
this.log.promptToFix("Xcode is not installed.", function () {
|
|
this.installXcode(cb);
|
|
}.bind(this), function () {
|
|
cb(msg, msg);
|
|
});
|
|
}
|
|
}.bind(this));
|
|
};
|
|
|
|
IOSChecker.prototype.checkForXcodeCommandLineTools = function (cb) {
|
|
var msg;
|
|
var pkgName = this.osVersion === '10.8' ? "com.apple.pkg.DeveloperToolsCLI" : "com.apple.pkg.CLTools_Executables";
|
|
exec("pkgutil --pkg-info=" + pkgName, { maxBuffer: 524288}, function (err, stdout) {
|
|
if (err === null) {
|
|
var match = stdout.match(/install-time/);
|
|
if (match !== null) {
|
|
this.log.pass("Xcode Command Line Tools are installed.", cb);
|
|
} else {
|
|
msg = "Xcode Command Line Tools are NOT installed.";
|
|
this.log.fail(msg);
|
|
this.log.promptToFix("Xcode's command line tools are NOT installed.", function () {
|
|
this.installXcodeCommandLineTools(cb);
|
|
}.bind(this), function () {
|
|
cb(msg, msg);
|
|
});
|
|
}
|
|
} else {
|
|
msg = "Xcode Command Line Tools are NOT installed: " + err;
|
|
this.log.fail(msg);
|
|
this.log.promptToFix("Xcode's command line tools are NOT installed.", function () {
|
|
this.installXcodeCommandLineTools(cb);
|
|
}.bind(this), function () {
|
|
cb(msg, msg);
|
|
});
|
|
}
|
|
}.bind(this));
|
|
};
|
|
|
|
IOSChecker.prototype.checkDevToolsSecurity = function (cb) {
|
|
var msg;
|
|
exec("DevToolsSecurity", { maxBuffer: 524288}, function (err, stdout) {
|
|
if (err === null && stdout.match(/enabled/) !== null) {
|
|
this.log.pass("DevToolsSecurity is enabled.", cb);
|
|
} else {
|
|
msg = 'DevToolsSecurity is not enabled.';
|
|
this.log.fail(msg);
|
|
this.log.promptToFix(msg, function () {
|
|
this.authorizeIOS(this.checkDevToolsSecurity.bind(this), cb);
|
|
}.bind(this), function () {
|
|
cb(msg, msg);
|
|
});
|
|
}
|
|
}.bind(this));
|
|
};
|
|
|
|
IOSChecker.prototype.checkAuthorizationDB = function (cb) {
|
|
var msg;
|
|
exec("security authorizationdb read system.privilege.taskport", { maxBuffer: 524288}, function (err, stdout) {
|
|
if (err === null && (stdout.match(/is-developer/) !== null || stdout.match(/allow/) !== null)) {
|
|
this.log.pass("The Authorization DB is set up properly.", cb);
|
|
} else if (this.osVersion === '10.8') {
|
|
fs.readFile('/etc/authorization', 'utf8', function (err, data) {
|
|
if (err) {
|
|
this.log.fail('The Authorization DB is NOT set up properly.', cb);
|
|
} else {
|
|
var match = data.match(/<key>system.privilege.taskport<\/key>\s*\n\s*<dict>\n\s*<key>allow-root<\/key>\n\s*(<true\/>)/);
|
|
if (match !== null) {
|
|
this.log.pass("The Authorization DB is set up properly.", cb);
|
|
} else {
|
|
this.log.fail('The Authorization DB is NOT set up properly.', cb);
|
|
}
|
|
}
|
|
}.bind(this));
|
|
} else {
|
|
msg = 'The Authorization DB is NOT set up properly.';
|
|
this.log.fail(msg);
|
|
this.log.promptToFix(msg, function () {
|
|
this.authorizeIOS(this.checkAuthorizationDB.bind(this), cb);
|
|
}.bind(this), function () {
|
|
cb(msg, msg);
|
|
});
|
|
}
|
|
}.bind(this));
|
|
};
|
|
|
|
IOSChecker.prototype.checkForNodeBinary = function (cb) {
|
|
this.checkForNodeBinaryInCommonPlaces(function (err, msg) {
|
|
if (!err) {
|
|
cb(null, msg);
|
|
} else {
|
|
this.checkForNodeBinaryUsingWhichCommand(function (err, msg) {
|
|
if (!err) {
|
|
cb(null, msg);
|
|
} else {
|
|
this.checkForNodeBinaryUsingAppleScript(function (err, msg) {
|
|
if (!err) {
|
|
cb(null, msg);
|
|
} else {
|
|
this.checkForNodeBinaryUsingAppiumConfigFile(function (err, msg) {
|
|
if (!err) {
|
|
cb(null, msg);
|
|
} else {
|
|
msg = 'The node binary could not be found.';
|
|
this.log.fail(msg);
|
|
this.log.promptToFix("The node binary could not be found.", function () {
|
|
this.setupNodeBinaryPath(cb);
|
|
}.bind(this), function () {
|
|
cb(msg, msg);
|
|
});
|
|
}
|
|
}.bind(this));
|
|
}
|
|
}.bind(this));
|
|
}
|
|
}.bind(this));
|
|
}
|
|
}.bind(this));
|
|
};
|
|
|
|
IOSChecker.prototype.checkForNodeBinaryInCommonPlaces = function (cb) {
|
|
if (typeof env.NODE_BIN !== "undefined" && fs.existsSync(env.NODE_BIN)) {
|
|
this.log.pass("Node binary found using NODE_BIN environment variable at " + env.NODE_BIN, cb);
|
|
} else if (fs.existsSync('/usr/local/bin/node')) {
|
|
this.log.pass("Node binary found at /usr/local/bin/node", cb);
|
|
} else if (fs.existsSync('/opt/local/bin/node')) {
|
|
this.log.pass("Node binary found at /opt/local/bin/node", cb);
|
|
} else {
|
|
var msg = 'Node binary could not be found in the usual places';
|
|
cb(msg, msg);
|
|
}
|
|
};
|
|
|
|
IOSChecker.prototype.checkForNodeBinaryUsingWhichCommand = function (cb) {
|
|
var msg;
|
|
exec("which node", { maxBuffer: 524288}, function (err, stdout) {
|
|
if (err === null && fs.existsSync(stdout.replace("\n", ""))) {
|
|
this.log.pass("Node binary found using which command at " + stdout.replace("\n", ""), cb);
|
|
} else {
|
|
msg = 'Node binary not found using the which command.';
|
|
cb(msg, msg);
|
|
}
|
|
}.bind(this));
|
|
};
|
|
|
|
IOSChecker.prototype.checkForNodeBinaryUsingAppleScript = function (cb) {
|
|
var msg;
|
|
var appScript = [
|
|
'try'
|
|
, ' set appiumIsRunning to false'
|
|
, ' tell application "System Events"'
|
|
, ' set appiumIsRunning to name of every process contains "Appium"'
|
|
, ' end tell'
|
|
, ' if appiumIsRunning then'
|
|
, ' tell application "Appium" to return node path'
|
|
, ' end if'
|
|
, 'end try'
|
|
, 'return "NULL"'
|
|
].join("\n");
|
|
exec("osascript -e '" + appScript + "'", { maxBuffer: 524288}, function (err, stdout) {
|
|
if (err === null && fs.existsSync(stdout.replace("\n", ""))) {
|
|
this.log.pass("Node binary found using AppleScript at " + stdout.replace("\n", ""), cb);
|
|
} else {
|
|
msg = 'Node binary not found using AppleScript.';
|
|
cb(msg, msg);
|
|
}
|
|
}.bind(this));
|
|
};
|
|
|
|
IOSChecker.prototype.checkForNodeBinaryUsingAppiumConfigFile = function (cb) {
|
|
var msg = 'Node binary not found in the .appiumconfig.json file.';
|
|
var appiumConfigPath = path.resolve(__dirname, "../..", ".appiumconfig.json");
|
|
if (fs.existsSync(appiumConfigPath)) {
|
|
fs.readFile(appiumConfigPath, 'utf8', function (err, data) {
|
|
if (err === null) {
|
|
try {
|
|
var jsonobj = JSON.parse(data);
|
|
if (typeof jsonobj.node_bin !== "undefined" && fs.existsSync(jsonobj.node_bin)) {
|
|
this.log.pass("Node binary found using .appiumconfig.json at " + jsonobj.node_bin, cb);
|
|
} else {
|
|
cb(msg, msg);
|
|
}
|
|
} catch (jsonErr) {
|
|
cb(msg, msg);
|
|
}
|
|
} else {
|
|
cb(msg, msg);
|
|
}
|
|
}.bind(this));
|
|
} else {
|
|
cb(msg, msg);
|
|
}
|
|
};
|
|
|
|
IOSChecker.prototype.installXcode = function (cb) {
|
|
exec("xcode-select --install", { maxBuffer: 524288}, function () {
|
|
this.log.promptToConfirmFix(function () {
|
|
this.checkForXcode(cb);
|
|
}.bind(this));
|
|
}.bind(this));
|
|
};
|
|
|
|
IOSChecker.prototype.installXcodeCommandLineTools = function (cb) {
|
|
exec("xcode-select --install", { maxBuffer: 524288}, function () {
|
|
this.log.promptToConfirmFix(function () {
|
|
this.checkForXcodeCommandLineTools(cb);
|
|
}.bind(this));
|
|
}.bind(this));
|
|
};
|
|
|
|
IOSChecker.prototype.authorizeIOS = function (outerCb, innerCb) {
|
|
var authorizePath = path.resolve(__dirname, "../../bin", "authorize-ios.js");
|
|
exec("'" + process.execPath + "' '" + authorizePath + "'", { maxBuffer: 524288}, function (err) {
|
|
if (err) {
|
|
this.log.error('Could not authorize iOS: ' + err);
|
|
}
|
|
}.bind(this)).on('exit', function () {
|
|
this.log.promptToConfirmFix(function () {
|
|
outerCb(innerCb);
|
|
}.bind(this));
|
|
}.bind(this));
|
|
};
|
|
|
|
IOSChecker.prototype.setupNodeBinaryPath = function (cb) {
|
|
var appiumConfigPath = path.resolve(__dirname, "../../", ".appiumconfig.json");
|
|
if (fs.existsSync(appiumConfigPath)) {
|
|
fs.readFile(appiumConfigPath, 'utf8', function (err, data) {
|
|
if (!err) {
|
|
try {
|
|
var jsonobj = JSON.parse(data);
|
|
jsonobj.node_bin = process.execPath;
|
|
fs.writeFile(appiumConfigPath, JSON.stringify(jsonobj), function () {
|
|
this.checkForNodeBinary(cb);
|
|
}.bind(this));
|
|
} catch (jsonErr) {
|
|
this.log.error("Could not setup node binary path in .appiumconfig.json. Error parsing JSON: " + jsonErr);
|
|
this.checkForNodeBinary(cb);
|
|
}
|
|
} else {
|
|
this.log.error("Could not setup node binary path in .appiumconfig.json. Error reading config: " + err);
|
|
this.checkForNodeBinary(cb);
|
|
}
|
|
}.bind(this));
|
|
} else {
|
|
this.log.error('The .appiumconfig.json file was not found at ' + appiumConfigPath);
|
|
this.exitDoctor();
|
|
}
|
|
};
|