private static void CloneStripDeviceListForSingleDevice(Device device, string baseProjectPath, DirectoryInfo testRunDirectory) { //Get device group again as a separate instance as we will remove other devices // and serialize our JSON Device configuration that will be used by each test run ParameterRetriever retriever = new ParameterRetriever(); PerfectoTestParams testParams = retriever.GetVSOExecParam(baseProjectPath, true); //drop other devices testParams.Devices.RemoveAll(d => d.DeviceDetails.DeviceID != device.DeviceDetails.DeviceID); //Add our run identifier to the device details testParams.Devices.FirstOrDefault(d => d.DeviceDetails.DeviceID == device.DeviceDetails.DeviceID).DeviceDetails.RunIdentifier = RunIdentifier; //Now save to disk JsonSerializer serializer = new JsonSerializer(); Console.WriteLine("Writing config file for " + device.DeviceDetails.Name ?? device.DeviceDetails.DeviceID); var runConfigPath = testRunDirectory.FullName + "\\TestResources\\DevicesGroup\\" + SharedConstants.DeviceConfigFileName; Directory.CreateDirectory(Path.GetDirectoryName(runConfigPath)); using (StreamWriter fileStream = new StreamWriter(runConfigPath, false)) using (JsonWriter writer = new JsonTextWriter(fileStream)) { serializer.Serialize(writer, testParams); } }
public static void beforeFeature() { TestRunLocation = TestContext.CurrentContext.TestDirectory; BaseProjectPath = Path.GetFullPath(Path.Combine(TestRunLocation, @"..\..\..\")); SensitiveInformation.GetHostAndCredentials(BaseProjectPath, out PerfectoHost, out PerfectoUser, out PerfectoPass); ParameterRetriever testParams = new ParameterRetriever(); PerfectoTestingParameters = testParams.GetVSOExecParam(BaseProjectPath, false); CurrentDevice = PerfectoTestingParameters.Devices.FirstOrDefault(); if (string.IsNullOrEmpty(CurrentDevice.DeviceDetails.RunIdentifier)) { CurrentDevice.DeviceDetails.RunIdentifier = string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now); } CheckForValidDeviceConfiguration(); var browserName = "mobileOS"; if (CurrentDevice.DeviceDetails.IsDesktopBrowser) { browserName = CurrentDevice.DeviceDetails.BrowserName; } DesiredCapabilities capabilities = new DesiredCapabilities(browserName, string.Empty, new Platform(PlatformType.Any)); capabilities.SetCapability("user", PerfectoUser); capabilities.SetCapability("password", PerfectoPass); capabilities.SetCapability("newCommandTimeout", "120"); capabilities.SetCapability("scriptName", "Parallel-SpecFlow-Web"); CheckForValidConfiguration(); var url = new Uri(string.Format("http://{0}/nexperience/perfectomobile/wd/hub", PerfectoHost)); if (CurrentDevice.DeviceDetails.IsDesktopBrowser) { capabilities.SetCapability("platformName", CurrentDevice.DeviceDetails.OS); capabilities.SetCapability("platformVersion", CurrentDevice.DeviceDetails.OSVersion); capabilities.SetCapability("browserName", CurrentDevice.DeviceDetails.BrowserName); capabilities.SetCapability("resolution", "1366x768"); capabilities.SetCapability("version", CurrentDevice.DeviceDetails.BrowserVersion); } else { capabilities.SetCapability("deviceName", CurrentDevice.DeviceDetails.DeviceID); //capabilities.SetCapability("windTunnelPersona", "Georgia"); } driver = new RemoteWebDriverExtended(url, capabilities, new TimeSpan(0, 2, 0)); driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(15)); reportingClient = CreateReportingClient(); }
private static void RunParallelExecutions(PerfectoTestParams testParams) { //Execute in parallel for each device Parallel.ForEach(testParams.Devices, device => { Console.WriteLine("Starting runner for " + device.DeviceDetails.Name); StartTestRunner(device); }); //Don't want to exit the program until all devices have processed and then we can release mutex do { Thread.Sleep(15000); Console.WriteLine(" --> Processing ... NUnit Runner count is: {0}", ParallelProcessObserver.GetStillRunningProcessCount()); }while (getParallelCount() > 0); }
public static void beforeFeature() { TestRunLocation = TestContext.CurrentContext.TestDirectory; BaseProjectPath = Path.GetFullPath(Path.Combine(TestRunLocation, @"..\..\..\")); SensitiveInformation.GetHostAndCredentials(BaseProjectPath, out PerfectoHost, out PerfectoUser, out PerfectoPass); ParameterRetriever testParams = new ParameterRetriever(); PerfectoTestingParameters = testParams.GetVSOExecParam(BaseProjectPath, false); CurrentDevice = PerfectoTestingParameters.Devices.FirstOrDefault(); if (string.IsNullOrEmpty(CurrentDevice.DeviceDetails.RunIdentifier)) { CurrentDevice.DeviceDetails.RunIdentifier = string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now); } CheckForValidDeviceConfiguration(); DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.SetCapability("user", PerfectoUser); capabilities.SetCapability("password", PerfectoPass); capabilities.SetCapability("platformName", CurrentDevice.DeviceDetails.OS); capabilities.SetCapability("deviceName", CurrentDevice.DeviceDetails.DeviceID); capabilities.SetCapability("windTunnelPersona", "Georgia"); capabilities.SetCapability("scriptName", "Parallel-SpecFlow-Native"); var url = new Uri(string.Format("http://{0}/nexperience/perfectomobile/wd/hub", PerfectoHost)); if (capabilities.GetCapability("platformName").Equals("Android")) { driver = new AndroidDriver <IWebElement>(url, capabilities); } else { driver = new IOSDriver <IWebElement>(url, capabilities); } driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(15)); reportingClient = CreateReportingClient(); }
/// <summary> /// To be called from concrete test fixtures to initialize the test run. /// </summary> protected static AppiumDriver <IWebElement> InitializeDriver() { try { Trace.Listeners.Add(new TextWriterTraceListener("AppiumTestCaseExecution.log", "appiumTestCaseListener")); ExecutionErrors = new List <ExecutionError>(); BaseProjectPath = Path.GetFullPath(Path.Combine(TestRunLocation, @"..\..\..\")); SensitiveInformation.GetHostAndCredentials(BaseProjectPath, out Host, out Username, out Password); ParameterRetriever testParams = new ParameterRetriever(); PerfectoTestingParameters = testParams.GetVSOExecParam(BaseProjectPath, false); CurrentDevice = PerfectoTestingParameters.Devices.FirstOrDefault(); if (string.IsNullOrEmpty(CurrentDevice.DeviceDetails.RunIdentifier)) { CurrentDevice.DeviceDetails.RunIdentifier = string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now); } CheckForValidDeviceConfiguration(); Trace.Listeners.Add(new ConsoleTraceListener()); Trace.AutoFlush = true; var runMessage = string.Format("Starting test runs for {0} with RunId of {1}", CurrentDevice.DeviceDetails.Name, CurrentDevice.DeviceDetails.RunIdentifier); Trace.WriteLine(runMessage); DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.SetCapability("automationName", "Appium"); capabilities.SetCapability("user", Username); capabilities.SetCapability("password", Password); capabilities.SetCapability("newCommandTimeout", "120"); capabilities.SetPerfectoLabExecutionId(Host); capabilities.SetCapability("deviceName", CurrentDevice.DeviceDetails.DeviceID); capabilities.SetCapability("scriptName", "Parallel-" + TestCaseName); if (AppSettingsRetriever.IsWindTunnelEnabled()) { capabilities.SetCapability("windTunnelPersona", "Georgia"); } var url = new Uri(string.Format("http://{0}/nexperience/perfectomobile/wd/hub", Host)); if (CurrentDevice.DeviceDetails.OS.ToUpperInvariant() == "IOS") { DriverInstance = new IOSDriver <IWebElement>(url, capabilities, new TimeSpan(0, 2, 0)); } else if (CurrentDevice.DeviceDetails.OS.ToUpperInvariant() == "ANDROID") { DriverInstance = new AndroidDriver <IWebElement>(url, capabilities, new TimeSpan(0, 2, 0)); } else { throw new ArgumentException("Unknown Device OS from config file: " + CurrentDevice.DeviceDetails.OS); } startedVitals.Add("outputs.monitors.cpu.total"); startedVitals.Add("outputs.monitors.memory.used"); StartVitals(1, startedVitals); DriverInstance.Context = "NATIVE_APP"; CloseApp(); OpenApp(); DriverInstance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(15)); return(DriverInstance); } catch (Exception ex) { var message = string.Format("Failed to aqcuire new driver instance for {0} with message {1} and stacktrace {2}", CurrentDevice, ex.Message, ex.StackTrace); Console.WriteLine(message); throw new Exception(message, ex); } }
/// <summary> /// To be called from concrete test fixtures to initialize the test run. /// </summary> protected static RemoteWebDriverExtended InitializeDriver() { string model = "Unknown device model"; try { Trace.Listeners.Add(new TextWriterTraceListener("webTestCaseExecution.log", "webTestCaseListener")); ExecutionErrors = new List <ExecutionError>(); BaseProjectPath = Path.GetFullPath(Path.Combine(TestRunLocation, @"..\..\..\")); SensitiveInformation.GetHostAndCredentials(BaseProjectPath, out Host, out Username, out Password); ParameterRetriever testParams = new ParameterRetriever(); PerfectoTestingParameters = testParams.GetVSOExecParam(BaseProjectPath, false); CurrentDevice = PerfectoTestingParameters.Devices.FirstOrDefault(); if (string.IsNullOrEmpty(CurrentDevice.DeviceDetails.RunIdentifier)) { CurrentDevice.DeviceDetails.RunIdentifier = string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now); } CheckForValidConfiguration(); model = CurrentDevice.DeviceDetails.Name ?? "Unknown device Model"; Trace.Listeners.Add(new ConsoleTraceListener()); Trace.AutoFlush = true; var browserName = "mobileOS"; if (CurrentDevice.DeviceDetails.IsDesktopBrowser) { browserName = CurrentDevice.DeviceDetails.BrowserName; } DesiredCapabilities capabilities = new DesiredCapabilities(browserName, string.Empty, new Platform(PlatformType.Any)); capabilities.SetCapability("user", Username); capabilities.SetCapability("password", Password); capabilities.SetCapability("newCommandTimeout", "120"); capabilities.SetPerfectoLabExecutionId(Host); capabilities.SetCapability("scriptName", "Parallel-" + TestCaseName); if (CurrentDevice.DeviceDetails.IsDesktopBrowser) { capabilities.SetCapability("platformName", CurrentDevice.DeviceDetails.OS); capabilities.SetCapability("platformVersion", CurrentDevice.DeviceDetails.OSVersion); capabilities.SetCapability("browserName", CurrentDevice.DeviceDetails.BrowserName); capabilities.SetCapability("resolution", "1366x768"); capabilities.SetCapability("version", CurrentDevice.DeviceDetails.BrowserVersion); } else { capabilities.SetCapability("deviceName", CurrentDevice.DeviceDetails.DeviceID); //WindTunnel only for devices and only when available if (AppSettingsRetriever.IsWindTunnelEnabled()) { capabilities.SetCapability("windTunnelPersona", "Georgia"); } } var url = new Uri(string.Format("https://{0}/nexperience/perfectomobile/wd/hub", Host)); RemoteWebDriverExtended driver = new RemoteWebDriverExtended(url, capabilities, new TimeSpan(0, 2, 0)); driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(15)); DriverInstance = driver; startedVitals.Add("outputs.monitors.cpu.total"); startedVitals.Add("outputs.monitors.memory.used"); StartVitals(1, startedVitals); return(driver); } catch (Exception e) { HandleGeneralException(e, DriverInstance); } return(null); }
public static void Main(string[] args) { try { //Allows us to group device runs for logging purposes RunIdentifier = string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now); ParallelProcessObserver = new ProcessObserver(); Trace.Listeners.Add(new TextWriterTraceListener("ParallelDeviceOutput.log", "myListener")); //Get the devices to run for string currentPath = Directory.GetCurrentDirectory(); string baseProjectPath = Path.GetFullPath(Path.Combine(currentPath, @"..\..\..\")); ParameterRetriever retriever = new ParameterRetriever(); PerfectoTestParams testParams = retriever.GetVSOExecParam(baseProjectPath, true); if (testParams.Devices.Count < 0) { Console.WriteLine("No devices found from JSON config file."); #if DEBUG Console.ReadKey(); #endif return; } //Now create a mutex so that this console app can only be run 1 at a time. // get application GUID as defined in AssemblyInfo.cs string appGuid = "PerfectoParallelRunner-82678dc5439649959b6e0b686efb1222"; // unique id for global mutex - Global prefix means it is global to the machine string mutexId = string.Format("Global\\{{{0}}}", appGuid); // Need a place to store a return value in Mutex() constructor call bool createdNew; var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow); var securitySettings = new MutexSecurity(); securitySettings.AddAccessRule(allowEveryoneRule); using (var mutex = new Mutex(false, mutexId, out createdNew, securitySettings)) { var hasHandle = false; try { try { hasHandle = mutex.WaitOne(5000, false); if (hasHandle == false) { throw new TimeoutException("Make sure another Test Process isn't already running."); } } catch (AbandonedMutexException) { // Log the fact that the mutex was abandoned in another process, it will still get acquired hasHandle = true; } // Perform your work here. RunParallelExecutions(testParams); } finally { if (hasHandle) { mutex.ReleaseMutex(); } } } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); #if DEBUG Console.ReadKey(); #endif throw; } }
public static void Main(string[] args) { try { //Allows us to group device runs for logging purposes RunIdentifier = string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now); ParallelProcessObserver = new ProcessObserver(); Trace.Listeners.Add(new TextWriterTraceListener("ParallelDeviceOutput.log", "myListener")); /*Args Note: * Having difficulty sending in separated args from Powershell * when there are spaces in the arguments, they split up the where statment. * Need to do some special handling to get around this. Using an "^" to split incoming args * * Expecting possiblity of: a:TheTestAssembly.dll^w:category==xyz AND category==123 */ var joinedArgs = string.Join(" ", args); Console.WriteLine("arguments are: " + joinedArgs); var argsSplit = string.IsNullOrWhiteSpace(joinedArgs) ? null : joinedArgs.Split('^'); string assemblyArgs = ""; string whereFilter = ""; if (argsSplit != null && argsSplit.Length > 0) { foreach (string arg in argsSplit) { Console.WriteLine("Reading Arg:" + arg); if (arg.StartsWith("a:")) { assemblyArgs = arg.Substring(2); } if (arg.StartsWith("w:")) { whereFilter = arg.Substring(2); } } } else { Console.WriteLine("No assembly passed in so using VSTSDigitalDemoTests.dll"); assemblyArgs = "VSTSDigitalDemoTests.dll"; } //Get the devices to run for string currentPath = Directory.GetCurrentDirectory(); string baseProjectPath = Path.GetFullPath(Path.Combine(currentPath, @"..\..\..\")); ParameterRetriever retriever = new ParameterRetriever(); PerfectoTestParams testParams = retriever.GetVSOExecParam(baseProjectPath, true); if (testParams.Devices.Count < 0) { Console.WriteLine("No devices found from JSON config file."); #if DEBUG Console.ReadKey(); #endif return; } //Now create a mutex so that this console app can only be run 1 at a time. // get application GUID as defined in AssemblyInfo.cs string appGuid = "PerfectoParallelRunner-82678dc5439649959b6e0b686efb1222"; // unique id for global mutex - Global prefix means it is global to the machine string mutexId = string.Format("Global\\{{{0}}}", appGuid); // Need a place to store a return value in Mutex() constructor call bool createdNew; var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow); var securitySettings = new MutexSecurity(); securitySettings.AddAccessRule(allowEveryoneRule); using (var mutex = new Mutex(false, mutexId, out createdNew, securitySettings)) { var hasHandle = false; try { try { hasHandle = mutex.WaitOne(5000, false); if (hasHandle == false) { throw new TimeoutException("Make sure another Test Process isn't already running."); } } catch (AbandonedMutexException) { // Log the fact that the mutex was abandoned in another process, it will still get acquired hasHandle = true; } // Perform your work here. RunParallelExecutions(assemblyArgs, whereFilter, testParams); } finally { if (hasHandle) { mutex.ReleaseMutex(); } } } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); #if DEBUG Console.ReadKey(); #endif throw; } }