basic ios8 support

This commit is contained in:
Jonathan Lipps
2014-06-13 10:55:33 -07:00
parent 4ac7a4ecd8
commit ece99e76ba
4 changed files with 116 additions and 40 deletions

View File

@@ -46,11 +46,11 @@ var parseXmlPlistFile = function (plist, cb) {
var parsePlistFile = function (plist, cb) {
bplistParse.parseFile(plist, function (err, obj) {
if (err) {
logger.error("Could not parse plist file (as binary) at " + plist);
logger.debug("Could not parse plist file (as binary) at " + plist);
logger.info("Will try to parse the plist file as XML");
parseXmlPlistFile(plist, function (err, obj) {
if (err) {
logger.error("Could not parse plist file (as XML) at " + plist);
logger.debug("Could not parse plist file (as XML) at " + plist);
return cb(err, null);
} else {
logger.debug("Parsed app Info.plist (as XML)");
@@ -276,7 +276,8 @@ IOS.prototype.start = function (cb, onDie) {
this.configureBootstrap.bind(this),
this.setBundleId.bind(this),
this.setInitialOrientation.bind(this),
this.initAutoWebview.bind(this)
this.initAutoWebview.bind(this),
this.waitForAppLaunched.bind(this),
], function (err) {
cb(err);
});
@@ -350,6 +351,15 @@ IOS.prototype.startInstruments = function (cb) {
};
IOS.prototype.makeInstruments = function (cb) {
// I-W-D crashes on Xcode 6, so force --native-instruments-lib on
if (this.xcodeVerNumeric >= 6 && this.args.withoutDelay) {
logger.warn("Your version of xcode and ios sdk do not support " +
"instruments-without-delay. Test execution will proceed more " +
"slowly");
this.args.withoutDelay = false;
}
// at the moment all the logging in uiauto is at debug level
// TODO: be able to use info in appium-uiauto
prepareBootstrap({
@@ -367,6 +377,7 @@ IOS.prototype.makeInstruments = function (cb) {
, bootstrap: bootstrapPath
, template: this.args.automationTraceTemplatePath
, withoutDelay: this.args.withoutDelay
, platformVersion: this.args.platformVersion
, xcodeVersion: this.xcodeVersion
, webSocket: this.args.webSocket
, launchTimeout: this.args.launchTimeout
@@ -430,6 +441,34 @@ IOS.prototype.setInitialOrientation = function (cb) {
}
};
IOS.prototype.waitForAppLaunched = function (cb) {
// on iOS8 in particular, we can get a working session before the app
// is ready to respond to commands; in that case the source will be empty
// so we just spin until it's not
logger.debug("Waiting for app source to contain elements");
var condFn = function (cb) {
this.getSourceForElementForXML(null, function (err, res) {
if (err || !res || res.status !== status.codes.Success.code) {
return cb(false, err);
}
var sourceObj, appEls;
try {
sourceObj = JSON.parse(res.value);
appEls = sourceObj.UIAApplication['>'];
if (appEls.length > 0) {
return cb(true);
} else {
return cb(false, new Error("App did not have elements"));
}
} catch (e) {
return cb(false, new Error("Couldn't parse JSON source"));
}
return cb(true, err);
});
}.bind(this);
this.waitForCondition(10000, condFn, cb, 500);
};
IOS.prototype.configureBootstrap = function (cb) {
logger.debug("Setting bootstrap config keys/values");
var isVerbose = logger.transports.console.level === 'debug';
@@ -539,7 +578,7 @@ IOS.prototype.setLocale = function (cb) {
logger.debug("Locale was set");
if (needSimRestart) {
logger.debug("First time setting locale, or locale changed, killing existing Instruments and Sim procs.");
Instruments.killAllSim();
Instruments.killAllSim(this.xcodeVersion);
Instruments.killAll();
setTimeout(cb, 250);
} else {
@@ -746,9 +785,10 @@ IOS.prototype.detectTraceTemplate = function (cb) {
helpers.getXcodeFolder(function (err, xcodeFolderPath) {
if (err) return cb(err);
if (xcodeFolderPath !== null) {
var instExt = this.iOSSDKVersion >= 8 ? 'xrplugin' : 'bundle';
var xcodeTraceTemplatePath = path.resolve(xcodeFolderPath,
"../Applications/Instruments.app/Contents/PlugIns",
"AutomationInstrument.bundle/Contents/Resources",
"AutomationInstrument." + instExt + "/Contents/Resources",
"Automation.tracetemplate");
if (fs.existsSync(xcodeTraceTemplatePath)) {
this.args.automationTraceTemplatePath = xcodeTraceTemplatePath;
@@ -929,7 +969,7 @@ IOS.prototype.getDeviceString = function () {
} else {
iosDeviceString += isRetina ? " (Retina)" : "";
}
} else {
} else if (this.xcodeVersion[0] === '5') {
iosDeviceString += isRetina ? " Retina" : "";
if (isiPhone) {
if (isRetina && isTall) {
@@ -940,16 +980,25 @@ IOS.prototype.getDeviceString = function () {
} else {
iosDeviceString += is64bit ? " (64-bit)" : "";
}
} else if (this.xcodeVersion[0] === '6') {
iosDeviceString = this.args.deviceName ||
(isiPhone ? "iPhone Simulator" : "iPad Simulator");
}
if (this.iOSSDKVersion >= 7.1) {
iosDeviceString += " - Simulator - iOS " +
(this.args.platformVersion || this.iOSSDKVersion);
var reqVersion = this.args.platformVersion || this.iOSSDKVersion;
if (this.iOSSDKVersion >= 8) {
iosDeviceString += " (" + reqVersion + " Simulator)";
} else if (this.iOSSDKVersion >= 7.1) {
iosDeviceString += " - Simulator - iOS " + reqVersion;
}
if (fixDevice) {
// Some device config are broken in 5.1
var CONFIG_FIX = {
'iPhone - Simulator - iOS 7.1': 'iPhone Retina (4-inch 64-bit) - Simulator - iOS 7.1',
'iPad - Simulator - iOS 7.1': 'iPad Retina (64-bit) - Simulator - iOS 7.1'
'iPad - Simulator - iOS 7.1': 'iPad Retina (64-bit) - Simulator - iOS 7.1',
'iPad Simulator (8.0 Simulator)': 'iPad 2 (8.0 Simulator)',
'iPad Simulator (7.1 Simulator)': 'iPad 2 (7.1 Simulator)',
'iPhone Simulator (8.0 Simulator)': 'iPhone 6 (8.0 Simulator)',
'iPhone Simulator (7.1 Simulator)': 'iPhone 5s (7.1 Simulator)'
};
if (CONFIG_FIX[iosDeviceString]) {
var oldDeviceString = iosDeviceString;
@@ -1005,14 +1054,26 @@ IOS.prototype.checkDeviceAvailable = function (cb) {
if (this.iOSSDKVersion >= 7.1) {
logger.debug("Checking whether instruments supports our device string");
Instruments.getAvailableDevicesWithRetry(3, function (err, availDevices) {
var dString = this.getDeviceString();
if (err) return cb(err);
if (!_.contains(availDevices, dString)) {
var noDevicesError = function () {
var msg = "Could not find a device to launch. You requested '" +
dString + "', but the available devices were: " +
JSON.stringify(availDevices);
logger.error(msg);
return cb(new Error(msg));
cb(new Error(msg));
};
var dString = this.getDeviceString();
if (this.iOSSDKVersion >= 8) {
var matchedDevice = null;
_.each(availDevices, function (device) {
if (device.indexOf(dString) !== -1) {
matchedDevice = device;
}
});
if (matchedDevice === null) return noDevicesError();
return cb();
} else if (!_.contains(availDevices, dString)) {
return noDevicesError();
}
cb();
}.bind(this));
@@ -1034,12 +1095,16 @@ IOS.prototype.setDeviceAndLaunchSimulator = function (cb) {
} else if (!this.args.deviceName && this.args.forceIphone === null && this.args.forceIpad === null) {
logger.debug("No device specified, current device in the iOS simulator will be used.");
cb(null);
} else if (this.args.defaultDevice) {
logger.debug("User specified default device, letting instruments launch it");
} else if (this.args.defaultDevice || this.iOSSDKVersion >= 8) {
if (this.iOSSDKVersion >= 8) {
logger.debug("We're on iOS8 so forcing defaultDevice on");
} else {
logger.debug("User specified default device, letting instruments launch it");
}
this.checkDeviceAvailable(function (err) {
if (err) return cb(err);
var iosDeviceString = this.getDeviceString();
var isiPhone = iosDeviceString.toLowerCase().indexOf("ipad") === -1;
var dString = this.getDeviceString();
var isiPhone = dString.toLowerCase().indexOf("ipad") === -1;
this.setDeviceTypeInInfoPlist(isiPhone ? 1 : 2, cb);
}.bind(this));
} else {
@@ -1133,7 +1198,8 @@ IOS.prototype.parseLocalizableStrings = function (cb, language) {
parsePlistFile(strings, function (err, obj) {
if (err) {
logger.warn("Could not parse app Localizable.strings");
logger.warn("Could not parse app Localizable.strings; assuming it " +
"doesn't exist");
} else {
logger.debug("Parsed app Localizable.strings");
this.localizableStrings = obj;
@@ -1293,25 +1359,18 @@ IOS.prototype.endSimulator = function (cb) {
if (this.iosSimProcess) {
this.iosSimProcess.kill("SIGHUP");
this.iosSimProcess = null;
this.endSimulatorDaemons(cb);
} else {
var cmd = 'killall -9 "iPhone Simulator"';
exec(cmd, { maxBuffer: 524288 }, function (err) {
if (err && err.message.indexOf('matching processes') === -1) {
cb(err);
} else {
this.endSimulatorDaemons(cb);
}
}.bind(this));
Instruments.killAllSim(this.xcodeVersion);
}
this.endSimulatorDaemons(cb);
};
IOS.prototype.endSimulatorDaemons = function (cb) {
logger.debug("Killing any other simulator daemons");
var stopCmd = 'launchctl list | grep com.apple.iphonesimulator.launchd | cut -f 3 | xargs -n 1 launchctl stop';
var stopCmd = 'launchctl list | grep com.apple.iphonesimulator | cut -f 3 | xargs -n 1 launchctl stop';
exec(stopCmd, { maxBuffer: 524288 }, function () {
var removeCmd = 'launchctl list | grep com.apple.iphonesimulator.launchd | cut -f 3 | xargs -n 1 launchctl remove';
var removeCmd = 'launchctl list | grep com.apple.iphonesimulator | cut -f 3 | xargs -n 1 launchctl remove';
exec(removeCmd, { maxBuffer: 524288 }, function () {
cb();
});

View File

@@ -152,12 +152,17 @@ reset_ios() {
set +e
sdk_ver=$(xcrun --sdk iphonesimulator --show-sdk-version 2>/dev/null)
sdk_status=$?
ios7_active=true
if [ $sdk_status -gt 0 ] || [[ "$sdk_ver" != "7."* ]]; then
echo "--------------------------------------------------"
echo "WARNING: you do not appear to have iOS7 SDK active"
echo "--------------------------------------------------"
ios7_active=false
ios7_active=false
ios8_active=false
if [[ "$sdk_ver" == "7."* ]]; then
ios7_active=true
elif [[ "$sdk_ver" == "8."* ]]; then
ios8_active=true
fi
if [ $sdk_status -gt 0 ] || (! $ios7_active && ! $ios8_active); then
echo "---------------------------------------------------"
echo "WARNING: you do not appear to have iOS7/8 SDK active"
echo "---------------------------------------------------"
fi
set -e
echo "* Setting iOS config to Appium's version"
@@ -186,7 +191,7 @@ reset_ios() {
echo "* Cloning/npm linking appium-adb"
run_cmd ./bin/npmlink.sh -l appium-adb
fi
if $ios7_active ; then
if $ios7_active || $ios8_active ; then
if $hardcore ; then
echo "* Clearing out old UICatalog download"
run_cmd rm -rf ./sample-code/apps/UICatalog/

View File

@@ -52,7 +52,7 @@ describe('testapp - basics - calc app 2', function () {
});
// TODO: Fails on sauce, investigate
it('should be able to get syslog logs @skip-ios6 @skip-ci', function (done) {
it('should be able to get syslog logs @skip-ios6 @skip-ios8 @skip-ci', function (done) {
driver
.setImplicitWaitTimeout(4000)
.elementByName('SumLabelz')

View File

@@ -63,8 +63,8 @@ function iphoneOrIpadSimulator(device, version) {
case '7.0':
case '7.1':
return isIpad ? 'iPad Simulator' : 'iPhone Simulator';
// case '7.1':
// return isIpad ? 'iPad Retina' : 'iPhone Retina 4-inch';
case '8.0':
return isIpad ? 'iPad 2' : 'iPhone 5s';
default:
throw new Error("invalid version");
}
@@ -99,6 +99,15 @@ switch (env.DEVICE) {
, app: process.env.APP ? path.resolve(__dirname, "../../sample-code/apps/" + process.env.APP + "/build/Release-iphonesimulator/" + process.env.APP + ".app") : ''
};
break;
case 'ios8':
case 'ios8_iphone':
case 'ios8_ipad':
env.CAPS = {
browserName: ''
, deviceName: iphoneOrIpadSimulator(env.DEVICE, "8.0")
, app: process.env.APP ? path.resolve(__dirname, "../../sample-code/apps/" + process.env.APP + "/build/Release-iphonesimulator/" + process.env.APP + ".app") : ''
};
break;
case 'android':
env.CAPS = {
browserName: ''
@@ -132,12 +141,13 @@ env.IOS = env.DEVICE.match(/ios/i);
env.IOS6 = env.DEVICE.match(/ios6/i);
env.IOS7 = env.DEVICE.match(/ios7/i);
env.IOS71 = env.DEVICE.match(/ios71/i);
env.IOS8 = env.DEVICE.match(/ios8/i);
env.ANDROID = env.DEVICE.match(/android/i);
env.SELENDROID = env.DEVICE.match(/selendroid/i);
// better timeout settings for 71
env.LAUNCH_TIMEOUT = process.env.LAUNCH_TIMEOUT ? JSON.parse(process.env.LAUNCH_TIMEOUT) :
(env.IOS71 ? {"global": 60000, "afterSimLaunch": 10000} : 60000);
((env.IOS71 || env.IOS8) ? {"global": 60000, "afterSimLaunch": 10000} : 60000);
env.CAPS.launchTimeout = env.LAUNCH_TIMEOUT;
@@ -157,6 +167,8 @@ if (env.VERSION) {
env.CAPS.platformVersion = "7.1";
} else if (env.IOS7) {
env.CAPS.platformVersion = "7.0";
} else if (env.IOS8) {
env.CAPS.platformVersion = "8.0";
}
// max retry