/// <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}");
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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
                }
            });
        }
예제 #4
0
        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);
        }
예제 #5
0
        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}");
        }
예제 #8
0
        /// <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))
 {
 }
예제 #11
0
 /// <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))
 {
 }