Browse Source
* fix switch bug * add switch e2e test * add switch workflow * pre task option * selectPreTask id * update * switch task e2e * naming optimization Co-authored-by: caishunfeng <534328519@qq.com>3.0.0/version-upgrade
wind
3 years ago
committed by
GitHub
14 changed files with 548 additions and 9 deletions
@ -0,0 +1,185 @@ |
|||||||
|
/* |
||||||
|
* Licensed to Apache Software Foundation (ASF) under one or more contributor |
||||||
|
* license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright |
||||||
|
* ownership. Apache Software Foundation (ASF) licenses this file to you under |
||||||
|
* the Apache License, Version 2.0 (the "License"); you may |
||||||
|
* not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.apache.dolphinscheduler.e2e.cases; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.LoginPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm.TaskType; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab.Row; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SwitchTaskForm; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; |
||||||
|
import org.junit.jupiter.api.AfterAll; |
||||||
|
import org.junit.jupiter.api.BeforeAll; |
||||||
|
import org.junit.jupiter.api.Order; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||||
|
import static org.awaitility.Awaitility.await; |
||||||
|
|
||||||
|
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") |
||||||
|
class WorkflowSwitchE2ETest { |
||||||
|
private static final String project = "test-workflow-1"; |
||||||
|
private static final String workflow = "test-workflow-1"; |
||||||
|
private static final String ifBranchName = "key==1"; |
||||||
|
private static final String elseBranchName = "key!=1"; |
||||||
|
|
||||||
|
private static final String tenant = System.getProperty("user.name"); |
||||||
|
|
||||||
|
private static RemoteWebDriver browser; |
||||||
|
|
||||||
|
@BeforeAll |
||||||
|
public static void setup() { |
||||||
|
new LoginPage(browser) |
||||||
|
.login("admin", "dolphinscheduler123") |
||||||
|
.goToNav(SecurityPage.class) |
||||||
|
.goToTab(TenantPage.class) |
||||||
|
.create(tenant) |
||||||
|
.goToNav(ProjectPage.class) |
||||||
|
.create(project) |
||||||
|
; |
||||||
|
} |
||||||
|
|
||||||
|
@AfterAll |
||||||
|
public static void cleanup() { |
||||||
|
new NavBarPage(browser) |
||||||
|
.goToNav(ProjectPage.class) |
||||||
|
.goTo(project) |
||||||
|
.goToTab(WorkflowDefinitionTab.class) |
||||||
|
.cancelPublishAll() |
||||||
|
.deleteAll() |
||||||
|
; |
||||||
|
new NavBarPage(browser) |
||||||
|
.goToNav(ProjectPage.class) |
||||||
|
.delete(project) |
||||||
|
.goToNav(SecurityPage.class) |
||||||
|
.goToTab(TenantPage.class) |
||||||
|
.delete(tenant) |
||||||
|
; |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@Order(1) |
||||||
|
void testCreateSwitchWorkflow() { |
||||||
|
|
||||||
|
final WorkflowDefinitionTab workflowDefinitionPage = |
||||||
|
new ProjectPage(browser) |
||||||
|
.goTo(project) |
||||||
|
.goToTab(WorkflowDefinitionTab.class); |
||||||
|
|
||||||
|
WorkflowForm workflowForm = workflowDefinitionPage.createWorkflow(); |
||||||
|
|
||||||
|
workflowForm.<ShellTaskForm> addTask(TaskType.SHELL) |
||||||
|
.script("echo ${today}\necho ${global_param}\n") |
||||||
|
.name("pre-task") |
||||||
|
.submit(); |
||||||
|
|
||||||
|
SwitchTaskForm switchTaskForm = workflowForm.addTask(TaskType.SWITCH); |
||||||
|
switchTaskForm.preTask("pre-task") |
||||||
|
.name("switch") |
||||||
|
.submit(); |
||||||
|
|
||||||
|
workflowForm.<ShellTaskForm>addTask(TaskType.SHELL) |
||||||
|
.script("echo ${key}") |
||||||
|
.preTask("switch") |
||||||
|
.name(ifBranchName) |
||||||
|
.submit(); |
||||||
|
|
||||||
|
workflowForm.<ShellTaskForm>addTask(TaskType.SHELL) |
||||||
|
.script("echo ${key}") |
||||||
|
.preTask("switch") |
||||||
|
.name(elseBranchName) |
||||||
|
.submit(); |
||||||
|
|
||||||
|
// format dag
|
||||||
|
workflowForm.formatDAG().confirm(); |
||||||
|
|
||||||
|
// add branch for switch task
|
||||||
|
workflowForm.getTask("switch"); |
||||||
|
switchTaskForm.addIfBranch("${key}==1", ifBranchName); |
||||||
|
switchTaskForm.elseBranch(elseBranchName); |
||||||
|
switchTaskForm.submit(); |
||||||
|
|
||||||
|
workflowForm.submit() |
||||||
|
.name(workflow) |
||||||
|
.tenant(tenant) |
||||||
|
.addGlobalParam("key", "1") |
||||||
|
.submit(); |
||||||
|
|
||||||
|
await().untilAsserted(() -> assertThat( |
||||||
|
workflowDefinitionPage.workflowList() |
||||||
|
).anyMatch(it -> it.getText().contains(workflow))); |
||||||
|
|
||||||
|
workflowDefinitionPage.publish(workflow); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@Order(10) |
||||||
|
void testRunWorkflow() { |
||||||
|
final ProjectDetailPage projectPage = |
||||||
|
new ProjectPage(browser) |
||||||
|
.goToNav(ProjectPage.class) |
||||||
|
.goTo(project); |
||||||
|
|
||||||
|
projectPage |
||||||
|
.goToTab(WorkflowInstanceTab.class) |
||||||
|
.deleteAll(); |
||||||
|
|
||||||
|
projectPage |
||||||
|
.goToTab(WorkflowDefinitionTab.class) |
||||||
|
.run(workflow) |
||||||
|
.submit(); |
||||||
|
|
||||||
|
await().untilAsserted(() -> { |
||||||
|
browser.navigate().refresh(); |
||||||
|
|
||||||
|
final Row row = projectPage |
||||||
|
.goToTab(WorkflowInstanceTab.class) |
||||||
|
.instances() |
||||||
|
.iterator() |
||||||
|
.next(); |
||||||
|
|
||||||
|
assertThat(row.isSuccess()).isTrue(); |
||||||
|
assertThat(row.executionTime()).isEqualTo(1); |
||||||
|
}); |
||||||
|
|
||||||
|
// check task for switch
|
||||||
|
List<TaskInstanceTab.Row> taskInstances = projectPage |
||||||
|
.goToTab(TaskInstanceTab.class) |
||||||
|
.instances(); |
||||||
|
|
||||||
|
await().untilAsserted(() -> { |
||||||
|
assertThat(taskInstances.size()).isEqualTo(3); |
||||||
|
assertThat(taskInstances.stream().filter(row -> row.name().contains(ifBranchName)).count()).isEqualTo(1); |
||||||
|
assertThat(taskInstances.stream().noneMatch(row -> row.name().contains(elseBranchName))).isTrue(); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,65 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; |
||||||
|
import org.openqa.selenium.By; |
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.FindBys; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class TaskInstanceTab extends NavBarPage implements ProjectDetailPage.Tab { |
||||||
|
@FindBy(className = "items-task-instances") |
||||||
|
private List<WebElement> instanceList; |
||||||
|
|
||||||
|
public TaskInstanceTab(RemoteWebDriver driver) { |
||||||
|
super(driver); |
||||||
|
} |
||||||
|
|
||||||
|
public List<Row> instances() { |
||||||
|
return instanceList() |
||||||
|
.stream() |
||||||
|
.filter(WebElement::isDisplayed) |
||||||
|
.map(Row::new) |
||||||
|
.filter(row -> !row.name().isEmpty()) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
} |
||||||
|
|
||||||
|
@RequiredArgsConstructor |
||||||
|
public static class Row { |
||||||
|
private final WebElement row; |
||||||
|
|
||||||
|
public String state() { |
||||||
|
return row.findElement(By.className("task-instance-state")).getText(); |
||||||
|
} |
||||||
|
|
||||||
|
public String name() { |
||||||
|
return row.findElement(By.className("task-instance-name")).getText(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,64 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
import org.openqa.selenium.By; |
||||||
|
import org.openqa.selenium.WebDriver; |
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.FindBys; |
||||||
|
import org.openqa.selenium.support.PageFactory; |
||||||
|
import org.openqa.selenium.support.pagefactory.ByChained; |
||||||
|
import org.openqa.selenium.support.ui.ExpectedConditions; |
||||||
|
import org.openqa.selenium.support.ui.WebDriverWait; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.stream.Stream; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class WorkflowFormatDialog { |
||||||
|
private final WebDriver driver; |
||||||
|
private final WorkflowForm parent; |
||||||
|
|
||||||
|
@FindBys({ |
||||||
|
@FindBy(className = "el-dialog__wrapper"), |
||||||
|
@FindBy(className = "el-button--primary"), |
||||||
|
}) |
||||||
|
private List<WebElement> buttonConfirm; |
||||||
|
|
||||||
|
public WorkflowFormatDialog(WorkflowForm parent) { |
||||||
|
this.parent = parent; |
||||||
|
this.driver = parent.driver(); |
||||||
|
|
||||||
|
PageFactory.initElements(driver, this); |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowForm confirm() { |
||||||
|
buttonConfirm() |
||||||
|
.stream() |
||||||
|
.filter(WebElement::isDisplayed) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("No confirm button when confirm")) |
||||||
|
.click(); |
||||||
|
|
||||||
|
return parent; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,94 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; |
||||||
|
import org.openqa.selenium.By; |
||||||
|
import org.openqa.selenium.JavascriptExecutor; |
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.FindBys; |
||||||
|
import org.openqa.selenium.support.ui.ExpectedConditions; |
||||||
|
import org.openqa.selenium.support.ui.WebDriverWait; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class SwitchTaskForm extends TaskNodeForm { |
||||||
|
|
||||||
|
@FindBy(id = "btnAddIfBranch") |
||||||
|
private WebElement buttonAddBranch; |
||||||
|
|
||||||
|
@FindBys({ |
||||||
|
@FindBy(className = "switch-task"), |
||||||
|
@FindBy(className = "switch-else"), |
||||||
|
@FindBy(className = "el-input__inner") |
||||||
|
}) |
||||||
|
private WebElement inputElseBranch; |
||||||
|
|
||||||
|
public SwitchTaskForm(WorkflowForm parent) { |
||||||
|
super(parent); |
||||||
|
} |
||||||
|
|
||||||
|
public SwitchTaskForm elseBranch(String elseBranchName) { |
||||||
|
((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", inputElseBranch()); |
||||||
|
|
||||||
|
final By optionsLocator = By.className("option-else-branches"); |
||||||
|
|
||||||
|
new WebDriverWait(parent().driver(), 10) |
||||||
|
.until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); |
||||||
|
|
||||||
|
List<WebElement> webElements = parent().driver().findElements(optionsLocator); |
||||||
|
webElements.stream() |
||||||
|
.filter(it -> it.getText().contains(elseBranchName)) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("No such else branch: " + elseBranchName)) |
||||||
|
.click(); |
||||||
|
|
||||||
|
inputNodeName().click(); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public SwitchTaskForm addIfBranch(String switchScript, String ifBranchName) { |
||||||
|
((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", buttonAddBranch); |
||||||
|
|
||||||
|
SwitchTaskIfBranch switchTaskIfBranch = new SwitchTaskIfBranch(this); |
||||||
|
switchTaskIfBranch.codeEditor().content(switchScript); |
||||||
|
|
||||||
|
((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", switchTaskIfBranch.inputIfBranch()); |
||||||
|
|
||||||
|
final By optionsLocator = By.className("option-if-branches"); |
||||||
|
|
||||||
|
new WebDriverWait(parent().driver(), 10) |
||||||
|
.until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); |
||||||
|
|
||||||
|
List<WebElement> webElements = parent().driver().findElements(optionsLocator); |
||||||
|
webElements.stream() |
||||||
|
.filter(it -> it.getText().contains(ifBranchName)) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("No such if branch: " + ifBranchName)) |
||||||
|
.click(); |
||||||
|
|
||||||
|
inputNodeName().click(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; |
||||||
|
import org.openqa.selenium.WebDriver; |
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.FindBys; |
||||||
|
import org.openqa.selenium.support.PageFactory; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class SwitchTaskIfBranch { |
||||||
|
private final WebDriver driver; |
||||||
|
private final SwitchTaskForm parent; |
||||||
|
|
||||||
|
private final CodeEditor codeEditor; |
||||||
|
|
||||||
|
@FindBys({ |
||||||
|
@FindBy(className = "switch-task"), |
||||||
|
@FindBy(className = "switch-list"), |
||||||
|
@FindBy(className = "el-input") |
||||||
|
}) |
||||||
|
private WebElement inputIfBranch; |
||||||
|
|
||||||
|
public SwitchTaskIfBranch(SwitchTaskForm parent) { |
||||||
|
this.parent = parent; |
||||||
|
this.driver = parent.parent().driver(); |
||||||
|
|
||||||
|
this.codeEditor = new CodeEditor(driver); |
||||||
|
|
||||||
|
PageFactory.initElements(driver, this); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue