Browse Source

[Feature-8850][E2E] Restore project center e2e test cases in ui-next (#8909)

3.0.0/version-upgrade
xiangzihao 3 years ago committed by GitHub
parent
commit
eefe7896c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      .github/workflows/e2e.yml
  2. 129
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java
  3. 2
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java
  4. 5
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java
  5. 8
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java
  6. 30
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectPage.java
  7. 40
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowDefinitionTab.java
  8. 5
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java
  9. 29
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowInstanceTab.java
  10. 2
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java
  11. 68
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowSaveDialog.java
  12. 10
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/ShellTaskForm.java
  13. 39
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SubWorkflowTaskForm.java
  14. 48
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java
  15. 6
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FunctionManagePage.java
  16. 6
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/basic/docker-compose.yaml
  17. 2
      dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts
  18. 4
      dolphinscheduler-ui-next/src/components/modal/index.tsx
  19. 3
      dolphinscheduler-ui-next/src/views/projects/list/components/project-modal.tsx
  20. 2
      dolphinscheduler-ui-next/src/views/projects/list/index.tsx
  21. 1
      dolphinscheduler-ui-next/src/views/projects/list/use-table.ts
  22. 3
      dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-child-node.ts
  23. 3
      dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-custom-params.ts
  24. 1
      dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-name.ts
  25. 1
      dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-pre-tasks.ts
  26. 2
      dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/dag-canvas.tsx
  27. 5
      dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/dag-save-modal.tsx
  28. 2
      dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/dag-sidebar.tsx
  29. 4
      dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/dag-toolbar.tsx
  30. 3
      dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/start-modal.tsx
  31. 4
      dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/table-action.tsx
  32. 3
      dolphinscheduler-ui-next/src/views/projects/workflow/definition/index.tsx
  33. 1
      dolphinscheduler-ui-next/src/views/projects/workflow/definition/use-table.ts
  34. 2
      dolphinscheduler-ui-next/src/views/projects/workflow/instance/components/table-action.tsx
  35. 2
      dolphinscheduler-ui-next/src/views/projects/workflow/instance/index.tsx
  36. 12
      dolphinscheduler-ui-next/src/views/projects/workflow/instance/use-table.ts

8
.github/workflows/e2e.yml

@ -77,16 +77,16 @@ jobs:
class: org.apache.dolphinscheduler.e2e.cases.UserE2ETest class: org.apache.dolphinscheduler.e2e.cases.UserE2ETest
- name: WorkerGroup - name: WorkerGroup
class: org.apache.dolphinscheduler.e2e.cases.WorkerGroupE2ETest class: org.apache.dolphinscheduler.e2e.cases.WorkerGroupE2ETest
# - name: Project - name: Project
# class: org.apache.dolphinscheduler.e2e.cases.ProjectE2ETest class: org.apache.dolphinscheduler.e2e.cases.ProjectE2ETest
- name: Queue - name: Queue
class: org.apache.dolphinscheduler.e2e.cases.QueueE2ETest class: org.apache.dolphinscheduler.e2e.cases.QueueE2ETest
- name: Environment - name: Environment
class: org.apache.dolphinscheduler.e2e.cases.EnvironmentE2ETest class: org.apache.dolphinscheduler.e2e.cases.EnvironmentE2ETest
- name: Token - name: Token
class: org.apache.dolphinscheduler.e2e.cases.TokenE2ETest class: org.apache.dolphinscheduler.e2e.cases.TokenE2ETest
# - name: Workflow - name: Workflow
# class: org.apache.dolphinscheduler.e2e.cases.WorkflowE2ETest class: org.apache.dolphinscheduler.e2e.cases.WorkflowE2ETest
# - name: WorkflowForSwitch # - name: WorkflowForSwitch
# class: org.apache.dolphinscheduler.e2e.cases.WorkflowSwitchE2ETest # class: org.apache.dolphinscheduler.e2e.cases.WorkflowSwitchE2ETest
- name: FileManage - name: FileManage

129
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java

@ -32,11 +32,15 @@ import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SubWorkflowTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SubWorkflowTaskForm;
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage;
import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; import org.apache.dolphinscheduler.e2e.pages.security.TenantPage;
import org.apache.dolphinscheduler.e2e.pages.security.UserPage;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await; import static org.awaitility.Awaitility.await;
@ -44,46 +48,63 @@ import static org.awaitility.Awaitility.await;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class WorkflowE2ETest { class WorkflowE2ETest {
private static final String project = "test-workflow-1"; private static final String project = "test-workflow-1";
private static final String user = "admin";
private static final String password = "dolphinscheduler123";
private static final String email = "admin@gmail.com";
private static final String phone = "15800000000";
private static final String tenant = System.getProperty("user.name"); private static final String tenant = System.getProperty("user.name");
private static RemoteWebDriver browser; private static RemoteWebDriver browser;
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
new LoginPage(browser) UserPage userPage = new LoginPage(browser)
.login("admin", "dolphinscheduler123") .login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class) .goToNav(SecurityPage.class)
.goToTab(TenantPage.class) .goToTab(TenantPage.class)
.create(tenant) .create(tenant)
.goToNav(SecurityPage.class)
.goToTab(UserPage.class);
new WebDriverWait(userPage.driver(), 20).until(ExpectedConditions.visibilityOfElementLocated(
new By.ByClassName("name")));
userPage.update(user, user, password, email, phone, tenant)
.goToNav(ProjectPage.class) .goToNav(ProjectPage.class)
.create(project) .create(project)
; ;
} }
@AfterAll // @AfterAll
public static void cleanup() { // public static void cleanup() {
new NavBarPage(browser) // new NavBarPage(browser)
.goToNav(ProjectPage.class) // .goToNav(ProjectPage.class)
.goTo(project) // .goTo(project)
.goToTab(WorkflowDefinitionTab.class) // .goToTab(WorkflowDefinitionTab.class)
.cancelPublishAll() // .cancelPublishAll()
.deleteAll() // .deleteAll()
; // ;
new NavBarPage(browser) //
.goToNav(ProjectPage.class) // new NavBarPage(browser)
.delete(project) // .goToNav(ProjectPage.class)
.goToNav(SecurityPage.class) // .delete(project)
.goToTab(TenantPage.class) // .goToNav(SecurityPage.class)
.delete(tenant) // .goToTab(TenantPage.class)
; // .delete(tenant)
} // ;
// }
@Test @Test
@Order(1) @Order(1)
void testCreateWorkflow() { void testCreateWorkflow() {
final String workflow = "test-workflow-1"; final String workflow = "test-workflow-1";
final WorkflowDefinitionTab workflowDefinitionPage = WorkflowDefinitionTab workflowDefinitionPage =
new ProjectPage(browser) new ProjectPage(browser)
.goTo(project) .goTo(project)
.goToTab(WorkflowDefinitionTab.class); .goToTab(WorkflowDefinitionTab.class);
@ -104,43 +125,47 @@ class WorkflowE2ETest {
.submit() .submit()
; ;
await().untilAsserted(() -> assertThat( await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList())
workflowDefinitionPage.workflowList() .as("Workflow list should contain newly-created workflow")
).anyMatch(it -> it.getText().contains(workflow))); .anyMatch(
it -> it.getText().contains(workflow)
));
workflowDefinitionPage.publish(workflow); workflowDefinitionPage.publish(workflow);
} }
@Test // @Test
@Order(10) // @Order(10)
void testCreateSubWorkflow() { // void testCreateSubWorkflow() {
final String workflow = "test-sub-workflow-1"; // final String workflow = "test-sub-workflow-1";
//
final WorkflowDefinitionTab workflowDefinitionPage = // WorkflowDefinitionTab workflowDefinitionPage =
new ProjectPage(browser) // new ProjectPage(browser)
.goToNav(ProjectPage.class) // .goToNav(ProjectPage.class)
.goTo(project) // .goTo(project)
.goToTab(WorkflowDefinitionTab.class); // .goToTab(WorkflowDefinitionTab.class);
//
workflowDefinitionPage // workflowDefinitionPage
.createWorkflow() // .createWorkflow()
//
.<SubWorkflowTaskForm> addTask(TaskType.SUB_PROCESS) // .<SubWorkflowTaskForm> addTask(TaskType.SUB_PROCESS)
.submit() // .childNode("test-workflow-1")
// .name("test-sub-1")
.submit() // .submit()
.name(workflow) //
.tenant(tenant) // .submit()
.addGlobalParam("global_param", "hello world") // .name(workflow)
.submit() // .tenant(tenant)
; // .addGlobalParam("global_param", "hello world")
// .submit()
await().untilAsserted(() -> assertThat( // ;
workflowDefinitionPage.workflowList() //
).anyMatch(it -> it.getText().contains(workflow))); // await().untilAsserted(() -> assertThat(
// workflowDefinitionPage.workflowList()
workflowDefinitionPage.publish(workflow); // ).anyMatch(it -> it.getText().contains(workflow)));
} //
// workflowDefinitionPage.publish(workflow);
// }
@Test @Test
@Order(30) @Order(30)

2
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java

@ -58,6 +58,8 @@ public final class LoginPage extends NavBarPage {
@SneakyThrows @SneakyThrows
public NavBarPage login(String username, String password) { public NavBarPage login(String username, String password) {
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(buttonSwitchLanguage));
buttonSwitchLanguage().click(); buttonSwitchLanguage().click();
inputUsername().sendKeys(username); inputUsername().sendKeys(username);

5
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java

@ -19,6 +19,7 @@
*/ */
package org.apache.dolphinscheduler.e2e.pages.common; package org.apache.dolphinscheduler.e2e.pages.common;
import org.junit.rules.ExpectedException;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
@ -29,6 +30,8 @@ import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter; import lombok.Getter;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@Getter @Getter
public final class CodeEditor { public final class CodeEditor {
@ -46,6 +49,8 @@ public final class CodeEditor {
} }
public CodeEditor content(String content) { public CodeEditor content(String content) {
new WebDriverWait(this.driver, 10).until(ExpectedConditions.elementToBeClickable(editor));
editor.click(); editor.click();
Actions actions = new Actions(this.driver); Actions actions = new Actions(this.driver);

8
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java

@ -32,11 +32,13 @@ import lombok.Getter;
@Getter @Getter
public final class ProjectDetailPage extends NavBarPage { public final class ProjectDetailPage extends NavBarPage {
@FindBy(className = "tab-process-definition") @FindBy(css = ".tab-vertical .n-submenu:nth-of-type(2) .n-menu-item:nth-of-type(2) > .n-menu-item-content")
private WebElement menuProcessDefinition; private WebElement menuProcessDefinition;
@FindBy(className = "tab-process-instance")
@FindBy(css = ".tab-vertical .n-submenu:nth-of-type(2) .n-menu-item:nth-of-type(3) > .n-menu-item-content")
private WebElement menuProcessInstances; private WebElement menuProcessInstances;
@FindBy(className = "tab-task-instance")
@FindBy(css = ".tab-vertical .n-submenu:nth-of-type(3) .n-menu-item:nth-of-type(2) > .n-menu-item-content")
private WebElement menuTaskInstances; private WebElement menuTaskInstances;
public ProjectDetailPage(RemoteWebDriver driver) { public ProjectDetailPage(RemoteWebDriver driver) {

30
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectPage.java

@ -25,6 +25,7 @@ import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage.NavBarItem;
import java.util.List; import java.util.List;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
@ -37,17 +38,17 @@ import lombok.Getter;
@Getter @Getter
public final class ProjectPage extends NavBarPage implements NavBarItem { public final class ProjectPage extends NavBarPage implements NavBarItem {
@FindBy(id = "btnCreateProject") @FindBy(className = "btn-create-project")
private WebElement buttonCreateProject; private WebElement buttonCreateProject;
@FindBy(className = "items-project") @FindBy(className = "items")
private List<WebElement> projectList; private List<WebElement> projectList;
@FindBys({ @FindBys({
@FindBy(className = "el-popconfirm"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "el-button--primary"), @FindBy(className = "n-button--primary-type"),
}) })
private List<WebElement> buttonConfirm; private WebElement buttonConfirm;
private final CreateProjectForm createProjectForm; private final CreateProjectForm createProjectForm;
@ -64,9 +65,6 @@ public final class ProjectPage extends NavBarPage implements NavBarItem {
createProjectForm().inputProjectName().sendKeys(project); createProjectForm().inputProjectName().sendKeys(project);
createProjectForm().buttonSubmit().click(); createProjectForm().buttonSubmit().click();
new WebDriverWait(driver(), 10)
.until(ExpectedConditions.textToBePresentInElementLocated(By.className("project-name"), project));
return this; return this;
} }
@ -78,12 +76,7 @@ public final class ProjectPage extends NavBarPage implements NavBarItem {
.orElseThrow(() -> new RuntimeException("Cannot find project: " + project)) .orElseThrow(() -> new RuntimeException("Cannot find project: " + project))
.findElement(By.className("delete")).click(); .findElement(By.className("delete")).click();
buttonConfirm() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.stream()
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No confirm button is displayed"))
.click();
return this; return this;
} }
@ -91,7 +84,7 @@ public final class ProjectPage extends NavBarPage implements NavBarItem {
public ProjectDetailPage goTo(String project) { public ProjectDetailPage goTo(String project) {
projectList().stream() projectList().stream()
.filter(it -> it.getText().contains(project)) .filter(it -> it.getText().contains(project))
.map(it -> it.findElement(By.className("project-name"))) .map(it -> it.findElement(By.className("project-name")).findElement(new By.ByTagName("button")))
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("Cannot click the project item")) .orElseThrow(() -> new RuntimeException("Cannot click the project item"))
.click(); .click();
@ -105,10 +98,13 @@ public final class ProjectPage extends NavBarPage implements NavBarItem {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputProjectName") @FindBys({
@FindBy(className = "input-project-name"),
@FindBy(tagName = "input"),
})
private WebElement inputProjectName; private WebElement inputProjectName;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
} }
} }

40
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowDefinitionTab.java

@ -23,6 +23,7 @@ import lombok.Getter;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
@ -34,17 +35,21 @@ import java.util.stream.Collectors;
@Getter @Getter
public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDetailPage.Tab { public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDetailPage.Tab {
@FindBy(id = "btnCreateProcess") @FindBy(className = "btn-create-process")
private WebElement buttonCreateProcess; private WebElement buttonCreateProcess;
@FindBy(className = "select-all") @FindBy(className = "select-all")
private WebElement checkBoxSelectAll; private WebElement checkBoxSelectAll;
@FindBy(className = "btn-delete-all") @FindBy(className = "btn-delete-all")
private WebElement buttonDeleteAll; private WebElement buttonDeleteAll;
@FindBys({ @FindBys({
@FindBy(className = "el-popconfirm"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "el-button--primary"), @FindBy(className = "n-button--primary-type"),
}) })
private List<WebElement> buttonConfirm; private WebElement buttonConfirm;
@FindBy(className = "items") @FindBy(className = "items")
private List<WebElement> workflowList; private List<WebElement> workflowList;
@ -61,8 +66,8 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
public WorkflowDefinitionTab publish(String workflow) { public WorkflowDefinitionTab publish(String workflow) {
workflowList() workflowList()
.stream() .stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").equals(workflow)) .filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("button-publish")).stream()) .flatMap(it -> it.findElements(By.className("btn-publish")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("Can not find publish button in workflow definition")) .orElseThrow(() -> new RuntimeException("Can not find publish button in workflow definition"))
@ -74,8 +79,8 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
public WorkflowRunDialog run(String workflow) { public WorkflowRunDialog run(String workflow) {
workflowList() workflowList()
.stream() .stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").equals(workflow)) .filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("button-run")).stream()) .flatMap(it -> it.findElements(By.className("btn-run")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("Can not find run button in workflow definition")) .orElseThrow(() -> new RuntimeException("Can not find run button in workflow definition"))
@ -85,17 +90,14 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
} }
public WorkflowDefinitionTab cancelPublishAll() { public WorkflowDefinitionTab cancelPublishAll() {
final Supplier<List<WebElement>> cancelButtons = () -> List<WebElement> cancelButtons = workflowList()
workflowList()
.stream() .stream()
.flatMap(it -> it.findElements(By.className("btn-cancel-publish")).stream()) .flatMap(it -> it.findElements(By.className("btn-publish")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.collect(Collectors.toList()); .collect(Collectors.toList());
for (List<WebElement> buttons = cancelButtons.get(); for (WebElement cancelButton : cancelButtons) {
!buttons.isEmpty(); cancelButton.click();
buttons = cancelButtons.get()) {
buttons.forEach(WebElement::click);
driver().navigate().refresh(); driver().navigate().refresh();
} }
@ -109,12 +111,8 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
checkBoxSelectAll().click(); checkBoxSelectAll().click();
buttonDeleteAll().click(); buttonDeleteAll().click();
buttonConfirm()
.stream() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No confirm button is displayed"))
.click();
return this; return this;
} }

5
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java

@ -24,6 +24,7 @@ import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SubWorkflowTa
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SwitchTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SwitchTaskForm;
import org.openqa.selenium.By; import org.openqa.selenium.By;
@ -44,14 +45,14 @@ import org.openqa.selenium.support.ui.WebDriverWait;
@SuppressWarnings("UnstableApiUsage") @SuppressWarnings("UnstableApiUsage")
@Getter @Getter
public final class WorkflowForm { public final class WorkflowForm {
private final WebDriver driver; private WebDriver driver;
private final WorkflowSaveDialog saveForm; private final WorkflowSaveDialog saveForm;
private final WorkflowFormatDialog formatDialog; private final WorkflowFormatDialog formatDialog;
@FindBy(className = "graph-format") @FindBy(className = "graph-format")
private WebElement formatBtn; private WebElement formatBtn;
@FindBy(id = "btnSave") @FindBy(className = "btn-save")
private WebElement buttonSave; private WebElement buttonSave;
public WorkflowForm(WebDriver driver) { public WorkflowForm(WebDriver driver) {

29
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowInstanceTab.java

@ -26,6 +26,7 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
@ -33,20 +34,27 @@ import org.openqa.selenium.support.FindBys;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.openqa.selenium.support.pagefactory.ByChained;
@Getter @Getter
public final class WorkflowInstanceTab extends NavBarPage implements ProjectDetailPage.Tab { public final class WorkflowInstanceTab extends NavBarPage implements ProjectDetailPage.Tab {
@FindBy(className = "items-workflow-instances") @FindBy(className = "items-workflow-instances")
private List<WebElement> instanceList; private List<WebElement> instanceList;
@FindBy(className = "select-all")
@FindBys({
@FindBy(className = "btn-selected"),
@FindBy(className = "n-checkbox-box"),
})
private WebElement checkBoxSelectAll; private WebElement checkBoxSelectAll;
@FindBy(className = "btn-delete-all") @FindBy(className = "btn-delete-all")
private WebElement buttonDeleteAll; private WebElement buttonDeleteAll;
@FindBys({ @FindBys({
@FindBy(className = "el-popconfirm"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "el-button--primary"), @FindBy(className = "n-button--primary-type"),
}) })
private List<WebElement> buttonConfirm; private WebElement buttonConfirm;
public WorkflowInstanceTab(RemoteWebDriver driver) { public WorkflowInstanceTab(RemoteWebDriver driver) {
super(driver); super(driver);
@ -66,13 +74,10 @@ public final class WorkflowInstanceTab extends NavBarPage implements ProjectDeta
} }
checkBoxSelectAll().click(); checkBoxSelectAll().click();
buttonDeleteAll().click(); buttonDeleteAll().click();
buttonConfirm()
.stream() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No confirm button is displayed"))
.click();
return this; return this;
} }
@ -90,11 +95,11 @@ public final class WorkflowInstanceTab extends NavBarPage implements ProjectDeta
} }
public int executionTime() { public int executionTime() {
return Integer.parseInt(row.findElement(By.className("execution-time")).getText()); return Integer.parseInt(row.findElement(By.className("workflow-run-times")).getText());
} }
public Row rerun() { public Row rerun() {
row.findElements(By.className("btn-rerun")) row.findElements(new ByChained(By.className("btn-rerun"), By.className("n-button__content")))
.stream() .stream()
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()

2
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java

@ -29,7 +29,7 @@ import lombok.Getter;
public final class WorkflowRunDialog { public final class WorkflowRunDialog {
private final WorkflowDefinitionTab parent; private final WorkflowDefinitionTab parent;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
public WorkflowRunDialog(WorkflowDefinitionTab parent) { public WorkflowRunDialog(WorkflowDefinitionTab parent) {

68
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowSaveDialog.java

@ -38,23 +38,33 @@ public final class WorkflowSaveDialog {
private final WebDriver driver; private final WebDriver driver;
private final WorkflowForm parent; private final WorkflowForm parent;
@FindBy(id = "inputName") @FindBys({
@FindBy(className = "input-name"),
@FindBy(tagName = "input")
})
private WebElement inputName; private WebElement inputName;
@FindBy(id = "btnSubmit")
@FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBys({ @FindBys({
@FindBy(className = "input-param-key"), @FindBy(className = "input-global-params"),
@FindBy(tagName = "input"), @FindBy(tagName = "button"),
}) })
private List<WebElement> inputParamKey; private WebElement buttonGlobalCustomParameters;
@FindBys({ @FindBys({
@FindBy(className = "input-param-val"), @FindBy(className = "btn-select-tenant-code"),
@FindBy(tagName = "input"), @FindBy(className = "n-base-selection"),
}) })
private List<WebElement> inputParamVal;
@FindBy(id = "selectTenant")
private WebElement selectTenant; private WebElement selectTenant;
@FindBy(className = "n-base-select-option__content")
private List<WebElement> selectTenantOption;
@FindBy(className = "input-global-params")
private WebElement globalParamsItems;
public WorkflowSaveDialog(WorkflowForm parent) { public WorkflowSaveDialog(WorkflowForm parent) {
this.parent = parent; this.parent = parent;
this.driver = parent.driver(); this.driver = parent.driver();
@ -71,37 +81,33 @@ public final class WorkflowSaveDialog {
public WorkflowSaveDialog tenant(String tenant) { public WorkflowSaveDialog tenant(String tenant) {
selectTenant().click(); selectTenant().click();
final By optionsLocator = By.className("option-tenants"); selectTenantOption()
new WebDriverWait(driver, 10)
.until(ExpectedConditions.visibilityOfElementLocated(optionsLocator));
driver().findElements(optionsLocator)
.stream() .stream()
.filter(it -> it.getText().contains(tenant)) .filter(it -> it.getAttribute("innerText").contains(tenant))
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No such tenant: " + tenant)) .orElseThrow(() -> new RuntimeException(String.format("No %s in workflow save dialog tenant dropdown " +
.click() "list", tenant)))
; .click();
return this; return this;
} }
public WorkflowSaveDialog addGlobalParam(String key, String val) { public WorkflowSaveDialog addGlobalParam(String key, String value) {
assert inputParamKey().size() == inputParamVal().size(); final int len = globalParamsItems().findElements(By.tagName("input")).size();
final int len = inputParamKey().size();
final WebDriver driver = parent().driver(); final WebDriver driver = parent().driver();
Stream.concat(
driver.findElements(new ByChained(By.className("user-def-params-model"), By.className("add"))).stream(),
driver.findElements(new ByChained(By.className("user-def-params-model"), By.className("add-dp"))).stream())
.findFirst()
.orElseThrow(() -> new RuntimeException("Cannot find button to add param"))
.click();
inputParamKey().get(len).sendKeys(key); if (len == 0) {
inputParamVal().get(len).sendKeys(val); buttonGlobalCustomParameters().click();
globalParamsItems().findElements(By.tagName("input")).get(0).sendKeys(key);
globalParamsItems().findElements(By.tagName("input")).get(1).sendKeys(value);
} else {
globalParamsItems().findElements(By.tagName("button")).get(len-1).click();
globalParamsItems().findElements(By.tagName("input")).get(len).sendKeys(key);
globalParamsItems().findElements(By.tagName("input")).get(len+1).sendKeys(value);
}
return this; return this;
} }

10
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/ShellTaskForm.java

@ -23,19 +23,25 @@ import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm;
import lombok.Getter; import lombok.Getter;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
@Getter @Getter
public final class ShellTaskForm extends TaskNodeForm { public final class ShellTaskForm extends TaskNodeForm {
private final CodeEditor codeEditor; private CodeEditor codeEditor;
private WebDriver driver;
public ShellTaskForm(WorkflowForm parent) { public ShellTaskForm(WorkflowForm parent) {
super(parent); super(parent);
this.codeEditor = new CodeEditor(parent.driver()); this.codeEditor = new CodeEditor(parent.driver());
this.driver = parent.driver();
} }
public ShellTaskForm script(String script) { public ShellTaskForm script(String script) {
codeEditor().content(script); codeEditor.content(script);
return this; return this;
} }

39
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SubWorkflowTaskForm.java

@ -22,10 +22,49 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow.task;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm;
import lombok.Getter; 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.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.List;
@Getter @Getter
public final class SubWorkflowTaskForm extends TaskNodeForm { public final class SubWorkflowTaskForm extends TaskNodeForm {
@FindBys({
@FindBy(className = "select-child-node"),
@FindBy(className = "n-base-selection"),
})
private WebElement btnSelectChildNodeDropdown;
@FindBy(className = "n-base-select-option__content")
private List<WebElement> selectChildNode;
private WebDriver driver;
public SubWorkflowTaskForm(WorkflowForm parent) { public SubWorkflowTaskForm(WorkflowForm parent) {
super(parent); super(parent);
this.driver = parent.driver();
}
public SubWorkflowTaskForm childNode(String node) {
btnSelectChildNodeDropdown().click();
new WebDriverWait(driver, 5).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
selectChildNode()
.stream()
.filter(it -> it.getText().contains(node))
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format("No %s in child node dropdown list", node)))
.click();
return this;
} }
} }

48
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java

@ -37,27 +37,42 @@ import java.util.stream.Stream;
@Getter @Getter
public abstract class TaskNodeForm { public abstract class TaskNodeForm {
@FindBy(id = "inputNodeName") @FindBys({
@FindBy(className = "input-node-name"),
@FindBy(tagName = "input")
})
private WebElement inputNodeName; private WebElement inputNodeName;
@FindBy(id = "btnSubmit")
@FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBys({ @FindBys({
@FindBy(className = "input-param-key"), @FindBy(className = "input-param-key"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private List<WebElement> inputParamKey; private List<WebElement> inputParamKey;
@FindBys({ @FindBys({
@FindBy(className = "input-param-val"), @FindBy(className = "input-param-value"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private List<WebElement> inputParamVal; private List<WebElement> inputParamValue;
@FindBys({ @FindBys({
@FindBy(className = "pre_tasks-model"), @FindBy(className = "pre-tasks-model"),
@FindBy(tagName = "input"), @FindBy(className = "n-base-selection"),
}) })
private WebElement selectPreTasks; private WebElement selectPreTasks;
@FindBys({
@FindBy(className = "btn-custom-parameters"),
@FindBy(tagName = "button"),
})
private WebElement buttonCustomParameters;
@FindBy(className = "btn-create-custom-parameter")
private WebElement buttonCreateCustomParameters;
private final WorkflowForm parent; private final WorkflowForm parent;
TaskNodeForm(WorkflowForm parent) { TaskNodeForm(WorkflowForm parent) {
@ -74,21 +89,24 @@ public abstract class TaskNodeForm {
return this; return this;
} }
public TaskNodeForm addParam(String key, String val) { public TaskNodeForm addParam(String key, String value) {
assert inputParamKey().size() == inputParamVal().size(); assert inputParamKey().size() == inputParamValue().size();
final int len = inputParamKey().size(); final int len = inputParamKey().size();
final WebDriver driver = parent().driver(); final WebDriver driver = parent().driver();
Stream.concat(
driver.findElements(new ByChained(By.className("user-def-params-model"), By.className("add"))).stream(), if (len == 0) {
driver.findElements(new ByChained(By.className("user-def-params-model"), By.className("add-dp"))).stream()) buttonCustomParameters().click();
.findFirst()
.orElseThrow(() -> new RuntimeException("Cannot find button to add param")) inputParamKey().get(0).sendKeys(key);
.click(); inputParamValue().get(0).sendKeys(value);
} else {
buttonCreateCustomParameters().click();
inputParamKey().get(len).sendKeys(key); inputParamKey().get(len).sendKeys(key);
inputParamVal().get(len).sendKeys(val); inputParamValue().get(len).sendKeys(value);
}
return this; return this;
} }

6
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FunctionManagePage.java

@ -51,9 +51,9 @@ public class FunctionManagePage extends NavBarPage implements ResourcePage.Tab {
}) })
private WebElement buttonConfirm; private WebElement buttonConfirm;
private final CreateUdfFunctionBox createUdfFunctionBox; private CreateUdfFunctionBox createUdfFunctionBox;
private final RenameUdfFunctionBox renameUdfFunctionBox; private RenameUdfFunctionBox renameUdfFunctionBox;
public FunctionManagePage(RemoteWebDriver driver) { public FunctionManagePage(RemoteWebDriver driver) {
super(driver); super(driver);
@ -66,7 +66,7 @@ public class FunctionManagePage extends NavBarPage implements ResourcePage.Tab {
public FunctionManagePage createUdfFunction(String udfFunctionName, String className, String udfResourceName, String description) { public FunctionManagePage createUdfFunction(String udfFunctionName, String className, String udfResourceName, String description) {
buttonCreateUdfFunction().click(); buttonCreateUdfFunction().click();
createUdfFunctionBox().radioFunctionType().click(); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", createUdfFunctionBox().radioFunctionType());
createUdfFunctionBox().inputFunctionName().sendKeys(udfFunctionName); createUdfFunctionBox().inputFunctionName().sendKeys(udfFunctionName);

6
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/basic/docker-compose.yaml

@ -23,10 +23,8 @@ services:
environment: environment:
MASTER_MAX_CPU_LOAD_AVG: 100 MASTER_MAX_CPU_LOAD_AVG: 100
WORKER_TENANT_AUTO_CREATE: 'true' WORKER_TENANT_AUTO_CREATE: 'true'
# expose: expose:
# - 12345 - 12345
ports:
- 12345:12345
networks: networks:
- e2e - e2e
healthcheck: healthcheck:

2
dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts

@ -46,6 +46,7 @@ const CustomParameters = defineComponent({
circle: true, circle: true,
size: 'small', size: 'small',
type: 'info', type: 'info',
class: 'btn-create-custom-parameter',
disabled, disabled,
onClick: onAdd onClick: onAdd
}, },
@ -134,6 +135,7 @@ export function renderCustomParameters(
type: 'error', type: 'error',
size: 'small', size: 'small',
disabled, disabled,
class: 'btn-delete-custom-parameter',
onClick: () => { onClick: () => {
fields[field].splice(i, 1) fields[field].splice(i, 1)
rules.splice(i, 1) rules.splice(i, 1)

4
dolphinscheduler-ui-next/src/components/modal/index.tsx

@ -123,7 +123,7 @@ const Modal = defineComponent({
<NSpace justify='end'> <NSpace justify='end'>
{this.cancelShow && ( {this.cancelShow && (
<NButton <NButton
class={this.cancelClassName} class={[this.cancelClassName, 'btn-cancel']}
quaternary quaternary
size='small' size='small'
onClick={onCancel} onClick={onCancel}
@ -134,7 +134,7 @@ const Modal = defineComponent({
{/* TODO: Add left and right slots later */} {/* TODO: Add left and right slots later */}
{renderSlot($slots, 'btn-middle')} {renderSlot($slots, 'btn-middle')}
<NButton <NButton
class={this.confirmClassName} class={[this.confirmClassName, 'btn-submit']}
type='info' type='info'
size='small' size='small'
onClick={onConfirm} onClick={onConfirm}

3
dolphinscheduler-ui-next/src/views/projects/list/components/project-modal.tsx

@ -101,6 +101,8 @@ const ProjectModal = defineComponent({
onConfirm={this.confirmModal} onConfirm={this.confirmModal}
onCancel={this.cancelModal} onCancel={this.cancelModal}
confirmDisabled={!this.model.projectName || !this.model.userName} confirmDisabled={!this.model.projectName || !this.model.userName}
confirmClassName='btn-submit'
cancelClassName='btn-cancel'
confirmLoading={this.saving} confirmLoading={this.saving}
> >
<NForm rules={this.rules} ref='projectFormRef'> <NForm rules={this.rules} ref='projectFormRef'>
@ -108,6 +110,7 @@ const ProjectModal = defineComponent({
<NInput <NInput
v-model={[this.model.projectName, 'value']} v-model={[this.model.projectName, 'value']}
placeholder={t('project.list.project_tips')} placeholder={t('project.list.project_tips')}
class='input-project-name'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('project.list.owned_users')} path='userName'> <NFormItem label={t('project.list.owned_users')} path='userName'>

2
dolphinscheduler-ui-next/src/views/projects/list/index.tsx

@ -100,7 +100,7 @@ const list = defineComponent({
size='small' size='small'
onClick={this.handleModalChange} onClick={this.handleModalChange}
type='primary' type='primary'
class='btn-create-tenant' class='btn-create-project'
> >
{t('project.list.create_project')} {t('project.list.create_project')}
</NButton> </NButton>

1
dolphinscheduler-ui-next/src/views/projects/list/use-table.ts

@ -71,6 +71,7 @@ export function useTable() {
{ {
title: t('project.list.project_name'), title: t('project.list.project_name'),
key: 'name', key: 'name',
className: 'project-name',
render: (row: { code: string; name: any }) => render: (row: { code: string; name: any }) =>
h( h(
NEllipsis, NEllipsis,

3
dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-child-node.ts

@ -82,6 +82,7 @@ export function useChildNode({
loading: loading, loading: loading,
'on-update:value': onChange 'on-update:value': onChange
}, },
options: options options: options,
class: 'select-child-node'
} }
} }

3
dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-custom-params.ts

@ -39,12 +39,14 @@ export function useCustomParams({
type: 'custom-parameters', type: 'custom-parameters',
field: field, field: field,
name: t(`project.node.${name}`), name: t(`project.node.${name}`),
class: 'btn-custom-parameters',
span, span,
children: [ children: [
{ {
type: 'input', type: 'input',
field: 'prop', field: 'prop',
span: 10, span: 10,
class: 'input-param-key',
props: { props: {
placeholder: t('project.node.prop_tips'), placeholder: t('project.node.prop_tips'),
maxLength: 256 maxLength: 256
@ -71,6 +73,7 @@ export function useCustomParams({
type: 'input', type: 'input',
field: 'value', field: 'value',
span: 10, span: 10,
class: 'input-param-value',
props: { props: {
placeholder: t('project.node.value_tips'), placeholder: t('project.node.value_tips'),
maxLength: 256 maxLength: 256

1
dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-name.ts

@ -23,6 +23,7 @@ export function useName(): IJsonItem {
return { return {
type: 'input', type: 'input',
field: 'name', field: 'name',
class: 'input-node-name',
name: t('project.node.name'), name: t('project.node.name'),
props: { props: {
placeholder: t('project.node.name_tips'), placeholder: t('project.node.name_tips'),

1
dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-pre-tasks.ts

@ -57,6 +57,7 @@ export function usePreTasks(
type: 'select', type: 'select',
field: 'preTasks', field: 'preTasks',
span: 24, span: 24,
class: 'pre-tasks-model',
name: t('project.node.pre_tasks'), name: t('project.node.pre_tasks'),
props: { props: {
multiple: true, multiple: true,

2
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/dag-canvas.tsx

@ -37,7 +37,7 @@ export default defineComponent({
return () => ( return () => (
<div <div
ref={container} ref={container}
class={Styles.canvas} class={[Styles.canvas, 'dag-container']}
onDrop={(e) => { onDrop={(e) => {
context.emit('drop', e) context.emit('drop', e)
}} }}

5
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/dag-save-modal.tsx

@ -178,18 +178,20 @@ export default defineComponent({
> >
<NForm model={formValue.value} rules={rule} ref={formRef}> <NForm model={formValue.value} rules={rule} ref={formRef}>
<NFormItem label={t('project.dag.workflow_name')} path='name'> <NFormItem label={t('project.dag.workflow_name')} path='name'>
<NInput v-model:value={formValue.value.name} /> <NInput v-model:value={formValue.value.name} class='input-name'/>
</NFormItem> </NFormItem>
<NFormItem label={t('project.dag.description')} path='description'> <NFormItem label={t('project.dag.description')} path='description'>
<NInput <NInput
type='textarea' type='textarea'
v-model:value={formValue.value.description} v-model:value={formValue.value.description}
class='input-description'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('project.dag.tenant')} path='tenantCode'> <NFormItem label={t('project.dag.tenant')} path='tenantCode'>
<NSelect <NSelect
options={tenantsDropdown.value} options={tenantsDropdown.value}
v-model:value={formValue.value.tenantCode} v-model:value={formValue.value.tenantCode}
class='btn-select-tenant-code'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('project.dag.timeout_alert')} path='timeoutFlag'> <NFormItem label={t('project.dag.timeout_alert')} path='timeoutFlag'>
@ -216,6 +218,7 @@ export default defineComponent({
preset='pair' preset='pair'
key-placeholder={t('project.dag.key')} key-placeholder={t('project.dag.key')}
value-placeholder={t('project.dag.value')} value-placeholder={t('project.dag.value')}
class='input-global-params'
/> />
</NFormItem> </NFormItem>
{props.definition && ( {props.definition && (

2
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/dag-sidebar.tsx

@ -35,7 +35,7 @@ export default defineComponent({
<div class={styles.sidebar}> <div class={styles.sidebar}>
{allTaskTypes.map((task) => ( {allTaskTypes.map((task) => (
<div <div
class={styles.draggable} class={[styles.draggable, `task-item-${task.type}`]}
draggable='true' draggable='true'
onDragstart={(e) => { onDragstart={(e) => {
context.emit('dragStart', e, task.type as TaskType) context.emit('dragStart', e, task.type as TaskType)

4
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/dag-toolbar.tsx

@ -462,7 +462,7 @@ export default defineComponent({
)} )}
{/* Save workflow */} {/* Save workflow */}
<NButton <NButton
class={Styles['toolbar-right-item']} class={[Styles['toolbar-right-item'], 'btn-save']}
type='info' type='info'
secondary secondary
round round
@ -473,7 +473,7 @@ export default defineComponent({
{t('project.dag.save')} {t('project.dag.save')}
</NButton> </NButton>
{/* Return to previous page */} {/* Return to previous page */}
<NButton secondary round onClick={onClose}> <NButton secondary round onClick={onClose} class='btn-close'>
{t('project.dag.close')} {t('project.dag.close')}
</NButton> </NButton>
</div> </div>

3
dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/start-modal.tsx

@ -392,12 +392,13 @@ export default defineComponent({
text text
type='error' type='error'
onClick={() => this.removeStartParams(index)} onClick={() => this.removeStartParams(index)}
class='btn-delete-custom-parameter'
> >
<NIcon> <NIcon>
<DeleteOutlined /> <DeleteOutlined />
</NIcon> </NIcon>
</NButton> </NButton>
<NButton text type='primary' onClick={this.addStartParams}> <NButton text type='primary' onClick={this.addStartParams} class='btn-create-custom-parameter'>
<NIcon> <NIcon>
<PlusCircleOutlined /> <PlusCircleOutlined />
</NIcon> </NIcon>

4
dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/table-action.tsx

@ -128,6 +128,7 @@ export default defineComponent({
circle circle
onClick={this.handleEditWorkflow} onClick={this.handleEditWorkflow}
disabled={releaseState === 'ONLINE'} disabled={releaseState === 'ONLINE'}
class='btn-edit'
/* TODO: Edit workflow */ /* TODO: Edit workflow */
> >
<NIcon> <NIcon>
@ -148,6 +149,7 @@ export default defineComponent({
circle circle
onClick={this.handleStartWorkflow} onClick={this.handleStartWorkflow}
disabled={releaseState === 'OFFLINE'} disabled={releaseState === 'OFFLINE'}
class='btn-run'
> >
<NIcon> <NIcon>
<PlayCircleOutlined /> <PlayCircleOutlined />
@ -188,6 +190,7 @@ export default defineComponent({
tag='div' tag='div'
circle circle
onClick={this.handleReleaseWorkflow} onClick={this.handleReleaseWorkflow}
class='btn-publish'
> >
<NIcon> <NIcon>
{releaseState === 'ONLINE' ? ( {releaseState === 'ONLINE' ? (
@ -248,6 +251,7 @@ export default defineComponent({
tag='div' tag='div'
circle circle
disabled={releaseState === 'ONLINE'} disabled={releaseState === 'ONLINE'}
class='btn-delete'
> >
<NPopconfirm onPositiveClick={this.handleDeleteWorkflow}> <NPopconfirm onPositiveClick={this.handleDeleteWorkflow}>
{{ {{

3
dolphinscheduler-ui-next/src/views/projects/workflow/definition/index.tsx

@ -99,7 +99,7 @@ export default defineComponent({
<Card class={styles.card}> <Card class={styles.card}>
<div class={styles.header}> <div class={styles.header}>
<NSpace> <NSpace>
<NButton type='primary' onClick={this.createDefinition}> <NButton type='primary' onClick={this.createDefinition} class='btn-create-process'>
{t('project.workflow.create_workflow')} {t('project.workflow.create_workflow')}
</NButton> </NButton>
<NButton strong secondary onClick={() => (this.showRef = true)}> <NButton strong secondary onClick={() => (this.showRef = true)}>
@ -132,6 +132,7 @@ export default defineComponent({
striped striped
size={'small'} size={'small'}
class={styles.table} class={styles.table}
row-class-name='items'
/> />
<div class={styles.pagination}> <div class={styles.pagination}>
<NPagination <NPagination

1
dolphinscheduler-ui-next/src/views/projects/workflow/definition/use-table.ts

@ -65,6 +65,7 @@ export function useTable() {
title: t('project.workflow.workflow_name'), title: t('project.workflow.workflow_name'),
key: 'name', key: 'name',
width: 200, width: 200,
className: 'workflow-name',
render: (row) => render: (row) =>
h( h(
NEllipsis, NEllipsis,

2
dolphinscheduler-ui-next/src/views/projects/workflow/instance/components/table-action.tsx

@ -116,6 +116,7 @@ export default defineComponent({
size='small' size='small'
type='info' type='info'
circle circle
class='btn-edit'
disabled={ disabled={
(state !== 'SUCCESS' && (state !== 'SUCCESS' &&
state !== 'PAUSE' && state !== 'PAUSE' &&
@ -143,6 +144,7 @@ export default defineComponent({
type='info' type='info'
circle circle
onClick={this.handleReRun} onClick={this.handleReRun}
class='btn-rerun'
disabled={ disabled={
(state !== 'SUCCESS' && (state !== 'SUCCESS' &&
state !== 'PAUSE' && state !== 'PAUSE' &&

2
dolphinscheduler-ui-next/src/views/projects/workflow/instance/index.tsx

@ -107,6 +107,7 @@ export default defineComponent({
class={styles.table} class={styles.table}
scrollX={1800} scrollX={1800}
v-model:checked-row-keys={this.checkedRowKeys} v-model:checked-row-keys={this.checkedRowKeys}
row-class-name='items-workflow-instances'
/> />
<div class={styles.pagination}> <div class={styles.pagination}>
<NPagination <NPagination
@ -129,6 +130,7 @@ export default defineComponent({
type='primary' type='primary'
disabled={this.checkedRowKeys.length <= 0} disabled={this.checkedRowKeys.length <= 0}
style='position: absolute; bottom: 10px; left: 10px;' style='position: absolute; bottom: 10px; left: 10px;'
class='btn-delete-all'
> >
<NPopconfirm onPositiveClick={this.handleBatchDelete}> <NPopconfirm onPositiveClick={this.handleBatchDelete}>
{{ {{

12
dolphinscheduler-ui-next/src/views/projects/workflow/instance/use-table.ts

@ -63,7 +63,8 @@ export function useTable() {
const createColumns = (variables: any) => { const createColumns = (variables: any) => {
variables.columns = [ variables.columns = [
{ {
type: 'selection' type: 'selection',
className: 'btn-selected'
}, },
{ {
title: '#', title: '#',
@ -75,6 +76,7 @@ export function useTable() {
title: t('project.workflow.workflow_name'), title: t('project.workflow.workflow_name'),
key: 'name', key: 'name',
width: 200, width: 200,
className: 'workflow-name',
render: (row: IWorkflowInstance) => render: (row: IWorkflowInstance) =>
h( h(
ButtonLink, ButtonLink,
@ -92,13 +94,15 @@ export function useTable() {
{ {
title: t('project.workflow.status'), title: t('project.workflow.status'),
key: 'state', key: 'state',
className: 'workflow-status',
render: (_row: IWorkflowInstance) => { render: (_row: IWorkflowInstance) => {
const stateIcon = taskStateIcon[_row.state] const stateIcon = taskStateIcon[_row.state]
const iconElement = h( const iconElement = h(
NIcon, NIcon,
{ {
size: '18px', size: '18px',
style: 'position: relative; top: 7.5px; left: 7.5px' style: 'position: relative; top: 7.5px; left: 7.5px',
class: stateIcon.classNames
}, },
{ {
default: () => default: () =>
@ -134,6 +138,7 @@ export function useTable() {
{ {
title: t('project.workflow.run_type'), title: t('project.workflow.run_type'),
key: 'commandType', key: 'commandType',
className: 'workflow-run-type',
render: (_row: IWorkflowInstance) => render: (_row: IWorkflowInstance) =>
( (
_.filter(runningType(t), (v) => v.code === _row.commandType)[0] || _.filter(runningType(t), (v) => v.code === _row.commandType)[0] ||
@ -171,7 +176,8 @@ export function useTable() {
}, },
{ {
title: t('project.workflow.run_times'), title: t('project.workflow.run_times'),
key: 'runTimes' key: 'runTimes',
className: 'workflow-run-times'
}, },
{ {
title: t('project.workflow.fault_tolerant_sign'), title: t('project.workflow.fault_tolerant_sign'),

Loading…
Cancel
Save