/// <summary> /// Creates a new test case under the specified automation provider. /// </summary> /// <param name="testCase">Rhino.Api.Contracts.AutomationProvider.RhinoTestCase by which to create automation provider test case.</param> /// <returns>The ID of the newly created entity.</returns> public override string CreateTestCase(RhinoTestCase testCase) { // shortcuts var onProject = Configuration.ConnectorConfiguration.Project; testCase.Context[ContextEntry.Configuration] = Configuration; var testType = $"{testCase.GetCapability(AtlassianCapabilities.TestType, "Test")}"; // setup context testCase.Context["issuetype-id"] = $"{jiraClient.GetIssueTypeFields(idOrKey: testType, path: "id")}"; testCase.Context["project-key"] = onProject; testCase.Context["test-sets-custom-field"] = jiraClient.GetCustomField(schema: TestSetSchema); testCase.Context["manual-test-steps-custom-field"] = jiraClient.GetCustomField(schema: ManualTestStepSchema); testCase.Context["test-plan-custom-field"] = jiraClient.GetCustomField(schema: AssociatedPlanSchema); // setup request body var requestBody = testCase.ToJiraXrayIssue(); var issue = jiraClient.Create(requestBody); // comment var comment = Utilities.GetActionSignature(action: "created"); jiraClient.AddComment(idOrKey: $"{issue.SelectToken("key")}", comment); // success Logger?.InfoFormat($"Create-Test -Project [{onProject}] -Set [{string.Join(",", testCase?.TestSuites)}] = true"); // results return($"{issue}"); }
/// <summary> /// Creates an automation provider test run entity. Use this method to implement the automation /// provider test run creation and to modify the loaded Rhino.Api.Contracts.AutomationProvider.RhinoTestRun. /// </summary> /// <param name="testRun">Rhino.Api.Contracts.AutomationProvider.RhinoTestRun object to modify before creating.</param> /// <returns>Rhino.Api.Contracts.AutomationProvider.RhinoTestRun based on provided test cases.</returns> public override RhinoTestRun OnCreateTestRun(RhinoTestRun testRun) { // setup: request body var customField = jiraClient.GetCustomField(TestExecutionSchema); var testCases = JsonConvert.SerializeObject(testRun.TestCases.Select(i => i.Key)); // load JSON body var comment = Utilities.GetActionSignature("created"); var requestBody = Assembly.GetExecutingAssembly().ReadEmbeddedResource("create_test_execution_xray.txt") .Replace("[project-key]", Configuration.ConnectorConfiguration.Project) .Replace("[run-title]", TestRun.Title) .Replace("[custom-1]", customField) .Replace("[tests-repository]", testCases) .Replace("[type-name]", $"{capabilities[AtlassianCapabilities.ExecutionType]}") .Replace("[assignee]", Configuration.ConnectorConfiguration.UserName); var responseBody = jiraClient.Create(requestBody, comment); // setup testRun.Key = $"{responseBody["key"]}"; testRun.Link = $"{responseBody["self"]}"; testRun.Context["runtimeid"] = $"{responseBody["id"]}"; testRun.Context[ContextEntry.Configuration] = Configuration; // test steps handler foreach (var testCase in TestRun.TestCases) { testCase.SetRuntimeKeys(testRun.Key); } return(testRun); }
private static object GetUpdateBugPayload(RhinoTestCase testCase, JToken onBug, JiraClient jiraClient) { // setup var comment = $"{RhinoUtilities.GetActionSignature("updated")} " + $"Bug status on execution [{testCase.TestRunKey}] is *{onBug.SelectToken("fields.status.name")}*."; // verify if bug is already open var template = testCase.BugMarkdown(jiraClient); var description = $"{JToken.Parse(template).SelectToken("fields.description")}"; // setup return(new { Update = new { Comment = new[] { new { Add = new { Body = comment } } } }, Fields = new { Description = description } }); }
private IEnumerable <string> DoCloseBugs(RhinoTestCase testCase, string status, string resolution, IEnumerable <string> labels, IEnumerable <string> bugs) { // close bugs var closedBugs = new List <string>(); foreach (var bug in bugs) { var isClosed = testCase.CloseBug(bugIssueKey: bug, status, resolution, labels, client); // logs if (isClosed) { closedBugs.Add($"{Utilities.GetUrl(client.Authentication.Collection)}/browse/{bug}"); continue; } logger?.Info($"Close-Bug -Bug [{bug}] -Test [{testCase.Key}] = false"); } // context if (!testCase.Context.ContainsKey(ContextEntry.BugClosed) || !(testCase.Context[ContextEntry.BugClosed] is IEnumerable <string>)) { testCase.Context[ContextEntry.BugClosed] = new List <string>(); } var onBugsClosed = (testCase.Context[ContextEntry.BugClosed] as IEnumerable <string>).ToList(); onBugsClosed.AddRange(closedBugs); testCase.Context[ContextEntry.BugClosed] = onBugsClosed; // get return(onBugsClosed); }
private string DoCreateBug(RhinoTestCase testCase) { // get bug response var response = testCase.CreateBug(client); // results return(response == default ? "-1" : $"{Utilities.GetUrl(client.Authentication.Collection)}/browse/{response["key"]}"); }
/// <summary> /// Completes automation provider test run results, if any were missed or bypassed. /// </summary> /// <param name="testRun">Rhino.Api.Contracts.AutomationProvider.RhinoTestRun results object to complete by.</param> public override void CompleteTestRun(RhinoTestRun testRun) { // exit conditions if (Configuration.IsDryRun()) { return; } // setup: failed to update var inStatus = new[] { "TODO", "EXECUTING" }; // get all test keys to re-assign outcome var testResults = testRun .GetTests() .Where(i => inStatus.Contains($"{i["status"]}")) .Select(i => $"{i["key"]}"); // iterate: pass/fail foreach (var testCase in testRun.TestCases.Where(i => testResults.Contains(i.Key) && !i.Inconclusive)) { DoUpdateTestResult(testCase, inline: false); } // iterate: align all runs var dataTests = testRun.TestCases.Where(i => i.Iteration > 0).Select(i => i.Key).Distinct(); var options = new ParallelOptions { MaxDegreeOfParallelism = 1 }; Parallel.ForEach(dataTests, options, testCase => { var outcome = testRun.TestCases.Any(i => i.Key.Equals(testCase) && !i.Actual) ? "FAIL" : "PASS"; if (outcome == "FAIL") { testRun.TestCases.FirstOrDefault(i => !i.Actual && i.Key.Equals(testCase))?.SetOutcomeByRun(outcome); return; } testRun.TestCases.FirstOrDefault(i => i.Actual && i.Key.Equals(testCase))?.SetOutcomeByRun(outcome); }); // iterate: inconclusive foreach (var testCase in testRun.TestCases.Where(i => i.Inconclusive)) { DoUpdateTestResult(testCase, inline: true); } // test plan AttachToTestPlan(testRun); // close var comment = Utilities.GetActionSignature("closed"); jiraClient.CreateTransition(idOrKey: testRun.Key, transition: "Closed", resolution: "Done", comment); }
/// <summary> /// Creates a new test case under the specified automation provider. /// </summary> /// <param name="testCase">Rhino.Api.Contracts.AutomationProvider.RhinoTestCase by which to create automation provider test case.</param> /// <returns>The ID of the newly created entity.</returns> public override string CreateTestCase(RhinoTestCase testCase) { // constants: logging const string M = "Create-Test -Project [{0}] -Set [{1}] = true"; // create jira issue var issue = CreateTestOnJira(testCase); // apply to context testCase.Key = $"{issue["key"]}"; testCase.Context["jira-issue-id"] = issue == default ? string.Empty : $"{issue["id"]}"; // create test steps CreateTestSteps(testCase); // create & apply preconditions var precondition = CreatePrecondition(testCase.Key, testCase.DataSource); if (precondition != null) { xpandClient.AddPrecondition($"{precondition.SelectToken("id")}", testCase.Key); } // add to test sets var testSets = jiraClient .Get(idsOrKeys: testCase.TestSuites) .Select(i => (id: $"{i.SelectToken("id")}", key: $"{i.SelectToken("key")}")); Parallel.ForEach(testSets, options, testSet => xpandClient.AddTestsToSet(idAndKey: testSet, new[] { $"{issue.SelectToken("id")}" })); // comment var comment = Utilities.GetActionSignature(action: "created"); jiraClient.AddComment(idOrKey: issue["key"].ToString(), comment); // success Logger?.InfoFormat(M, Configuration.ConnectorConfiguration.Project, string.Join(", ", testCase?.TestSuites)); // results return($"{issue}"); }
/// <summary> /// Updates an existing bug (partial updates are supported, i.e. you can submit and update specific fields only). /// </summary> /// <param name="testCase">Rhino.Api.Contracts.AutomationProvider.RhinoTestCase by which to update automation provider bug.</param> public string OnUpdateBug(RhinoTestCase testCase, string status, string resolution) { // get existing bugs var isBugs = testCase.Context.ContainsKey("bugs") && testCase.Context["bugs"] != default; var bugs = isBugs ? (IEnumerable <string>)testCase.Context["bugs"] : Array.Empty <string>(); // exit conditions if (bugs.All(i => string.IsNullOrEmpty(i))) { return("-1"); } // possible duplicates if (bugs.Count() > 1) { var issues = client.Get(idsOrKeys: bugs).Where(i => testCase.IsBugMatch(bug: i, assertDataSource: true)); var onBugs = issues .OrderBy(i => $"{i["key"]}") .Skip(1) .Select(i => $"{i.SelectToken("key")}") .Where(i => !string.IsNullOrEmpty(i)); var labels = new[] { "Duplicate" }; DoCloseBugs(testCase, status, resolution: !string.IsNullOrEmpty(resolution) ? "Duplicate" : string.Empty, labels, bugs: onBugs); } // update bugs = client .Get(idsOrKeys: bugs) .Select(i => i.AsJObject()) .Where(i => testCase.IsBugMatch(bug: i, assertDataSource: false)) .Select(i => $"{i.SelectToken("key")}") .Where(i => !string.IsNullOrEmpty(i)); testCase.UpdateBug(idOrKey: bugs.FirstOrDefault(), client); // get return($"{Utilities.GetUrl(client.Authentication.Collection)}/browse/{bugs.FirstOrDefault()}"); }
/// <summary> /// Executes a routie of post bug creation. /// </summary> /// <param name="testCase">RhinoTestCase to execute routine on.</param> public override void PostCreateBug(RhinoTestCase testCase) { // exit conditions if (!testCase.Context.ContainsKey("lastBugKey")) { return; } // setup var format = $"{Utilities.GetActionSignature("{0}")} On execution [{testCase.TestRunKey}]"; var key = $"{testCase.Context["lastBugKey"]}"; var id = GetExecution(testCase); // put testCase.CreateInwardLink(jiraClient, key, linkType: "Blocks", string.Format(format, "created")); // post var command = RavenCommandsRepository.AddDefectToExecution(keyBug: key, idExecution: id); jiraExecutor.SendCommand(command); }
/// <summary> /// Creates a new instance of this Rhino.Api.Simulator.Framework.XrayAutomationProvider. /// </summary> /// <param name="configuration">Rhino.Api.Contracts.Configuration.RhinoConfiguration to use with this provider.</param> /// <param name="types">A collection of <see cref="Type"/> to load for this repository.</param> public XrayAutomationProvider(RhinoConfiguration configuration, IEnumerable <Type> types) : this(configuration, types, Utilities.CreateDefaultLogger(configuration)) { }
/// <summary> /// Creates a new instance of this Rhino.Api.Components.RhinoConnector. /// </summary> /// <param name="configuration">Rhino.Api.Contracts.Configuration.RhinoConfiguration to use with this connector.</param> /// <param name="types">A collection of <see cref="Type"/> to load for this repository.</param> public XrayCloudConnector(RhinoConfiguration configuration, IEnumerable <Type> types) : this(configuration, types, Utilities.CreateDefaultLogger(configuration)) { }