Jenkins 50825: Test for stage deletion from the editor, plus parallelPipeline simplifications (#1733)

* Deletes still WIP, but testEditorParallel is radically simplified.

* Add an id to renderBigLabel, so stages are targetable in tests by their names

* Stage delete test works. Step delete test not implemented yet.

* testEditorAddAndDeleteStage replaces testEditorAddStages, since it does a lot of the same stuff
This commit is contained in:
Karl Shultz 2018-05-15 09:27:15 +12:00 committed by Ivan Meredith
parent 7a4a8abbc2
commit b53606f2f9
3 changed files with 66 additions and 69 deletions

View File

@ -55,7 +55,25 @@ public class EditorPage {
wait.click(By.cssSelector(".editor-step-selector div[data-functionName=\"echo\"]"));
wait.sendKeys(By.cssSelector("input.TextInput-control"),"Echo step added by ATH");
wait.click(By.cssSelector("div.sheet.active a.back-from-sheet"));
logger.info("Stages added, ready to save");
logger.info("Stage " + newStageName + " added");
}
/**
* Deletes an entire stage of a pipeline.
*
* @param stageName the step we want to delete
*
*/
public void deleteStage(String stageName) {
logger.info("Deleting stage " + stageName);
// Click the name of the stage
wait.click(By.id("pipeline-big-label-" + stageName));
// Click the little popup button
wait.click(By.cssSelector("div.more-menu"));
// Click Delete
// TODO: Ongoing work to get rid of text-based selectors. This is one.
wait.click(By.xpath("//*[text()=\"Delete\"]"));
logger.info("Successfully deleted stage " + stageName);
}
/**
@ -119,7 +137,8 @@ public class EditorPage {
}
/**
* Creates a simple pipeline from scratch.
* Creates a simple pipeline from scratch, and saves it as the
* branch specified when called.
*
* @param newBranch the name of the new branch we'll save to. If null,
* we save to master.
@ -139,56 +158,28 @@ public class EditorPage {
/**
* Creates a parallel pipeline from scratch.
*
* @param newBranch the name of the new branch we'll save to. If null,
* we save to master.
* @param numberOfParallels number of parallel branches we want to create.
*/
public void parallelPipeline(String newBranch, int numberOfParallels) {
public void parallelPipeline(int numberOfParallels) {
logger.info("Editing a parallel pipeline");
/*
We'll create as many parallel stages as we were told to
via int numberOfParallels when we were called.
*/
for (int i = 1; i < numberOfParallels; i++) {
logger.info("Create stage Parallel-" + i);
/*
We're only creating one stage. So the "add" button will always have
the id pipeline-node-hittarget-2-add, because it is the second
column in the "grid," so to speak.
*/
// The "add" Button will always have the id pipeline-node-hittarget-2-add
// since it's the second column in the grid.
wait.click(By.id("pipeline-node-hittarget-2-add"));
wait.sendKeys(By.cssSelector("input.stage-name-edit"),("Parallel-" + i));
wait.click(By.cssSelector("button.btn-primary.add"));
wait.click(By.cssSelector(".editor-step-selector div[data-functionName=\"sh\"]"));
wait.sendKeys(By.cssSelector("textarea.editor-step-detail-script"),"netstat -a");
wait.sendKeys(By.cssSelector("textarea.editor-step-detail-script"),"whoami");
logger.info("Clicking on active sheet div.sheet.active a.back-from-sheet");
wait.click(By.cssSelector("div.sheet.active a.back-from-sheet"));
logger.info("Stage Parallel-" + i + " created");
}
/*
Now we need to name the "wrapper" stage to something other than what
got automatically put in.
*/
// Rename the "wrapper" stage to something non-default
wait.click(By.cssSelector("div.pipeline-big-label.top-level-parallel"));
wait.clear(By.cssSelector("input.stage-name-edit"));
wait.sendKeys(By.cssSelector("input.stage-name-edit"),"Top Level Parallel Wrapper Stage");
wait.click(By.cssSelector("button.btn-primary.inverse"));
wait.sendKeys(By.cssSelector("textarea[placeholder=\"What changed?\"]"),"Parallel pipeline");
if(!Strings.isNullOrEmpty(newBranch)) {
logger.info("Saving to branch " + newBranch);
wait.click(By.xpath("//*[text()='Commit to new branch']"));
wait.sendKeys(By.cssSelector("input[placeholder='my-new-branch']:enabled"),newBranch);
} else {
/*
This mimics the user changing picking a new branch, and then
changing their mind and committing to master after all.
*/
wait.click(By.xpath("//*[text()='Commit to new branch']"));
wait.sendKeys(By.cssSelector("input[placeholder='my-new-branch']:enabled"),"i-am-changing-my-mind");
wait.click(By.xpath("//*[text()='Commit to master']"));
logger.info("Using branch master");
}
wait.click(By.xpath("//*[text()=\"Save & run\"]"));
logger.info("Save & run clicked, Parallel pipeline saved");
logger.info("Parallel pipeline created and ready to save");
}
}

View File

@ -139,30 +139,6 @@ public class GithubEditorTest {
sseClient.untilEvents(pipeline.buildsFinished);
}
/**
* This test covers creation of a pipeline, and subsequently adds a
* stage within that same pipeline, then saves it to a new branch.
*/
@Test
public void testEditorAddStages() throws IOException {
String newBranchName = "made-by-testEditorAddStages";
String newStageName = "Stage made by ATH";
creationPage.createPipeline(token, organization, repo, true);
MultiBranchPipeline pipeline = mbpFactory.pipeline(repo);
editorPage.simplePipeline();
ActivityPage activityPage = pipeline.getActivityPage().checkUrl();
driver.navigate().refresh();
sseClient.untilEvents(pipeline.buildsFinished);
sseClient.clear();
BranchPage branchPage = activityPage.clickBranchTab();
branchPage.openEditor("master");
editorPage.addStageToPipeline(pipeline, newStageName);
editorPage.saveBranch(newBranchName);
activityPage.checkUrl();
activityPage.getRunRowForBranch(newBranchName);
sseClient.untilEvents(pipeline.buildsFinished);
}
/**
* This test covers creation of a pipeline, and changes agent settings within it.
*/
@ -184,6 +160,39 @@ public class GithubEditorTest {
sseClient.untilEvents(pipeline.buildsFinished);
}
/**
* This test covers creation of a pipeline, and subsequently adds a
* stage within that same pipeline, then saves it to a new branch.
*/
@Test
public void testEditorAddAndDeleteStage() throws IOException {
String firstBranchName = "branch-before-delete";
String secondBranchName = "branch-after-delete";
String stageToDelete = "stage to be deleted";
creationPage.createPipeline(token, organization, repo, true);
MultiBranchPipeline pipeline = mbpFactory.pipeline(repo);
editorPage.simplePipeline();
ActivityPage activityPage = pipeline.getActivityPage().checkUrl();
sseClient.untilEvents(pipeline.buildsFinished);
sseClient.clear();
BranchPage branchPage = activityPage.clickBranchTab();
branchPage.openEditor("master");
editorPage.addStageToPipeline(pipeline, stageToDelete);
editorPage.saveBranch(firstBranchName);
activityPage.checkUrl();
activityPage.getRunRowForBranch(firstBranchName);
sseClient.untilEvents(pipeline.buildsFinished);
sseClient.clear();
branchPage.open();
// The delete operations are here.
branchPage.openEditor(firstBranchName);
editorPage.deleteStage(stageToDelete);
editorPage.saveBranch(secondBranchName);
activityPage.checkUrl();
activityPage.getRunRowForBranch(secondBranchName);
sseClient.untilEvents(pipeline.buildsFinished);
}
/**
* This test covers creation of a pipeline, and adds an environment
* variable to it.
@ -223,18 +232,14 @@ public class GithubEditorTest {
*/
@Test
public void testEditorParallel() throws IOException {
String branchNameForParallelPipeline = "branch-with-parallels";
creationPage.createPipeline(token, organization, repo, true);
MultiBranchPipeline pipeline = mbpFactory.pipeline(repo);
editorPage.parallelPipeline("branch-with-parallels", 4);
editorPage.parallelPipeline(4);
editorPage.saveBranch(branchNameForParallelPipeline);
ActivityPage activityPage = pipeline.getActivityPage().checkUrl();
driver.navigate().refresh();
sseClient.untilEvents(pipeline.buildsFinished);
sseClient.clear();
BranchPage branchPage = activityPage.clickBranchTab();
branchPage.openEditor("branch-with-parallels");
editorPage.saveBranch("new - branch");
activityPage.checkUrl();
activityPage.getRunRowForBranch("branch-with-parallels");
sseClient.untilEvents(pipeline.buildsFinished);
}
}

View File

@ -402,7 +402,8 @@ export class EditorPipelineGraph extends Component<DefaultProps, Props, State> {
}
}
return (
<div className={classNames.join(' ')} style={style} key={key} onClick={e => this.nodeClicked({ isPlaceholder: false, stage }, e)}>
// The id is in here to facilitate easier test automation.
<div className={classNames.join(' ')} id={`pipeline-big-label-${details.text ? `${details.text}` : ""}`} style={style} key={key} onClick={e => this.nodeClicked({ isPlaceholder: false, stage }, e)}>
{details.text || NBSP}
{inner}
</div>