public async Task Setup() { if (TestConfig.IsReportingEnabled) { await ReportManager.CreateTestAsync().ConfigureAwait(false); } CurrentTenant = TenantTitle.upload1; CurrentUser = TestConfig.AdminUser; await BackgroundTaskApi.DeleteAllTasksAsync(TestConfig.AdminUser).ConfigureAwait(false); AppApi.DeleteApps(true, new[] { AppTitle.Haribo, AppTitle.ComposerHq1, AppTitle.ComposerHq2, AppTitle.SapPorsche, AppTitle.Player }, TenantTitle.upload1); AppApi.DeleteApps(true, new[] { AppTitle.Haribo, AppTitle.ComposerHq1, AppTitle.ComposerHq2 }, TenantTitle.upload2); // page ready without "upload spinner" element check IsUseAllPageReadyChecks = false; }
/// <summary> /// Finalizes execution of every test. Use this method in TearDown section of /// every TestFixture /// </summary> protected async Task TestEnd() { var deleteAllTasksTask = BackgroundTaskApi.DeleteAllTasksAsync(CurrentUser); if (TestConfig.IsReportingEnabled) { ReportManager.GenerateTestResultRecord(); } CloseSecondaryBrowser(); if (IsEachTestInNewBrowser) { ClosePrimaryBrowser(); IsUserLoggedIn = false; await deleteAllTasksTask.ConfigureAwait(false); return; } var browserTabs = GetTabHandles(); if (browserTabs == null || browserTabs.Count <= 1) { await deleteAllTasksTask.ConfigureAwait(false); return; } foreach (var browserTab in browserTabs.Skip(1)) { CloseTab(browserTab); } await deleteAllTasksTask.ConfigureAwait(false); }
/// <summary> /// Imports tenant ZIP archive to current tenant (see <see /// cref="ActionManager.CurrentTenant"/>). The ZIP file will be taken by path in /// <see cref="TestConfig.BrowserDownloadFolder"/>. /// </summary> /// <param name="fileName">Exported tenant archive file name without path (like /// tenantCode_[timestamp].zip)</param> public static void ImportTenant(string fileName) { var tenantFilePath = string.Empty; var token = BackgroundTaskApi.GetPackageSas(); try { var blob = new CloudAppendBlob(new Uri(token)); tenantFilePath = Path.Combine(TestConfig.BrowserDownloadFolder, fileName); blob.UploadFromFile(tenantFilePath); blob.SetProperties(); } catch (Exception e) { throw new FileLoadException( $"Tenant API: Error uploading file {tenantFilePath} to cloud: {e.Message}"); } var task = BackgroundTaskApi.NewBackgroundTask(TaskActionType.ImportTenant, fileName, new FileInfo(tenantFilePath).Length, token); if (task == null || string.IsNullOrEmpty(task.TaskId)) { throw new Exception( $"Could not start new background task for tenant archive '{fileName}' import"); } var body = new AppImport { PackageSas = token, TaskId = task.TaskId }; BackgroundTaskApi.ProcessedObjects.AddOrUpdate(task.TaskId, (null, null, new ManualResetEvent(false)), (k, v) => (null, null, new ManualResetEvent(false))); Trace.TraceInformation($"Tenant API: Import task {task.TaskId} started"); RestController.HttpRequestJson(UriCxm.BackgroundTaskExecution, Method.POST, body); if (BackgroundTaskApi.ProcessedObjects.TryGetValue(task.TaskId, out var tenantObj) && tenantObj.Item3.WaitOne(TimeSpan.FromSeconds(TestConfig.TenantImportTimeout))) { Trace.TraceInformation($"Tenant API: Import task {task.TaskId} complete"); } else { Trace.TraceError($"Tenant API: {task.TaskId} import timed out!"); BackgroundTaskApi.DeleteTaskId(task.TaskId); throw new TimeoutException( $"Tenant API: Import to tenant {ActionManager.CurrentTenantCode} timed out after " + $"{TestConfig.TenantImportTimeout} s. File {fileName}."); } BackgroundTaskApi.ProcessedObjects.TryRemove(task.TaskId, out _); BackgroundTaskApi.DeleteTaskId(task.TaskId); }
public async Task Setup() { if (TestConfig.IsReportingEnabled) { await ReportManager.CreateTestAsync().ConfigureAwait(false); } CurrentTenant = TenantTitle.media1; CurrentUser = TestConfig.AdminUser; await BackgroundTaskApi.DeleteAllTasksAsync(TestConfig.AdminUser).ConfigureAwait(false); }
/// <summary> /// Exports all entities from current tenant (see <see cref="ActionManager.CurrentTenant"/>) /// </summary> /// <returns>(<see cref="string"/>) Exported ZIP file name that is saved in <see cref= /// "TestConfig.BrowserDownloadFolder"/> folder</returns> public static string ExportTenant() { var response = RestController.HttpRequestJson(UriCxm.TenantsExport, Method.GET); var objList = JsonConvert.DeserializeObject <EntitiesListInfo>(response.Content); var entitiesIdList = new EntitiesListId(); entitiesIdList.Apps.AddRange(objList.Apps.Select(x => x.Id)); entitiesIdList.Items.AddRange(objList.Items.Select(x => x.Id)); entitiesIdList.Places.AddRange(objList.Places.Select(x => x.Id)); //entitiesIdList.SourceId = "xxx"; response = RestController.HttpRequestJson(UriCxm.TenantsExport, Method.POST, entitiesIdList); var task = JsonConvert.DeserializeObject <BackgroundTask>(response.Content); if (task == null || string.IsNullOrEmpty(task.TaskId)) { throw new Exception( $"Could not start new background task for tenant '{ActionManager.CurrentTenant}' export"); } BackgroundTaskApi.ProcessedObjects.AddOrUpdate(task.TaskId, (null, null, new ManualResetEvent(false)), (k, v) => (null, null, new ManualResetEvent(false))); Trace.TraceInformation($"Tenant API: Export task {task.TaskId} started"); string sas, fileName; if (BackgroundTaskApi.ProcessedObjects.TryGetValue(task.TaskId, out var tenantObj) && tenantObj.Item3.WaitOne(TimeSpan.FromSeconds(TestConfig.TenantExportTimeout))) { var obj = tenantObj.Item1 as BackgroundTask; sas = obj?.FileSas; fileName = obj?.FileName; Trace.TraceInformation($"Tenant API: Export task {task.TaskId} complete"); } else { Trace.TraceError($"Tenant API: {task.TaskId} export timed out!"); BackgroundTaskApi.DeleteTaskId(task.TaskId); throw new TimeoutException( $"Tenant API: Export from tenant {ActionManager.CurrentTenantCode} timed out after " + $"{TestConfig.TenantExportTimeout} s."); } FileManager.Download(sas, fileName); BackgroundTaskApi.ProcessedObjects.TryRemove(task.TaskId, out _); BackgroundTaskApi.DeleteTaskId(task.TaskId); return(fileName); }
/// <summary> /// Method to be automatically called by SignalR event with the same name. Processes own /// parameters objects and (depending on task status) sets specific variables up in order /// to manage background tasks. /// </summary> /// <param name="task"><see cref="BackgroundTask"/> object as json</param> /// <param name="result">Imported/exported object as json or server error message</param> private static void TaskProgressChanged(string task, string result) { var task1 = JsonConvert.DeserializeObject <BackgroundTask>(task); if (BackgroundTaskApi.ProcessedObjects == null || !BackgroundTaskApi.ProcessedObjects.ContainsKey(task1.TaskId)) { return; } Trace.TraceInformation( $@"SignalR client: Task {task1.TaskId}, file '{task1.FileName}' progress {task1.Progress}%"); if (task1.Status < (int)TaskStatus.Completed) { return; } if (task1.Status == (int)TaskStatus.Failed || task1.Status == (int)TaskStatus.Canceled) { BackgroundTaskApi.AddOrUpdateTask(task1, null, result); return; } // if we're here, import/export has completed without errors => process the result object taskObject = null; switch ((TaskActionType)task1.ActionType) { case TaskActionType.UploadApp: taskObject = JsonConvert.DeserializeObject <AppWrapper>(result).Data; break; case TaskActionType.ExportTenant: taskObject = JsonConvert.DeserializeObject <BackgroundTaskWrapper>(result).Data; break; case TaskActionType.ImportTenant: // taskObject is not used (null) for this task type break; default: throw new AggregateException( $@"Wrong or unknown background task type '{task1.ActionType}' detected"); } BackgroundTaskApi.AddOrUpdateTask(task1, taskObject, null); }
/// <summary> /// Deletes apps (or all of specified type(s)) within all or specified tenant /// </summary> /// <param name="deleteCompletely">Optional. If true, delete app(s) of the type(s) specified. /// If false, mark the app(s) version(s) as deleted.</param> /// <param name="appTypes">App types array (optional, use null to delete all app types) /// </param> /// <param name="tenantTitle">Tenant title (optional)</param> public static void DeleteApps(bool deleteCompletely = true, string[] appTypes = null, TenantTitle tenantTitle = TenantTitle.All) { var tenantList = tenantTitle == TenantTitle.All ? ActionManager.Tenants.ToArray() : ActionManager.Tenants .Where(x => x.Title == tenantTitle.ToString()) .ToArray(); if (appTypes == null || appTypes.Length == 0) { appTypes = new [] { AppTitle.Any }; } BackgroundTaskApi.DeleteAllTasksAsync(TestConfig.AdminUser) .ConfigureAwait(false) .GetAwaiter() .GetResult(); foreach (var tenant in tenantList) { var response = RestController.HttpRequestJson( UriCxm.Apps, Method.GET, tenantCode: tenant.Code, user: TestConfig.AdminUser); var apps = JsonConvert.DeserializeObject <AppResponse[]>(response.Content); foreach (var app in apps) { if (appTypes.All(x => x.ToString() != AppTitle.Any) && appTypes.All(x => x.ToString() != app.ActualAppVersion.Title) && appTypes.All(x => x.ToString() != app.Key) && !app.ActualAppVersion.Title.Contains("Auto")) { continue; } var app1 = GetById(app.AppId, tenant.Code, TestConfig.AdminUser); if (app1.Places != null && app1.Places.Count > 0) { foreach (var place in app1.Places) { try { var p = PlaceApi.GetById(place.Id, tenant.Code); p.Schedule.ScheduleApps.ForEach(x => x.DoDelete = true); PlaceApi.SavePlace(p); } catch { // ignored } } app1 = GetById(app.AppId, tenant.Code, TestConfig.AdminUser); } foreach (var version in app1.Versions) { RestController.HttpRequestJson( new Uri( string.Format( UriCxm.AppsDelete, version.Id, DateTime.MaxValue.ToString("yyyy-MM-ddTHH:mm:ss"), deleteCompletely.ToString().ToLower()), UriKind.Relative) .ToString(), Method.DELETE, tenantCode: tenant.Code, user: TestConfig.AdminUser); } } } }
/// <summary> /// Imports app from file by app version in file name /// </summary> /// <param name="path">Full path to file</param> /// <param name="mask">File name mask (like name*.zip) or file name without path</param> /// <param name="version">App version</param> /// <returns>(<see cref="AppResponse"/>) App object</returns> public static AppResponse ImportApp(string path, string mask, string version) { var appFilePath = string.Empty; var token = BackgroundTaskApi.GetPackageSas(); try { var blob = new CloudAppendBlob(new Uri(token)); appFilePath = FileManager.GetFileByVersion(path, mask, version); blob.UploadFromFile(appFilePath); blob.SetProperties(); } catch (Exception e) { throw new FileLoadException( $"App API: Error uploading file {appFilePath} to cloud: {e.Message}"); } var fileName = Path.GetFileName(appFilePath); var task = BackgroundTaskApi.NewBackgroundTask(TaskActionType.UploadApp, fileName, new FileInfo(appFilePath).Length, token); if (task == null || string.IsNullOrEmpty(task.TaskId)) { throw new Exception($"Could not start new background task for app '{fileName}' import"); } var body = new AppImport { PackageSas = token, TaskId = task.TaskId }; BackgroundTaskApi.ProcessedObjects.AddOrUpdate(task.TaskId, (null, null, new ManualResetEvent(false)), (k, v) => (null, null, new ManualResetEvent(false))); Trace.TraceInformation($"App API: Import task {task.TaskId} started"); RestController.HttpRequestJson(UriCxm.BackgroundTaskExecution, Method.POST, body); if (BackgroundTaskApi.ProcessedObjects.TryGetValue(task.TaskId, out var appObj) && appObj.Item3.WaitOne(TimeSpan.FromSeconds(TestConfig.AppImportTimeout))) { Trace.TraceInformation($"App API: Import task {task.TaskId} complete"); } else { Trace.TraceError($"App API: {task.TaskId} timed out!"); throw new TimeoutException( $"App API: Import on tenant {ActionManager.CurrentTenantCode} timed out after " + $"{TestConfig.AppImportTimeout} s. File {fileName}."); } var result = BackgroundTaskApi.ProcessedObjects.TryGetValue(task.TaskId, out appObj) ? appObj.Item1 as AppResponse : null; BackgroundTaskApi.ProcessedObjects.TryRemove(task.TaskId, out _); return(result); }