diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 329af9f441..60a2f44865 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -108,6 +108,8 @@ jobs: class: org.apache.dolphinscheduler.e2e.cases.WorkflowE2ETest - name: WorkflowHttp class: org.apache.dolphinscheduler.e2e.cases.WorkflowHttpTaskE2ETest + - name: WorkflowJava + class: org.apache.dolphinscheduler.e2e.cases.WorkflowJavaTaskE2ETest # - name: WorkflowForSwitch # class: org.apache.dolphinscheduler.e2e.cases.WorkflowSwitchE2ETest - name: FileManage diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java new file mode 100644 index 0000000000..d61a9ddd2a --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java @@ -0,0 +1,186 @@ +/* + * 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.WorkflowDefinitionTab; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.JavaTaskForm; +import org.apache.dolphinscheduler.e2e.pages.security.EnvironmentPage; +import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; +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.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.testcontainers.shaded.org.awaitility.Awaitility; + +import java.time.Duration; + +import static org.assertj.core.api.Assertions.assertThat; + +@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") +public class WorkflowJavaTaskE2ETest { + private static final String project = "test-workflow-1"; + + private static final String workflow = "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 environmentName = "JAVA_HOME"; + + private static final String environmentConfig = "export JAVA_HOME=${JAVA_HOME:-/opt/java/openjdk}"; + + private static final String environmentDesc = "JAVA_HOME_DESC"; + + private static final String environmentWorkerGroup = "default"; + + private static final String javaContent = "public class Test {" + + " public static void main(String[] args) {" + + " System.out.println(\"hello world\");" + + " }" + + "}"; + + private static RemoteWebDriver browser; + + @BeforeAll + public static void setup() { + UserPage userPage = new LoginPage(browser) + .login(user, password) + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class) + .create(tenant) + .goToNav(SecurityPage.class) + .goToTab(EnvironmentPage.class) + .create(environmentName, environmentConfig, environmentDesc, environmentWorkerGroup) + .goToNav(SecurityPage.class) + .goToTab(UserPage.class); + + new WebDriverWait(userPage.driver(), Duration.ofSeconds(20)).until(ExpectedConditions.visibilityOfElementLocated( + new By.ByClassName("name"))); + + userPage.update(user, user, email, phone, tenant) + .goToNav(ProjectPage.class) + .create(project) + ; + } + + @AfterAll + public static void cleanup() { + new NavBarPage(browser) + .goToNav(ProjectPage.class) + .goTo(project) + .goToTab(WorkflowDefinitionTab.class) + .delete(workflow); + + new NavBarPage(browser) + .goToNav(ProjectPage.class) + .delete(project); + + browser.navigate().refresh(); + + new NavBarPage(browser) + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class) + .delete(tenant); + } + + + + @Test + @Order(1) + void testCreateWorkflow() { + WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goTo(project) + .goToTab(WorkflowDefinitionTab.class); + + workflowDefinitionPage + .createWorkflow() + . addTask(WorkflowForm.TaskType.JAVA) + .script(javaContent) + .name("test-1") + .addParam("today", "${system.datetime}") + .selectEnv(environmentName) + .submit() + .submit() + .name(workflow) + .addGlobalParam("global_param", "hello world") + .submit() + ; + + Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList()) + .as("Workflow list should contain newly-created workflow") + .anyMatch( + it -> it.getText().contains(workflow) + )); + workflowDefinitionPage.publish(workflow); + } + + + @Test + @Order(30) + 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(); + + Awaitility.await().untilAsserted(() -> { + browser.navigate().refresh(); + + final WorkflowInstanceTab.Row row = projectPage + .goToTab(WorkflowInstanceTab.class) + .instances() + .iterator() + .next(); + + assertThat(row.isSuccess()).isTrue(); + assertThat(row.executionTime()).isEqualTo(1); + }); + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java index c04df11233..58c5c96051 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java @@ -22,13 +22,14 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.HttpTaskForm; 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.SwitchTaskForm; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.JavaTaskForm; import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.List; import java.util.concurrent.TimeUnit; -import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SwitchTaskForm; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; @@ -85,6 +86,8 @@ public final class WorkflowForm { return (T) new SwitchTaskForm(this); case HTTP: return (T) new HttpTaskForm(this); + case JAVA: + return (T) new JavaTaskForm(this); } throw new UnsupportedOperationException("Unknown task type"); } @@ -121,5 +124,6 @@ public final class WorkflowForm { SUB_PROCESS, SWITCH, HTTP, + JAVA, } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/JavaTaskForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/JavaTaskForm.java new file mode 100644 index 0000000000..960f7672fd --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/JavaTaskForm.java @@ -0,0 +1,44 @@ +/* + * 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 org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; +import org.openqa.selenium.WebDriver; + +public class JavaTaskForm extends TaskNodeForm{ + private CodeEditor codeEditor; + + private WebDriver driver; + + public JavaTaskForm(WorkflowForm parent) { + super(parent); + + this.codeEditor = new CodeEditor(parent.driver()); + + this.driver = parent.driver(); + } + + public JavaTaskForm script(String script) { + codeEditor.content(script); + return this; + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java index ee0f5399eb..fadfd6c38b 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java @@ -65,6 +65,12 @@ public abstract class TaskNodeForm { }) private WebElement selectPreTasks; + @FindBys({ + @FindBy(className = "env-select"), + @FindBy(className = "n-base-selection"), + }) + private WebElement selectEnv; + @FindBys({ @FindBy(className = "btn-custom-parameters"), @FindBy(tagName = "button"), @@ -112,6 +118,25 @@ public abstract class TaskNodeForm { return this; } + public TaskNodeForm selectEnv(String envName){ + ((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", selectEnv); + + final By optionsLocator = By.className("n-base-selection-input__content"); + + new WebDriverWait(parent.driver(), Duration.ofSeconds(20)) + .until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); + + List webElements = parent.driver().findElements(optionsLocator); + + webElements.stream() + .filter(it -> it.getText().contains(envName)) + .findFirst() + .orElseThrow(() -> new RuntimeException("No such envName: " + envName)) + .click(); + + return this; + } + public TaskNodeForm preTask(String preTaskName) { ((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", selectPreTasks); diff --git a/dolphinscheduler-standalone-server/src/main/docker/Dockerfile b/dolphinscheduler-standalone-server/src/main/docker/Dockerfile index 5acab794ca..40158ff8e1 100644 --- a/dolphinscheduler-standalone-server/src/main/docker/Dockerfile +++ b/dolphinscheduler-standalone-server/src/main/docker/Dockerfile @@ -15,7 +15,7 @@ # limitations under the License. # -FROM eclipse-temurin:8-jre +FROM eclipse-temurin:8-jdk ENV DOCKER true ENV TZ Asia/Shanghai diff --git a/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-environment-name.ts b/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-environment-name.ts index 22326fed9d..e3b95bda8c 100644 --- a/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-environment-name.ts +++ b/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-environment-name.ts @@ -93,6 +93,7 @@ export function useEnvironmentName( return { type: 'select', field: 'environmentCode', + class: 'env-select', span: 12, name: t('project.node.environment_name'), props: {