public async Task <(string deviceName, ProcessExecutionResult result)> InstallApp(AppBundleInformation appBundleInformation, TestTargetOs target, string?deviceName = null, CancellationToken cancellationToken = default) { if (target.Platform.IsSimulator()) { // We reset the simulator when running, so a separate install step does not make much sense. throw new InvalidOperationException("Installing to a simulator is not supported."); } if (!Directory.Exists(appBundleInformation.LaunchAppPath)) { throw new DirectoryNotFoundException("Failed to find the app bundle directory"); } if (deviceName == null) { // the _deviceLoader.FindDevice will return the fist device of the type, but we want to make sure that // the device we use is if the correct arch, therefore, we will use the LoadDevices and return the // correct one await _deviceLoader.LoadDevices(_mainLog, false, false); IHardwareDevice?device = null; if (appBundleInformation.Supports32Bit) { // we only support 32b on iOS, therefore we can ignore the target device = _deviceLoader.Connected32BitIOS.FirstOrDefault(); } else { device = target.Platform switch { TestTarget.Device_iOS => _deviceLoader.Connected64BitIOS.FirstOrDefault(), TestTarget.Device_tvOS => _deviceLoader.ConnectedTV.FirstOrDefault(), _ => device }; } deviceName = target.Platform.IsWatchOSTarget() ? (await _deviceLoader.FindCompanionDevice(_mainLog, device)).Name : device?.Name; } if (deviceName == null) { throw new NoDeviceFoundException(); } var args = new MlaunchArguments(); for (int i = -1; i < _verbosity; i++) { args.Add(new VerbosityArgument()); } args.Add(new InstallAppOnDeviceArgument(appBundleInformation.LaunchAppPath)); args.Add(new DeviceNameArgument(deviceName)); if (target.Platform.IsWatchOSTarget()) { args.Add(new DeviceArgument("ios,watchos")); } var totalSize = Directory.GetFiles(appBundleInformation.LaunchAppPath, "*", SearchOption.AllDirectories).Select((v) => new FileInfo(v).Length).Sum(); _mainLog.WriteLine($"Installing '{appBundleInformation.LaunchAppPath}' to '{deviceName}' ({totalSize / 1024.0 / 1024.0:N2} MB)"); ProcessExecutionResult result = await _processManager.ExecuteCommandAsync(args, _mainLog, TimeSpan.FromHours(1), cancellationToken : cancellationToken); return(deviceName, result); } }
public async Task <DevicePair> FindDevice( TestTargetOs target, string?deviceName, ILog log, bool includeWirelessDevices = true, CancellationToken cancellationToken = default) { IDevice?device; IDevice?companionDevice = null; bool IsMatchingDevice(IDevice device) => device.Name.Equals(deviceName, StringComparison.InvariantCultureIgnoreCase) || device.UDID.Equals(deviceName, StringComparison.InvariantCultureIgnoreCase); if (target.Platform.IsSimulator()) { if (deviceName == null) { (device, companionDevice) = await _simulatorLoader.FindSimulators(target, log, retryCount : 3, cancellationToken : cancellationToken); } else { await _simulatorLoader.LoadDevices(log, includeLocked : false, cancellationToken : cancellationToken); device = _simulatorLoader.AvailableDevices.FirstOrDefault(IsMatchingDevice) ?? throw new NoDeviceFoundException($"Failed to find a simulator '{deviceName}'"); } } else { // The DeviceLoader.FindDevice will return the fist device of the type, but we want to make sure that // the device we use is of the correct arch, therefore, we will use the LoadDevices and handpick one await _deviceLoader.LoadDevices( log, includeLocked : false, forceRefresh : false, includeWirelessDevices : includeWirelessDevices, cancellationToken : cancellationToken); if (deviceName == null) { IHardwareDevice?hardwareDevice = target.Platform switch { TestTarget.Simulator_iOS32 => _deviceLoader.Connected32BitIOS.FirstOrDefault(), TestTarget.Device_iOS => _deviceLoader.Connected64BitIOS.FirstOrDefault(), TestTarget.Device_tvOS => _deviceLoader.ConnectedTV.FirstOrDefault(), _ => throw new ArgumentOutOfRangeException(nameof(target), $"Unrecognized device platform {target.Platform}") }; if (target.Platform.IsWatchOSTarget() && hardwareDevice != null) { companionDevice = await _deviceLoader.FindCompanionDevice(log, hardwareDevice, cancellationToken : cancellationToken); } device = hardwareDevice; } else { device = _deviceLoader.ConnectedDevices.FirstOrDefault(IsMatchingDevice) ?? throw new NoDeviceFoundException($"Failed to find a device '{deviceName}'. " + "Please make sure the device is connected and unlocked."); } } if (device == null) { throw new NoDeviceFoundException($"Failed to find a suitable device for target {target.AsString()}"); } return(new DevicePair(device, companionDevice)); }