diff --git a/src/main/frontend/pipeline-console-view/pipeline-console/main/hooks/use-steps-poller.ts b/src/main/frontend/pipeline-console-view/pipeline-console/main/hooks/use-steps-poller.ts index b39bb2de8..917d76d22 100644 --- a/src/main/frontend/pipeline-console-view/pipeline-console/main/hooks/use-steps-poller.ts +++ b/src/main/frontend/pipeline-console-view/pipeline-console/main/hooks/use-steps-poller.ts @@ -108,8 +108,13 @@ export function useStepsPoller(props: RunPollerProps) { case Result.unstable: case Result.failure: case Result.aborted: - if (selectedStepResult && stepResult < selectedStepResult) { - // Return first unstable/failed/aborted step which has a state worse than the selectedStep. + if ( + run?.complete && + selectedStepResult && + stepResult < selectedStepResult + ) { + // If the run is complete return first unstable/failed/aborted step which has a state worse + // than the selectedStep. // E.g. if the first step state is failure we want to return that over a later unstable step. return step; } diff --git a/src/test/java/io/jenkins/plugins/pipelinegraphview/PipelineGraphViewTest.java b/src/test/java/io/jenkins/plugins/pipelinegraphview/PipelineGraphViewTest.java index b13bfcd26..dacefc5d8 100644 --- a/src/test/java/io/jenkins/plugins/pipelinegraphview/PipelineGraphViewTest.java +++ b/src/test/java/io/jenkins/plugins/pipelinegraphview/PipelineGraphViewTest.java @@ -3,22 +3,21 @@ import com.microsoft.playwright.Page; import com.microsoft.playwright.junit.UsePlaywright; import hudson.model.Result; -import io.jenkins.plugins.pipelinegraphview.playwright.ManageAppearancePage; +import io.jenkins.plugins.casc.misc.ConfiguredWithCode; +import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; +import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; import io.jenkins.plugins.pipelinegraphview.playwright.PipelineJobPage; import io.jenkins.plugins.pipelinegraphview.playwright.PlaywrightConfig; import io.jenkins.plugins.pipelinegraphview.utils.PipelineState; import io.jenkins.plugins.pipelinegraphview.utils.TestUtils; -import java.util.concurrent.CompletableFuture; -import java.util.function.Supplier; import org.jenkinsci.plugins.workflow.job.WorkflowRun; +import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep; import org.junit.jupiter.api.Test; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.junit.jupiter.WithJenkins; +import org.jvnet.hudson.test.Issue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.util.function.ThrowingSupplier; -@WithJenkins +@WithJenkinsConfiguredWithCode @UsePlaywright(PlaywrightConfig.class) class PipelineGraphViewTest { private static final Logger log = LoggerFactory.getLogger(PipelineGraphViewTest.class); @@ -28,10 +27,10 @@ class PipelineGraphViewTest { // http://localhost:8080/jenkins @Test - void smokeTest(Page p, JenkinsRule j) { + @ConfiguredWithCode("configure-appearance.yml") + void smokeTest(Page p, JenkinsConfiguredWithCodeRule j) throws Exception { String name = "Integration Tests"; - WorkflowRun run = setupJenkins(p, j.jenkins.getRootUrl(), (ThrowingSupplier) - () -> TestUtils.createAndRunJob(j, name, "smokeTest.jenkinsfile", Result.FAILURE)); + WorkflowRun run = TestUtils.createAndRunJob(j, name, "smokeTest.jenkinsfile", Result.FAILURE); new PipelineJobPage(p, run.getParent()) .goTo() @@ -62,21 +61,46 @@ void smokeTest(Page p, JenkinsRule j) { .stageIsVisibleInTree("B2"); } - private static WorkflowRun setupJenkins(Page p, String rootUrl, Supplier setupRun) { - CompletableFuture run = CompletableFuture.supplyAsync(setupRun); - CompletableFuture jenkinsSetup = CompletableFuture.runAsync(() -> { - log.info("Setting up Jenkins to have the Pipeline Graph View on all pages"); - new ManageAppearancePage(p, rootUrl) - .goTo() - .displayPipelineOnJobPage() - .displayPipelineOnBuildPage() - .setPipelineGraphAsConsoleProvider() - .save(); - log.info("Jenkins setup complete"); - }); + @Issue("GH#797") + @Test + @ConfiguredWithCode("configure-appearance.yml") + void runningStageSelected(Page p, JenkinsConfiguredWithCodeRule j) throws Exception { + String name = "gh797"; + WorkflowRun run = TestUtils.createAndRunJobNoWait(j, name, "gh797_errorAndContinueWithWait.jenkinsfile") + .waitForStart(); + SemaphoreStep.waitForStart("wait/1", run); - CompletableFuture.allOf(run, jenkinsSetup).join(); + new PipelineJobPage(p, run.getParent()) + .goTo() + .hasBuilds(1) + .nthBuild(0) + .goToBuild() + .goToPipelineOverview() + .hasStagesInGraph(2, "Caught1", "Runs1") + .stageIsVisibleInTree("Parallel1") + .stageIsVisibleInTree("Runs1") + .stageIsSelected("Runs1"); + + SemaphoreStep.success("wait/1", run); + j.assertBuildStatus(Result.SUCCESS, j.waitForCompletion(run)); + } - return run.join(); + @Test + @ConfiguredWithCode("configure-appearance.yml") + void failedStageSelected(Page p, JenkinsConfiguredWithCodeRule j) throws Exception { + String name = "Pipeline Success Error Caught"; + WorkflowRun run = TestUtils.createAndRunJob(j, name, "gh797_errorAndContinue.jenkinsfile", Result.SUCCESS); + + new PipelineJobPage(p, run.getParent()) + .goTo() + .hasBuilds(1) + .nthBuild(0) + .goToBuild() + .goToPipelineOverview() + .hasStagesInGraph(2, "Caught1", "Runs1") + .stageIsVisibleInTree("Parallel1") + .stageIsVisibleInTree("Caught1") + .stageIsVisibleInTree("Runs1") + .stageIsSelected("Caught1"); } } diff --git a/src/test/resources/io/jenkins/plugins/pipelinegraphview/utils/gh797_errorAndContinue.jenkinsfile b/src/test/resources/io/jenkins/plugins/pipelinegraphview/utils/gh797_errorAndContinue.jenkinsfile new file mode 100644 index 000000000..f5f6dd1a9 --- /dev/null +++ b/src/test/resources/io/jenkins/plugins/pipelinegraphview/utils/gh797_errorAndContinue.jenkinsfile @@ -0,0 +1,22 @@ +pipeline { + agent any + + stages { + stage('Parallel1') { + parallel { + stage('Caught1') { + steps { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + error 'Oops' + } + } + } + } + } + stage('Runs1') { + steps { + echo 'success' + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/io/jenkins/plugins/pipelinegraphview/utils/gh797_errorAndContinueWithWait.jenkinsfile b/src/test/resources/io/jenkins/plugins/pipelinegraphview/utils/gh797_errorAndContinueWithWait.jenkinsfile new file mode 100644 index 000000000..f72a81e3f --- /dev/null +++ b/src/test/resources/io/jenkins/plugins/pipelinegraphview/utils/gh797_errorAndContinueWithWait.jenkinsfile @@ -0,0 +1,22 @@ +pipeline { + agent any + + stages { + stage('Parallel1') { + parallel { + stage('Caught1') { + steps { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + error 'Oops' + } + } + } + } + } + stage('Runs1') { + steps { + semaphore 'wait' + } + } + } +} \ No newline at end of file