private static async Task ConfigureForAndroidTests(TestConfiguration config, int?androidSdk, string headBin, CancellationToken cancellationToken) { // Ensure WebDrivers are installed await SdkManager.InstallWebDriver(cancellationToken).ConfigureAwait(false); // Ensure latest CmdLine tools are installed await SdkManager.InstallLatestCommandLineTools(cancellationToken).ConfigureAwait(false); var sdkVersion = ApkHelper.GetAndroidSdkVersion(androidSdk, headBin); Logger.WriteLine($"Targeting Android Sdk: {sdkVersion}", LogLevel.Minimal); var appActivity = ApkHelper.GetAppActivity(headBin); if (!config.Capabilities.ContainsKey("appActivity")) { config.Capabilities.Add("appActivity", appActivity); } var emulatorName = $"{AvdManager.DefaultUITestEmulatorName}{sdkVersion}"; // Check for connected device if (await Adb.DeviceIsConnected(cancellationToken)) { var androidDevice = (await Adb.ListDevices(cancellationToken).ConfigureAwait(false)).First(); config.DeviceName = androidDevice.Name; config.UDID = androidDevice.Id; config.OSVersion = $"{androidDevice.SdkVersion}"; } else { // Ensure SDK Installed await SdkManager.EnsureSdkIsInstalled(sdkVersion, cancellationToken).ConfigureAwait(false); // Ensure Emulator Exists if (!(await Emulator.ListEmulators(cancellationToken)).Any(x => x == emulatorName)) { await AvdManager.InstallEmulator(emulatorName, sdkVersion, cancellationToken); } // Let Appium Start and control the Emulator config.DeviceName = emulatorName; config.OSVersion = $"{sdkVersion}"; if (!config.Capabilities.ContainsKey("avd")) { config.Capabilities.Add("avd", emulatorName); } } }
private AppVersion LoadVersionFromApkFile() { var appVersion = ApkHelper.LoadAppVersion(this.apkFile); var fileVesion = this.LoadVersionFromVersionFile(); if (null != fileVesion && fileVesion.VersionCode == appVersion.VersionCode && fileVesion.VersionName == appVersion.VersionName) { appVersion = fileVesion; } else { this.UpdateVersionFile(); } return(appVersion); }
protected override Task <ExitCode> InvokeInternal(ILogger logger) { if (!File.Exists(_arguments.AppPackagePath)) { logger.LogCritical($"Couldn't find {_arguments.AppPackagePath}!"); return(Task.FromResult(ExitCode.PACKAGE_NOT_FOUND)); } var runner = new AdbRunner(logger); string apkRequiredArchitecture; if (!string.IsNullOrEmpty(_arguments.DeviceArchitecture)) { apkRequiredArchitecture = _arguments.DeviceArchitecture; } else { apkRequiredArchitecture = ApkHelper.GetApkSupportedArchitectures(_arguments.AppPackagePath).First(); } try { // Make sure the adb server is started runner.StartAdbServer(); // enumerate the devices attached and their architectures // Tell ADB to only use that one (will always use the present one for systems w/ only 1 machine) var deviceToUse = runner.GetDeviceToUse(logger, apkRequiredArchitecture, "architecture"); if (deviceToUse == null) { return(Task.FromResult(ExitCode.ADB_DEVICE_ENUMERATION_FAILURE)); } Console.WriteLine(deviceToUse); return(Task.FromResult(ExitCode.SUCCESS)); } catch (Exception toLog) { logger.LogCritical(toLog, $"Failure to find compatible device: {toLog.Message}"); } return(Task.FromResult(ExitCode.GENERAL_FAILURE)); }
protected override Task <ExitCode> InvokeInternal(ILogger logger) { logger.LogDebug($"Android Install command called: App = {_arguments.AppPackagePath}"); logger.LogDebug($"Timeout = {_arguments.Timeout.TotalSeconds} seconds."); if (!File.Exists(_arguments.AppPackagePath)) { logger.LogCritical($"Couldn't find {_arguments.AppPackagePath}!"); return(Task.FromResult(ExitCode.PACKAGE_NOT_FOUND)); } var runner = new AdbRunner(logger); string?apkRequiredArchitecture = null; if (string.IsNullOrEmpty(_arguments.DeviceId)) { // trying to choose suitable device if (!string.IsNullOrEmpty(_arguments.DeviceArchitecture)) { apkRequiredArchitecture = _arguments.DeviceArchitecture; logger.LogInformation($"Will attempt to run device on specified architecture: '{apkRequiredArchitecture}'"); } else { apkRequiredArchitecture = ApkHelper.GetApkSupportedArchitectures(_arguments.AppPackagePath).First(); logger.LogInformation($"Will attempt to run device on detected architecture: '{apkRequiredArchitecture}'"); } } // Package Name is not guaranteed to match file name, so it needs to be mandatory. return(Task.FromResult(InvokeHelper( logger: logger, apkPackageName: _arguments.PackageName, appPackagePath: _arguments.AppPackagePath, apkRequiredArchitecture: apkRequiredArchitecture, deviceId: _arguments.DeviceId, runner: runner))); }
protected override Task <ExitCode> InvokeInternal(ILogger logger) { logger.LogDebug($"Android Test command called: App = {_arguments.AppPackagePath}{Environment.NewLine}Instrumentation Name = {_arguments.InstrumentationName}"); logger.LogDebug($"Output Directory:{_arguments.OutputDirectory}{Environment.NewLine}Timeout = {_arguments.Timeout.TotalSeconds} seconds."); logger.LogDebug("Arguments to instrumentation:"); if (!File.Exists(_arguments.AppPackagePath)) { logger.LogCritical($"Couldn't find {_arguments.AppPackagePath}!"); return(Task.FromResult(ExitCode.PACKAGE_NOT_FOUND)); } var runner = new AdbRunner(logger); // Assumption: APKs we test will only have one arch for now string apkRequiredArchitecture; if (!string.IsNullOrEmpty(_arguments.DeviceArchitecture)) { apkRequiredArchitecture = _arguments.DeviceArchitecture; logger.LogInformation($"Will attempt to run device on specified architecture: '{apkRequiredArchitecture}'"); } else { apkRequiredArchitecture = ApkHelper.GetApkSupportedArchitectures(_arguments.AppPackagePath).First(); logger.LogInformation($"Will attempt to run device on detected architecture: '{apkRequiredArchitecture}'"); } // Package Name is not guaranteed to match file name, so it needs to be mandatory. string apkPackageName = _arguments.PackageName; int instrumentationExitCode = (int)ExitCode.GENERAL_FAILURE; try { using (logger.BeginScope("Initialization and setup of APK on device")) { // Make sure the adb server is freshly started runner.KillAdbServer(); runner.StartAdbServer(); // Wait til at least device(s) are ready runner.WaitForDevice(); // enumerate the devices attached and their architectures // Tell ADB to only use that one (will always use the present one for systems w/ only 1 machine) runner.SetActiveDevice(GetDeviceToUse(logger, runner, apkRequiredArchitecture)); // Empty log as we'll be uploading the full logcat for this execution runner.ClearAdbLog(); logger.LogDebug($"Working with {runner.GetAdbVersion()}"); // If anything changed about the app, Install will fail; uninstall it first. // (we'll ignore if it's not present) // This is where mismatched architecture APKs fail. runner.UninstallApk(apkPackageName); if (runner.InstallApk(_arguments.AppPackagePath) != 0) { logger.LogCritical("Install failure: Test command cannot continue"); return(Task.FromResult(ExitCode.PACKAGE_INSTALLATION_FAILURE)); } runner.KillApk(apkPackageName); } // No class name = default Instrumentation (string stdOut, _, int exitCode) = runner.RunApkInstrumentation(apkPackageName, _arguments.InstrumentationName, _arguments.InstrumentationArguments, _arguments.Timeout); using (logger.BeginScope("Post-test copy and cleanup")) { if (exitCode == (int)ExitCode.SUCCESS) { (var resultValues, var instrExitCode) = ParseInstrumentationOutputs(logger, stdOut); instrumentationExitCode = instrExitCode; foreach (string possibleResultKey in _xmlOutputVariableNames) { if (resultValues.ContainsKey(possibleResultKey)) { logger.LogInformation($"Found XML result file: '{resultValues[possibleResultKey]}'(key: {possibleResultKey})"); runner.PullFiles(resultValues[possibleResultKey], _arguments.OutputDirectory); } } } // Optionally copy off an entire folder if (!string.IsNullOrEmpty(_arguments.DeviceOutputFolder)) { var logs = runner.PullFiles(_arguments.DeviceOutputFolder, _arguments.OutputDirectory); foreach (string log in logs) { logger.LogDebug($"Found output file: {log}"); } } runner.DumpAdbLog(Path.Combine(_arguments.OutputDirectory, $"adb-logcat-{_arguments.PackageName}.log")); runner.UninstallApk(apkPackageName); } if (instrumentationExitCode != (int)ExitCode.SUCCESS) { logger.LogError($"Non-success instrumentation exit code: {instrumentationExitCode}"); } else { return(Task.FromResult(ExitCode.SUCCESS)); } } catch (Exception toLog) { logger.LogCritical(toLog, $"Failure to run test package: {toLog.Message}"); } finally { runner.KillAdbServer(); } return(Task.FromResult(ExitCode.GENERAL_FAILURE)); }