Browse Source

[Chore] [CI] Add api-test and e2e-test to spotless check (#16242)

dev
xiangzihao 5 months ago committed by GitHub
parent
commit
565a91790a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      .github/workflows/api-test.yml
  2. 3
      .github/workflows/owasp-dependency-check.yaml
  3. 46
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ExecutorAPITest.java
  4. 87
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessDefinitionAPITest.java
  5. 70
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessInstanceAPITest.java
  6. 57
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProjectAPITest.java
  7. 46
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/SchedulerAPITest.java
  8. 12
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/TenantAPITest.java
  9. 16
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/WorkerGroupAPITest.java
  10. 1
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseData.java
  11. 1
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseTotalList.java
  12. 1
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/LoginPage.java
  13. 8
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/project/ProjectPage.java
  14. 1
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/TenantPage.java
  15. 7
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/WorkerGroupPage.java
  16. 10
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ExecutorPage.java
  17. 8
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessDefinitionPage.java
  18. 5
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessInstancePage.java
  19. 2
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/SchedulerPage.java
  20. 10
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/JSONUtils.java
  21. 65
      dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/RequestClient.java
  22. 1
      dolphinscheduler-api-test/dolphinscheduler-api-test-core/src/main/java/org/apache/dolphinscheduler/api/test/core/DolphinScheduler.java
  23. 10
      dolphinscheduler-api-test/dolphinscheduler-api-test-core/src/main/java/org/apache/dolphinscheduler/api/test/core/DolphinSchedulerExtension.java
  24. 219
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClickhouseDataSourceE2ETest.java
  25. 22
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClusterE2ETest.java
  26. 26
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/EnvironmentE2ETest.java
  27. 169
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java
  28. 24
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java
  29. 221
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/MysqlDataSourceE2ETest.java
  30. 219
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/PostgresDataSourceE2ETest.java
  31. 9
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ProjectE2ETest.java
  32. 12
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/QueueE2ETest.java
  33. 219
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/SqlServerDataSourceE2ETest.java
  34. 34
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TenantE2ETest.java
  35. 23
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TokenE2ETest.java
  36. 39
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java
  37. 40
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java
  38. 91
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java
  39. 21
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowHttpTaskE2ETest.java
  40. 24
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java
  41. 95
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowSwitchE2ETest.java
  42. 14
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java
  43. 30
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java
  44. 1
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/DefaultTenant.java
  45. 3
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/AdminUser.java
  46. 3
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/IUser.java
  47. 24
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java
  48. 14
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java
  49. 11
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/HttpInput.java
  50. 23
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java
  51. 405
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java
  52. 13
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java
  53. 14
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectPage.java
  54. 22
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/TaskInstanceTab.java
  55. 58
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowDefinitionTab.java
  56. 20
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java
  57. 11
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowFormatDialog.java
  58. 30
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowInstanceTab.java
  59. 18
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java
  60. 15
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowSaveDialog.java
  61. 5
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/HttpTaskForm.java
  62. 4
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/JavaTaskForm.java
  63. 3
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/ShellTaskForm.java
  64. 19
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SubWorkflowTaskForm.java
  65. 21
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskForm.java
  66. 5
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskIfBranch.java
  67. 15
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java
  68. 664
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java
  69. 124
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java
  70. 29
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/ClusterPage.java
  71. 42
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java
  72. 9
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/NamespacePage.java
  73. 11
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/QueuePage.java
  74. 56
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java
  75. 15
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java
  76. 73
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java
  77. 79
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java
  78. 40
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/WorkerGroupPage.java
  79. 5
      dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/Constants.java
  80. 1
      dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinScheduler.java
  81. 37
      dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java
  82. 5
      dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/TestDescription.java
  83. 1
      dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java
  84. 4
      dolphinscheduler-e2e/pom.xml
  85. 8
      pom.xml

2
.github/workflows/api-test.yml

@ -125,7 +125,7 @@ jobs:
run: | run: |
./mvnw -B -f dolphinscheduler-api-test/pom.xml -am \ ./mvnw -B -f dolphinscheduler-api-test/pom.xml -am \
-DfailIfNoTests=false \ -DfailIfNoTests=false \
-Dspotless.skip=false \ -Dspotless.skip=true \
-Dtest=${{ matrix.case.class }} test -Dtest=${{ matrix.case.class }} test
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: always() if: always()

3
.github/workflows/owasp-dependency-check.yaml

@ -30,6 +30,7 @@ env:
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 120
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@ -47,4 +48,4 @@ jobs:
continue-on-error: true continue-on-error: true
with: with:
name: dependency report name: dependency report
path: target/dependency-check-report.html path: target/dependency-check-report.html

46
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ExecutorAPITest.java

@ -31,17 +31,8 @@ import org.apache.dolphinscheduler.common.enums.FailureStrategy;
import org.apache.dolphinscheduler.common.enums.ReleaseState; import org.apache.dolphinscheduler.common.enums.ReleaseState;
import org.apache.dolphinscheduler.common.enums.UserType; import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.common.enums.WarningType; import org.apache.dolphinscheduler.common.enums.WarningType;
import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
@ -51,6 +42,14 @@ import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
//TODO: Some test cases rely on ProcessInstance APIs. Should complete remaining cases after ProcessInstance related API tests done. //TODO: Some test cases rely on ProcessInstance APIs. Should complete remaining cases after ProcessInstance related API tests done.
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j @Slf4j
@ -80,7 +79,8 @@ public class ExecutorAPITest {
public static void setup() { public static void setup() {
LoginPage loginPage = new LoginPage(); LoginPage loginPage = new LoginPage();
HttpResponse loginHttpResponse = loginPage.login(username, password); HttpResponse loginHttpResponse = loginPage.login(username, password);
sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); sessionId =
JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId();
executorPage = new ExecutorPage(sessionId); executorPage = new ExecutorPage(sessionId);
processDefinitionPage = new ProcessDefinitionPage(sessionId); processDefinitionPage = new ProcessDefinitionPage(sessionId);
projectPage = new ProjectPage(sessionId); projectPage = new ProjectPage(sessionId);
@ -103,24 +103,30 @@ public class ExecutorAPITest {
HttpResponse createProjectResponse = projectPage.createProject(loginUser, "project-test"); HttpResponse createProjectResponse = projectPage.createProject(loginUser, "project-test");
HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser); HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser);
Assertions.assertTrue(queryAllProjectListResponse.getBody().getSuccess()); Assertions.assertTrue(queryAllProjectListResponse.getBody().getSuccess());
projectCode = (long) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProjectListResponse.getBody().getData()).get(0)).get("code"); projectCode = (long) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProjectListResponse
.getBody().getData()).get(0)).get("code");
// upload test workflow definition json // upload test workflow definition json
ClassLoader classLoader = getClass().getClassLoader(); ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("workflow-json/test.json").getFile()); File file = new File(classLoader.getResource("workflow-json/test.json").getFile());
CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage
.importProcessDefinition(loginUser, projectCode, file); .importProcessDefinition(loginUser, projectCode, file);
String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity()); String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity());
Assertions.assertTrue(data.contains("\"success\":true")); Assertions.assertTrue(data.contains("\"success\":true"));
// get workflow definition code // get workflow definition code
HttpResponse queryAllProcessDefinitionByProjectCodeResponse = processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); HttpResponse queryAllProcessDefinitionByProjectCodeResponse =
processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode);
Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess()); Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess());
Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString().contains("hello world")); Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString()
processDefinitionCode = (long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("code"); .contains("hello world"));
processDefinitionCode =
(long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse
.getBody().getData()).get(0)).get("processDefinition")).get("code");
// release test workflow // release test workflow
HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.ONLINE); HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser,
projectCode, processDefinitionCode, ReleaseState.ONLINE);
Assertions.assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess()); Assertions.assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess());
// trigger workflow instance // trigger workflow instance
@ -128,11 +134,12 @@ public class ExecutorAPITest {
Date date = new Date(); Date date = new Date();
String scheduleTime = String.format("%s,%s", formatter.format(date), formatter.format(date)); String scheduleTime = String.format("%s,%s", formatter.format(date), formatter.format(date));
log.info("use current time {} as scheduleTime", scheduleTime); log.info("use current time {} as scheduleTime", scheduleTime);
HttpResponse startProcessInstanceResponse = executorPage.startProcessInstance(loginUser, projectCode, processDefinitionCode, scheduleTime, FailureStrategy.END, WarningType.NONE); HttpResponse startProcessInstanceResponse = executorPage.startProcessInstance(loginUser, projectCode,
processDefinitionCode, scheduleTime, FailureStrategy.END, WarningType.NONE);
Assertions.assertTrue(startProcessInstanceResponse.getBody().getSuccess()); Assertions.assertTrue(startProcessInstanceResponse.getBody().getSuccess());
triggerCode = (long) startProcessInstanceResponse.getBody().getData(); triggerCode = (long) startProcessInstanceResponse.getBody().getData();
} catch (Exception e) { } catch (Exception e) {
log.error("failed", e); log.error("failed", e);
Assertions.fail(); Assertions.fail();
} }
@ -141,7 +148,8 @@ public class ExecutorAPITest {
@Test @Test
@Order(2) @Order(2)
public void testStartCheckProcessDefinition() { public void testStartCheckProcessDefinition() {
HttpResponse testStartCheckProcessDefinitionResponse = executorPage.startCheckProcessDefinition(loginUser, projectCode, processDefinitionCode); HttpResponse testStartCheckProcessDefinitionResponse =
executorPage.startCheckProcessDefinition(loginUser, projectCode, processDefinitionCode);
Assertions.assertTrue(testStartCheckProcessDefinitionResponse.getBody().getSuccess()); Assertions.assertTrue(testStartCheckProcessDefinitionResponse.getBody().getSuccess());
} }

87
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessDefinitionAPITest.java

@ -30,21 +30,21 @@ import org.apache.dolphinscheduler.common.enums.ReleaseState;
import org.apache.dolphinscheduler.common.enums.UserType; import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import java.io.File;; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import java.io.File;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
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 lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j @Slf4j
public class ProcessDefinitionAPITest { public class ProcessDefinitionAPITest {
@ -67,12 +67,12 @@ public class ProcessDefinitionAPITest {
private static String processDefinitionName; private static String processDefinitionName;
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
LoginPage loginPage = new LoginPage(); LoginPage loginPage = new LoginPage();
HttpResponse loginHttpResponse = loginPage.login(username, password); HttpResponse loginHttpResponse = loginPage.login(username, password);
sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); sessionId =
JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId();
processDefinitionPage = new ProcessDefinitionPage(sessionId); processDefinitionPage = new ProcessDefinitionPage(sessionId);
projectPage = new ProjectPage(sessionId); projectPage = new ProjectPage(sessionId);
loginUser = new User(); loginUser = new User();
@ -93,14 +93,15 @@ public class ProcessDefinitionAPITest {
HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser); HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser);
Assertions.assertTrue(queryAllProjectListResponse.getBody().getSuccess()); Assertions.assertTrue(queryAllProjectListResponse.getBody().getSuccess());
projectCode = (long) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProjectListResponse.getBody().getData()).get(0)).get("code"); projectCode = (long) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProjectListResponse
.getBody().getData()).get(0)).get("code");
ClassLoader classLoader = getClass().getClassLoader(); ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("workflow-json/test.json").getFile()); File file = new File(classLoader.getResource("workflow-json/test.json").getFile());
CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage
.importProcessDefinition(loginUser, projectCode, file); .importProcessDefinition(loginUser, projectCode, file);
String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity()); String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity());
Assertions.assertTrue(data.contains("\"success\":true")); Assertions.assertTrue(data.contains("\"success\":true"));
} catch (Exception e) { } catch (Exception e) {
log.error("failed", e); log.error("failed", e);
Assertions.fail(); Assertions.fail();
} }
@ -109,72 +110,92 @@ public class ProcessDefinitionAPITest {
@Test @Test
@Order(2) @Order(2)
public void testQueryAllProcessDefinitionByProjectCode() { public void testQueryAllProcessDefinitionByProjectCode() {
HttpResponse queryAllProcessDefinitionByProjectCodeResponse = processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); HttpResponse queryAllProcessDefinitionByProjectCodeResponse =
processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode);
Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess()); Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess());
Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString().contains("hello world")); Assertions.assertTrue(
processDefinitionCode = (long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("code"); queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString().contains("hello world"));
processDefinitionName = (String) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("name"); processDefinitionCode =
(long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse
.getBody().getData()).get(0)).get("processDefinition")).get("code");
processDefinitionName =
(String) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse
.getBody().getData()).get(0)).get("processDefinition")).get("name");
} }
@Test @Test
@Order(3) @Order(3)
public void testQueryProcessDefinitionByCode() { public void testQueryProcessDefinitionByCode() {
HttpResponse queryProcessDefinitionByCodeResponse = processDefinitionPage.queryProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); HttpResponse queryProcessDefinitionByCodeResponse =
processDefinitionPage.queryProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode);
Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getSuccess()); Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getSuccess());
Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getData().toString().contains("hello world")); Assertions.assertTrue(
queryProcessDefinitionByCodeResponse.getBody().getData().toString().contains("hello world"));
} }
@Test @Test
@Order(4) @Order(4)
public void testgetProcessListByProjectCode() { public void testgetProcessListByProjectCode() {
HttpResponse getProcessListByProjectCodeResponse = processDefinitionPage.getProcessListByProjectCode(loginUser, projectCode); HttpResponse getProcessListByProjectCodeResponse =
processDefinitionPage.getProcessListByProjectCode(loginUser, projectCode);
Assertions.assertTrue(getProcessListByProjectCodeResponse.getBody().getSuccess()); Assertions.assertTrue(getProcessListByProjectCodeResponse.getBody().getSuccess());
Assertions.assertTrue(getProcessListByProjectCodeResponse.getBody().getData().toString().contains("test_import")); Assertions
.assertTrue(getProcessListByProjectCodeResponse.getBody().getData().toString().contains("test_import"));
} }
@Test @Test
@Order(5) @Order(5)
public void testQueryProcessDefinitionByName() { public void testQueryProcessDefinitionByName() {
HttpResponse queryProcessDefinitionByNameResponse = processDefinitionPage.queryProcessDefinitionByName(loginUser, projectCode, processDefinitionName); HttpResponse queryProcessDefinitionByNameResponse =
processDefinitionPage.queryProcessDefinitionByName(loginUser, projectCode, processDefinitionName);
Assertions.assertTrue(queryProcessDefinitionByNameResponse.getBody().getSuccess()); Assertions.assertTrue(queryProcessDefinitionByNameResponse.getBody().getSuccess());
Assertions.assertTrue(queryProcessDefinitionByNameResponse.getBody().getData().toString().contains("hello world")); Assertions.assertTrue(
queryProcessDefinitionByNameResponse.getBody().getData().toString().contains("hello world"));
} }
@Test @Test
@Order(6) @Order(6)
public void testQueryProcessDefinitionList() { public void testQueryProcessDefinitionList() {
HttpResponse queryProcessDefinitionListResponse = processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode); HttpResponse queryProcessDefinitionListResponse =
processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode);
Assertions.assertTrue(queryProcessDefinitionListResponse.getBody().getSuccess()); Assertions.assertTrue(queryProcessDefinitionListResponse.getBody().getSuccess());
Assertions.assertTrue(queryProcessDefinitionListResponse.getBody().getData().toString().contains("hello world")); Assertions
.assertTrue(queryProcessDefinitionListResponse.getBody().getData().toString().contains("hello world"));
} }
@Test @Test
@Order(7) @Order(7)
public void testReleaseProcessDefinition() { public void testReleaseProcessDefinition() {
HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.ONLINE); HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser,
projectCode, processDefinitionCode, ReleaseState.ONLINE);
Assertions.assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess()); Assertions.assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess());
HttpResponse queryProcessDefinitionByCodeResponse = processDefinitionPage.queryProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); HttpResponse queryProcessDefinitionByCodeResponse =
processDefinitionPage.queryProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode);
Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getSuccess()); Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getSuccess());
Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getData().toString().contains("releaseState=ONLINE")); Assertions.assertTrue(
queryProcessDefinitionByCodeResponse.getBody().getData().toString().contains("releaseState=ONLINE"));
} }
@Test @Test
@Order(8) @Order(8)
public void testDeleteProcessDefinitionByCode() { public void testDeleteProcessDefinitionByCode() {
HttpResponse deleteProcessDefinitionByCodeResponse = processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); HttpResponse deleteProcessDefinitionByCodeResponse =
processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode);
Assertions.assertFalse(deleteProcessDefinitionByCodeResponse.getBody().getSuccess()); Assertions.assertFalse(deleteProcessDefinitionByCodeResponse.getBody().getSuccess());
HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.OFFLINE); HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser,
projectCode, processDefinitionCode, ReleaseState.OFFLINE);
Assertions.assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess()); Assertions.assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess());
deleteProcessDefinitionByCodeResponse = processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); deleteProcessDefinitionByCodeResponse =
processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode);
Assertions.assertTrue(deleteProcessDefinitionByCodeResponse.getBody().getSuccess()); Assertions.assertTrue(deleteProcessDefinitionByCodeResponse.getBody().getSuccess());
HttpResponse queryProcessDefinitionListResponse = processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode); HttpResponse queryProcessDefinitionListResponse =
processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode);
Assertions.assertTrue(queryProcessDefinitionListResponse.getBody().getSuccess()); Assertions.assertTrue(queryProcessDefinitionListResponse.getBody().getSuccess());
Assertions.assertFalse(queryProcessDefinitionListResponse.getBody().getData().toString().contains("hello world")); Assertions
.assertFalse(queryProcessDefinitionListResponse.getBody().getData().toString().contains("hello world"));
} }
} }

70
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessInstanceAPITest.java

@ -48,6 +48,8 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
@ -55,8 +57,6 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.testcontainers.shaded.org.awaitility.Awaitility; import org.testcontainers.shaded.org.awaitility.Awaitility;
import lombok.extern.slf4j.Slf4j;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j @Slf4j
public class ProcessInstanceAPITest { public class ProcessInstanceAPITest {
@ -89,7 +89,8 @@ public class ProcessInstanceAPITest {
public static void setup() { public static void setup() {
LoginPage loginPage = new LoginPage(); LoginPage loginPage = new LoginPage();
HttpResponse loginHttpResponse = loginPage.login(username, password); HttpResponse loginHttpResponse = loginPage.login(username, password);
sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); sessionId =
JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId();
processInstancePage = new ProcessInstancePage(sessionId); processInstancePage = new ProcessInstancePage(sessionId);
executorPage = new ExecutorPage(sessionId); executorPage = new ExecutorPage(sessionId);
processDefinitionPage = new ProcessDefinitionPage(sessionId); processDefinitionPage = new ProcessDefinitionPage(sessionId);
@ -113,24 +114,30 @@ public class ProcessInstanceAPITest {
HttpResponse createProjectResponse = projectPage.createProject(loginUser, "project-test"); HttpResponse createProjectResponse = projectPage.createProject(loginUser, "project-test");
HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser); HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser);
assertTrue(queryAllProjectListResponse.getBody().getSuccess()); assertTrue(queryAllProjectListResponse.getBody().getSuccess());
projectCode = (long) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProjectListResponse.getBody().getData()).get(0)).get("code"); projectCode = (long) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProjectListResponse
.getBody().getData()).get(0)).get("code");
// upload test workflow definition json // upload test workflow definition json
ClassLoader classLoader = getClass().getClassLoader(); ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("workflow-json/test.json").getFile()); File file = new File(classLoader.getResource("workflow-json/test.json").getFile());
CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage
.importProcessDefinition(loginUser, projectCode, file); .importProcessDefinition(loginUser, projectCode, file);
String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity()); String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity());
assertTrue(data.contains("\"success\":true")); assertTrue(data.contains("\"success\":true"));
// get workflow definition code // get workflow definition code
HttpResponse queryAllProcessDefinitionByProjectCodeResponse = processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); HttpResponse queryAllProcessDefinitionByProjectCodeResponse =
processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode);
assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess()); assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess());
assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString().contains("hello world")); assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString()
processDefinitionCode = (long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("code"); .contains("hello world"));
processDefinitionCode =
(long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse
.getBody().getData()).get(0)).get("processDefinition")).get("code");
// release test workflow // release test workflow
HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.ONLINE); HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser,
projectCode, processDefinitionCode, ReleaseState.ONLINE);
assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess()); assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess());
// trigger workflow instance // trigger workflow instance
@ -138,23 +145,27 @@ public class ProcessInstanceAPITest {
Date date = new Date(); Date date = new Date();
String scheduleTime = String.format("%s,%s", formatter.format(date), formatter.format(date)); String scheduleTime = String.format("%s,%s", formatter.format(date), formatter.format(date));
log.info("use current time {} as scheduleTime", scheduleTime); log.info("use current time {} as scheduleTime", scheduleTime);
HttpResponse startProcessInstanceResponse = executorPage.startProcessInstance(loginUser, projectCode, processDefinitionCode, scheduleTime, FailureStrategy.END, WarningType.NONE); HttpResponse startProcessInstanceResponse = executorPage.startProcessInstance(loginUser, projectCode,
processDefinitionCode, scheduleTime, FailureStrategy.END, WarningType.NONE);
assertTrue(startProcessInstanceResponse.getBody().getSuccess()); assertTrue(startProcessInstanceResponse.getBody().getSuccess());
// make sure process instance has completed and successfully persisted into db // make sure process instance has completed and successfully persisted into db
Awaitility.await() Awaitility.await()
.atMost(30, TimeUnit.SECONDS) .atMost(30, TimeUnit.SECONDS)
.untilAsserted(() -> { .untilAsserted(() -> {
// query workflow instance by trigger code // query workflow instance by trigger code
triggerCode = (long) startProcessInstanceResponse.getBody().getData(); triggerCode = (long) startProcessInstanceResponse.getBody().getData();
HttpResponse queryProcessInstancesByTriggerCodeResponse = processInstancePage.queryProcessInstancesByTriggerCode(loginUser, projectCode, triggerCode); HttpResponse queryProcessInstancesByTriggerCodeResponse = processInstancePage
assertTrue(queryProcessInstancesByTriggerCodeResponse.getBody().getSuccess()); .queryProcessInstancesByTriggerCode(loginUser, projectCode, triggerCode);
List<LinkedHashMap<String, Object>> body = (List<LinkedHashMap<String, Object>>) queryProcessInstancesByTriggerCodeResponse.getBody().getData(); assertTrue(queryProcessInstancesByTriggerCodeResponse.getBody().getSuccess());
assertTrue(CollectionUtils.isNotEmpty(body)); List<LinkedHashMap<String, Object>> body =
assertEquals("SUCCESS", body.get(0).get("state")); (List<LinkedHashMap<String, Object>>) queryProcessInstancesByTriggerCodeResponse
processInstanceId = (int) body.get(0).get("id"); .getBody().getData();
}); assertTrue(CollectionUtils.isNotEmpty(body));
} catch (Exception e) { assertEquals("SUCCESS", body.get(0).get("state"));
processInstanceId = (int) body.get(0).get("id");
});
} catch (Exception e) {
log.error("failed", e); log.error("failed", e);
Assertions.fail(); Assertions.fail();
} }
@ -163,7 +174,8 @@ public class ProcessInstanceAPITest {
@Test @Test
@Order(2) @Order(2)
public void testQueryProcessInstanceList() { public void testQueryProcessInstanceList() {
HttpResponse queryProcessInstanceListResponse = processInstancePage.queryProcessInstanceList(loginUser, projectCode, 1, 10); HttpResponse queryProcessInstanceListResponse =
processInstancePage.queryProcessInstanceList(loginUser, projectCode, 1, 10);
assertTrue(queryProcessInstanceListResponse.getBody().getSuccess()); assertTrue(queryProcessInstanceListResponse.getBody().getSuccess());
assertTrue(queryProcessInstanceListResponse.getBody().getData().toString().contains("test_import")); assertTrue(queryProcessInstanceListResponse.getBody().getData().toString().contains("test_import"));
} }
@ -171,7 +183,8 @@ public class ProcessInstanceAPITest {
@Test @Test
@Order(3) @Order(3)
public void testQueryTaskListByProcessId() { public void testQueryTaskListByProcessId() {
HttpResponse queryTaskListByProcessIdResponse = processInstancePage.queryTaskListByProcessId(loginUser, projectCode, processInstanceId); HttpResponse queryTaskListByProcessIdResponse =
processInstancePage.queryTaskListByProcessId(loginUser, projectCode, processInstanceId);
assertTrue(queryTaskListByProcessIdResponse.getBody().getSuccess()); assertTrue(queryTaskListByProcessIdResponse.getBody().getSuccess());
assertTrue(queryTaskListByProcessIdResponse.getBody().getData().toString().contains("test_import")); assertTrue(queryTaskListByProcessIdResponse.getBody().getData().toString().contains("test_import"));
} }
@ -179,7 +192,8 @@ public class ProcessInstanceAPITest {
@Test @Test
@Order(4) @Order(4)
public void testQueryProcessInstanceById() { public void testQueryProcessInstanceById() {
HttpResponse queryProcessInstanceByIdResponse = processInstancePage.queryProcessInstanceById(loginUser, projectCode, processInstanceId); HttpResponse queryProcessInstanceByIdResponse =
processInstancePage.queryProcessInstanceById(loginUser, projectCode, processInstanceId);
assertTrue(queryProcessInstanceByIdResponse.getBody().getSuccess()); assertTrue(queryProcessInstanceByIdResponse.getBody().getSuccess());
assertTrue(queryProcessInstanceByIdResponse.getBody().getData().toString().contains("test_import")); assertTrue(queryProcessInstanceByIdResponse.getBody().getData().toString().contains("test_import"));
} }
@ -187,10 +201,12 @@ public class ProcessInstanceAPITest {
@Test @Test
@Order(5) @Order(5)
public void testDeleteProcessInstanceById() { public void testDeleteProcessInstanceById() {
HttpResponse deleteProcessInstanceByIdResponse = processInstancePage.deleteProcessInstanceById(loginUser, projectCode, processInstanceId); HttpResponse deleteProcessInstanceByIdResponse =
processInstancePage.deleteProcessInstanceById(loginUser, projectCode, processInstanceId);
assertTrue(deleteProcessInstanceByIdResponse.getBody().getSuccess()); assertTrue(deleteProcessInstanceByIdResponse.getBody().getSuccess());
HttpResponse queryProcessInstanceListResponse = processInstancePage.queryProcessInstanceList(loginUser, projectCode, 1, 10); HttpResponse queryProcessInstanceListResponse =
processInstancePage.queryProcessInstanceList(loginUser, projectCode, 1, 10);
assertTrue(queryProcessInstanceListResponse.getBody().getSuccess()); assertTrue(queryProcessInstanceListResponse.getBody().getSuccess());
Assertions.assertFalse(queryProcessInstanceListResponse.getBody().getData().toString().contains("test_import")); Assertions.assertFalse(queryProcessInstanceListResponse.getBody().getData().toString().contains("test_import"));
} }

57
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProjectAPITest.java

@ -29,17 +29,17 @@ import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.Project; import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import java.util.LinkedHashMap;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
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 lombok.extern.slf4j.Slf4j;
import java.util.LinkedHashMap;
import java.util.List;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j @Slf4j
// TODO: Add more detailed permission control related cases after userPage test cases completed // TODO: Add more detailed permission control related cases after userPage test cases completed
@ -59,7 +59,8 @@ public class ProjectAPITest {
public static void setup() { public static void setup() {
LoginPage loginPage = new LoginPage(); LoginPage loginPage = new LoginPage();
HttpResponse loginHttpResponse = loginPage.login(username, password); HttpResponse loginHttpResponse = loginPage.login(username, password);
sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); sessionId =
JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId();
projectPage = new ProjectPage(sessionId); projectPage = new ProjectPage(sessionId);
loginUser = new User(); loginUser = new User();
loginUser.setUserName("admin"); loginUser.setUserName("admin");
@ -98,7 +99,8 @@ public class ProjectAPITest {
List<LinkedHashMap> projects = (List<LinkedHashMap>) queryAllProjectListResponse.getBody().getData(); List<LinkedHashMap> projects = (List<LinkedHashMap>) queryAllProjectListResponse.getBody().getData();
Long code = (Long) projects.get(0).get("code"); Long code = (Long) projects.get(0).get("code");
HttpResponse updateProjectResponse = projectPage.updateProject(loginUser, code,"project-new", loginUser.getUserName()); HttpResponse updateProjectResponse =
projectPage.updateProject(loginUser, code, "project-new", loginUser.getUserName());
Assertions.assertTrue(updateProjectResponse.getBody().getSuccess()); Assertions.assertTrue(updateProjectResponse.getBody().getSuccess());
queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser); queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser);
@ -133,17 +135,21 @@ public class ProjectAPITest {
@Test @Test
@Order(6) @Order(6)
public void testQueryProjectWithAuthorizedLevelListPaging() { public void testQueryProjectWithAuthorizedLevelListPaging() {
HttpResponse queryProjectWithAuthorizedLevelListPagingResponse = projectPage.queryProjectWithAuthorizedLevelListPaging(loginUser, loginUser.getId(),1, 1); HttpResponse queryProjectWithAuthorizedLevelListPagingResponse =
projectPage.queryProjectWithAuthorizedLevelListPaging(loginUser, loginUser.getId(), 1, 1);
Assertions.assertTrue(queryProjectWithAuthorizedLevelListPagingResponse.getBody().getSuccess()); Assertions.assertTrue(queryProjectWithAuthorizedLevelListPagingResponse.getBody().getSuccess());
Assertions.assertTrue(queryProjectWithAuthorizedLevelListPagingResponse.getBody().getData().toString().contains("project-new")); Assertions.assertTrue(queryProjectWithAuthorizedLevelListPagingResponse.getBody().getData().toString()
.contains("project-new"));
} }
@Test @Test
@Order(7) @Order(7)
public void testQueryUnauthorizedProject() { public void testQueryUnauthorizedProject() {
HttpResponse queryUnauthorizedProjectResponse = projectPage.queryUnauthorizedProject(loginUser, loginUser.getId()); HttpResponse queryUnauthorizedProjectResponse =
projectPage.queryUnauthorizedProject(loginUser, loginUser.getId());
Assertions.assertTrue(queryUnauthorizedProjectResponse.getBody().getSuccess()); Assertions.assertTrue(queryUnauthorizedProjectResponse.getBody().getSuccess());
// project-new was created by instead of authorized to this user, therefore, it should be in the unauthorized list // project-new was created by instead of authorized to this user, therefore, it should be in the unauthorized
// list
Assertions.assertTrue(queryUnauthorizedProjectResponse.getBody().getData().toString().contains("project-new")); Assertions.assertTrue(queryUnauthorizedProjectResponse.getBody().getData().toString().contains("project-new"));
} }
@ -152,17 +158,21 @@ public class ProjectAPITest {
public void testQueryAuthorizedProject() { public void testQueryAuthorizedProject() {
HttpResponse queryAuthorizedProjectResponse = projectPage.queryAuthorizedProject(loginUser, loginUser.getId()); HttpResponse queryAuthorizedProjectResponse = projectPage.queryAuthorizedProject(loginUser, loginUser.getId());
Assertions.assertTrue(queryAuthorizedProjectResponse.getBody().getSuccess()); Assertions.assertTrue(queryAuthorizedProjectResponse.getBody().getSuccess());
// project-new was created by instead of authorized to this user, therefore, it should not be in the authorized list // project-new was created by instead of authorized to this user, therefore, it should not be in the authorized
// list
Assertions.assertFalse(queryAuthorizedProjectResponse.getBody().getData().toString().contains("project-new")); Assertions.assertFalse(queryAuthorizedProjectResponse.getBody().getData().toString().contains("project-new"));
} }
@Test @Test
@Order(9) @Order(9)
public void testQueryProjectWithAuthorizedLevel() { public void testQueryProjectWithAuthorizedLevel() {
HttpResponse queryProjectWithAuthorizedLevelResponse = projectPage.queryProjectWithAuthorizedLevel(loginUser, loginUser.getId()); HttpResponse queryProjectWithAuthorizedLevelResponse =
projectPage.queryProjectWithAuthorizedLevel(loginUser, loginUser.getId());
Assertions.assertTrue(queryProjectWithAuthorizedLevelResponse.getBody().getSuccess()); Assertions.assertTrue(queryProjectWithAuthorizedLevelResponse.getBody().getSuccess());
// queryProjectWithAuthorizedLevel api returns a joint-set of projects both created by and authorized to the user // queryProjectWithAuthorizedLevel api returns a joint-set of projects both created by and authorized to the
Assertions.assertTrue(queryProjectWithAuthorizedLevelResponse.getBody().getData().toString().contains("project-new")); // user
Assertions.assertTrue(
queryProjectWithAuthorizedLevelResponse.getBody().getData().toString().contains("project-new"));
} }
@Test @Test
@ -181,10 +191,13 @@ public class ProjectAPITest {
@Test @Test
@Order(11) @Order(11)
public void testQueryProjectCreatedAndAuthorizedByUser() { public void testQueryProjectCreatedAndAuthorizedByUser() {
HttpResponse queryProjectCreatedAndAuthorizedByUserResponse = projectPage.queryProjectCreatedAndAuthorizedByUser(loginUser); HttpResponse queryProjectCreatedAndAuthorizedByUserResponse =
projectPage.queryProjectCreatedAndAuthorizedByUser(loginUser);
Assertions.assertTrue(queryProjectCreatedAndAuthorizedByUserResponse.getBody().getSuccess()); Assertions.assertTrue(queryProjectCreatedAndAuthorizedByUserResponse.getBody().getSuccess());
// queryProjectCreatedAndAuthorizedByUser api returns a joint-set of projects both created by and authorized to the user // queryProjectCreatedAndAuthorizedByUser api returns a joint-set of projects both created by and authorized to
Assertions.assertTrue(queryProjectCreatedAndAuthorizedByUserResponse.getBody().getData().toString().contains("project-new")); // the user
Assertions.assertTrue(
queryProjectCreatedAndAuthorizedByUserResponse.getBody().getData().toString().contains("project-new"));
} }
@Test @Test
@ -192,7 +205,8 @@ public class ProjectAPITest {
public void testQueryAllProjectListForDependent() { public void testQueryAllProjectListForDependent() {
HttpResponse queryAllProjectListForDependentResponse = projectPage.queryAllProjectListForDependent(loginUser); HttpResponse queryAllProjectListForDependentResponse = projectPage.queryAllProjectListForDependent(loginUser);
Assertions.assertTrue(queryAllProjectListForDependentResponse.getBody().getSuccess()); Assertions.assertTrue(queryAllProjectListForDependentResponse.getBody().getSuccess());
Assertions.assertTrue(queryAllProjectListForDependentResponse.getBody().getData().toString().contains("project-new")); Assertions.assertTrue(
queryAllProjectListForDependentResponse.getBody().getData().toString().contains("project-new"));
} }
@Test @Test
@ -203,8 +217,7 @@ public class ProjectAPITest {
Long code = (Long) projects.get(0).get("code"); Long code = (Long) projects.get(0).get("code");
HttpResponse queryAllProjectListForDependentResponse = projectPage.deleteProject(loginUser, code); HttpResponse queryAllProjectListForDependentResponse = projectPage.deleteProject(loginUser, code);
Assertions.assertTrue(queryAllProjectListForDependentResponse.getBody().getSuccess()); Assertions.assertTrue(queryAllProjectListForDependentResponse.getBody().getSuccess());
Assertions.assertFalse(queryAllProjectListForDependentResponse.getBody().getData().toString().contains("project-new")); Assertions.assertFalse(
queryAllProjectListForDependentResponse.getBody().getData().toString().contains("project-new"));
} }
} }

46
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/SchedulerAPITest.java

@ -35,14 +35,14 @@ import java.io.File;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
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 lombok.extern.slf4j.Slf4j;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j @Slf4j
public class SchedulerAPITest { public class SchedulerAPITest {
@ -67,12 +67,12 @@ public class SchedulerAPITest {
private static int scheduleId; private static int scheduleId;
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
LoginPage loginPage = new LoginPage(); LoginPage loginPage = new LoginPage();
HttpResponse loginHttpResponse = loginPage.login(username, password); HttpResponse loginHttpResponse = loginPage.login(username, password);
sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); sessionId =
JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId();
projectPage = new ProjectPage(sessionId); projectPage = new ProjectPage(sessionId);
schedulerPage = new SchedulerPage(sessionId); schedulerPage = new SchedulerPage(sessionId);
processDefinitionPage = new ProcessDefinitionPage(sessionId); processDefinitionPage = new ProcessDefinitionPage(sessionId);
@ -94,17 +94,24 @@ public class SchedulerAPITest {
HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser); HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser);
Assertions.assertTrue(queryAllProjectListResponse.getBody().getSuccess()); Assertions.assertTrue(queryAllProjectListResponse.getBody().getSuccess());
projectCode = (long) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProjectListResponse.getBody().getData()).get(0)).get("code"); projectCode = (long) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProjectListResponse
.getBody().getData()).get(0)).get("code");
ClassLoader classLoader = getClass().getClassLoader(); ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("workflow-json/test.json").getFile()); File file = new File(classLoader.getResource("workflow-json/test.json").getFile());
processDefinitionPage.importProcessDefinition(loginUser, projectCode, file); processDefinitionPage.importProcessDefinition(loginUser, projectCode, file);
HttpResponse queryAllProcessDefinitionByProjectCodeResponse = processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); HttpResponse queryAllProcessDefinitionByProjectCodeResponse =
processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode);
Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess()); Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess());
processDefinitionCode = (long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("code"); processDefinitionCode =
(long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse
processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.ONLINE); .getBody().getData()).get(0)).get("processDefinition")).get("code");
final String schedule = "{\"startTime\":\"2019-08-08 00:00:00\",\"endTime\":\"2100-08-08 00:00:00\",\"timezoneId\":\"America/Phoenix\",\"crontab\":\"0 0 3/6 * * ? *\"}" ;
HttpResponse createScheduleResponse = schedulerPage.createSchedule(loginUser, projectCode, processDefinitionCode, schedule); processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode,
ReleaseState.ONLINE);
final String schedule =
"{\"startTime\":\"2019-08-08 00:00:00\",\"endTime\":\"2100-08-08 00:00:00\",\"timezoneId\":\"America/Phoenix\",\"crontab\":\"0 0 3/6 * * ? *\"}";
HttpResponse createScheduleResponse =
schedulerPage.createSchedule(loginUser, projectCode, processDefinitionCode, schedule);
Assertions.assertTrue(createScheduleResponse.getBody().getSuccess()); Assertions.assertTrue(createScheduleResponse.getBody().getSuccess());
Assertions.assertTrue(createScheduleResponse.getBody().getData().toString().contains("2019-08-08")); Assertions.assertTrue(createScheduleResponse.getBody().getData().toString().contains("2019-08-08"));
} }
@ -115,13 +122,15 @@ public class SchedulerAPITest {
HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode); HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode);
Assertions.assertTrue(queryScheduleListResponse.getBody().getSuccess()); Assertions.assertTrue(queryScheduleListResponse.getBody().getSuccess());
Assertions.assertTrue(queryScheduleListResponse.getBody().getData().toString().contains("2019-08-08")); Assertions.assertTrue(queryScheduleListResponse.getBody().getData().toString().contains("2019-08-08"));
scheduleId = (int) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryScheduleListResponse.getBody().getData()).get(0)).get("id"); scheduleId = (int) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryScheduleListResponse.getBody()
.getData()).get(0)).get("id");
} }
@Test @Test
@Order(3) @Order(3)
public void testPublishScheduleOnline() { public void testPublishScheduleOnline() {
HttpResponse publishScheduleOnlineResponse = schedulerPage.publishScheduleOnline(loginUser, projectCode, scheduleId); HttpResponse publishScheduleOnlineResponse =
schedulerPage.publishScheduleOnline(loginUser, projectCode, scheduleId);
Assertions.assertTrue(publishScheduleOnlineResponse.getBody().getSuccess()); Assertions.assertTrue(publishScheduleOnlineResponse.getBody().getSuccess());
HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode); HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode);
@ -137,14 +146,17 @@ public class SchedulerAPITest {
HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode); HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode);
Assertions.assertTrue(queryScheduleListResponse.getBody().getSuccess()); Assertions.assertTrue(queryScheduleListResponse.getBody().getSuccess());
Assertions.assertTrue(queryScheduleListResponse.getBody().getData().toString().contains("releaseState=OFFLINE")); Assertions
.assertTrue(queryScheduleListResponse.getBody().getData().toString().contains("releaseState=OFFLINE"));
} }
@Test @Test
@Order(5) @Order(5)
public void testUpdateSchedule() { public void testUpdateSchedule() {
final String schedule = "{\"startTime\":\"1996-08-08 00:00:00\",\"endTime\":\"2200-08-08 00:00:00\",\"timezoneId\":\"America/Phoenix\",\"crontab\":\"0 0 3/6 * * ? *\"}"; final String schedule =
HttpResponse updateScheduleResponse = schedulerPage.updateSchedule(loginUser, projectCode, scheduleId, schedule); "{\"startTime\":\"1996-08-08 00:00:00\",\"endTime\":\"2200-08-08 00:00:00\",\"timezoneId\":\"America/Phoenix\",\"crontab\":\"0 0 3/6 * * ? *\"}";
HttpResponse updateScheduleResponse =
schedulerPage.updateSchedule(loginUser, projectCode, scheduleId, schedule);
Assertions.assertTrue(updateScheduleResponse.getBody().getSuccess()); Assertions.assertTrue(updateScheduleResponse.getBody().getSuccess());
HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode); HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode);
@ -163,5 +175,3 @@ public class SchedulerAPITest {
Assertions.assertFalse(queryScheduleListResponse.getBody().getData().toString().contains("1996-08-08")); Assertions.assertFalse(queryScheduleListResponse.getBody().getData().toString().contains("1996-08-08"));
} }
} }

12
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/TenantAPITest.java

@ -28,17 +28,18 @@ import org.apache.dolphinscheduler.api.test.pages.LoginPage;
import org.apache.dolphinscheduler.api.test.pages.security.TenantPage; import org.apache.dolphinscheduler.api.test.pages.security.TenantPage;
import org.apache.dolphinscheduler.api.test.utils.JSONUtils; import org.apache.dolphinscheduler.api.test.utils.JSONUtils;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
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 lombok.extern.slf4j.Slf4j;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j @Slf4j
public class TenantAPITest { public class TenantAPITest {
private static final String tenant = System.getProperty("user.name"); private static final String tenant = System.getProperty("user.name");
private static final String user = "admin"; private static final String user = "admin";
@ -54,7 +55,8 @@ public class TenantAPITest {
LoginPage loginPage = new LoginPage(); LoginPage loginPage = new LoginPage();
HttpResponse loginHttpResponse = loginPage.login(user, password); HttpResponse loginHttpResponse = loginPage.login(user, password);
sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); sessionId =
JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId();
} }
@AfterAll @AfterAll
@ -90,7 +92,9 @@ public class TenantAPITest {
HttpResponse createTenantHttpResponse = tenantPage.getTenantListPaging(sessionId, 1, 10, ""); HttpResponse createTenantHttpResponse = tenantPage.getTenantListPaging(sessionId, 1, 10, "");
boolean result = false; boolean result = false;
for (TenantListPagingResponseTotalList tenantListPagingResponseTotalList : JSONUtils.convertValue(createTenantHttpResponse.getBody().getData(), TenantListPagingResponseData.class).getTotalList()) { for (TenantListPagingResponseTotalList tenantListPagingResponseTotalList : JSONUtils
.convertValue(createTenantHttpResponse.getBody().getData(), TenantListPagingResponseData.class)
.getTotalList()) {
if (tenantListPagingResponseTotalList.getTenantCode().equals(tenant)) { if (tenantListPagingResponseTotalList.getTenantCode().equals(tenant)) {
result = true; result = true;
existTenantId = tenantListPagingResponseTotalList.getId(); existTenantId = tenantListPagingResponseTotalList.getId();

16
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/WorkerGroupAPITest.java

@ -33,14 +33,14 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
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 lombok.extern.slf4j.Slf4j;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j @Slf4j
public class WorkerGroupAPITest { public class WorkerGroupAPITest {
@ -59,7 +59,8 @@ public class WorkerGroupAPITest {
public static void setup() { public static void setup() {
LoginPage loginPage = new LoginPage(); LoginPage loginPage = new LoginPage();
HttpResponse loginHttpResponse = loginPage.login(username, password); HttpResponse loginHttpResponse = loginPage.login(username, password);
sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); sessionId =
JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId();
workerGroupPage = new WorkerGroupPage(sessionId); workerGroupPage = new WorkerGroupPage(sessionId);
loginUser = new User(); loginUser = new User();
loginUser.setId(123); loginUser.setId(123);
@ -75,7 +76,7 @@ public class WorkerGroupAPITest {
@Order(1) @Order(1)
public void testSaveWorkerGroup() { public void testSaveWorkerGroup() {
HttpResponse saveWorkerGroupHttpResponse = workerGroupPage HttpResponse saveWorkerGroupHttpResponse = workerGroupPage
.saveWorkerGroup(loginUser, 1, "test_worker_group", "10.5.0.5:1234", "test", null); .saveWorkerGroup(loginUser, 1, "test_worker_group", "10.5.0.5:1234", "test", null);
Assertions.assertTrue(saveWorkerGroupHttpResponse.getBody().getSuccess()); Assertions.assertTrue(saveWorkerGroupHttpResponse.getBody().getSuccess());
HttpResponse queryAllWorkerGroupsResponse = workerGroupPage.queryAllWorkerGroups(loginUser); HttpResponse queryAllWorkerGroupsResponse = workerGroupPage.queryAllWorkerGroups(loginUser);
@ -88,9 +89,10 @@ public class WorkerGroupAPITest {
@Test @Test
@Order(2) @Order(2)
public void testQueryAllWorkerGroupsPaging() { public void testQueryAllWorkerGroupsPaging() {
HttpResponse queryAllWorkerGroupsPagingResponse = workerGroupPage.queryAllWorkerGroupsPaging(loginUser, 1, 2, null); HttpResponse queryAllWorkerGroupsPagingResponse =
workerGroupPage.queryAllWorkerGroupsPaging(loginUser, 1, 2, null);
Assertions.assertTrue(queryAllWorkerGroupsPagingResponse.getBody().getSuccess()); Assertions.assertTrue(queryAllWorkerGroupsPagingResponse.getBody().getSuccess());
String workerGroupPageInfoData = queryAllWorkerGroupsPagingResponse.getBody().getData().toString(); String workerGroupPageInfoData = queryAllWorkerGroupsPagingResponse.getBody().getData().toString();
Assertions.assertTrue(workerGroupPageInfoData.contains("test_worker_group")); Assertions.assertTrue(workerGroupPageInfoData.contains("test_worker_group"));
} }
@ -100,7 +102,7 @@ public class WorkerGroupAPITest {
HttpResponse queryAllWorkerGroupsResponse = workerGroupPage.queryAllWorkerGroups(loginUser); HttpResponse queryAllWorkerGroupsResponse = workerGroupPage.queryAllWorkerGroups(loginUser);
Assertions.assertTrue(queryAllWorkerGroupsResponse.getBody().getSuccess()); Assertions.assertTrue(queryAllWorkerGroupsResponse.getBody().getSuccess());
String workerGroupPageInfoData = queryAllWorkerGroupsResponse.getBody().getData().toString(); String workerGroupPageInfoData = queryAllWorkerGroupsResponse.getBody().getData().toString();
Assertions.assertTrue(workerGroupPageInfoData.contains("test_worker_group")); Assertions.assertTrue(workerGroupPageInfoData.contains("test_worker_group"));
} }

1
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseData.java

@ -29,6 +29,7 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor @NoArgsConstructor
@Data @Data
public class TenantListPagingResponseData { public class TenantListPagingResponseData {
private Integer currentPage; private Integer currentPage;
private Integer pageSize; private Integer pageSize;

1
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseTotalList.java

@ -29,6 +29,7 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor @NoArgsConstructor
@Data @Data
public class TenantListPagingResponseTotalList { public class TenantListPagingResponseTotalList {
private Date createTime; private Date createTime;
private Date updateTime; private Date updateTime;

1
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/LoginPage.java

@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public final class LoginPage { public final class LoginPage {
public HttpResponse login(String username, String password) { public HttpResponse login(String username, String password) {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();

8
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/project/ProjectPage.java

@ -19,8 +19,6 @@
package org.apache.dolphinscheduler.api.test.pages.project; package org.apache.dolphinscheduler.api.test.pages.project;
import lombok.AllArgsConstructor;
import org.apache.dolphinscheduler.api.test.core.Constants; import org.apache.dolphinscheduler.api.test.core.Constants;
import org.apache.dolphinscheduler.api.test.entity.HttpResponse; import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
import org.apache.dolphinscheduler.api.test.utils.RequestClient; import org.apache.dolphinscheduler.api.test.utils.RequestClient;
@ -29,8 +27,11 @@ import org.apache.dolphinscheduler.dao.entity.User;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import lombok.AllArgsConstructor;
@AllArgsConstructor @AllArgsConstructor
public final class ProjectPage { public final class ProjectPage {
private String sessionId; private String sessionId;
public HttpResponse createProject(User loginUser, String projectName) { public HttpResponse createProject(User loginUser, String projectName) {
@ -90,7 +91,8 @@ public final class ProjectPage {
return requestClient.get("/projects", headers, params); return requestClient.get("/projects", headers, params);
} }
public HttpResponse queryProjectWithAuthorizedLevelListPaging(User loginUser, Integer userId, Integer pageSize, Integer pageNo) { public HttpResponse queryProjectWithAuthorizedLevelListPaging(User loginUser, Integer userId, Integer pageSize,
Integer pageNo) {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("loginUser", loginUser); params.put("loginUser", loginUser);
params.put("userId", userId); params.put("userId", userId);

1
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/TenantPage.java

@ -27,6 +27,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public final class TenantPage { public final class TenantPage {
public HttpResponse createTenant(String sessionId, String tenant, Integer queueId, String description) { public HttpResponse createTenant(String sessionId, String tenant, Integer queueId, String description) {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("tenantCode", tenant); params.put("tenantCode", tenant);

7
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/WorkerGroupPage.java

@ -19,8 +19,6 @@
package org.apache.dolphinscheduler.api.test.pages.security; package org.apache.dolphinscheduler.api.test.pages.security;
import lombok.AllArgsConstructor;
import org.apache.dolphinscheduler.api.test.core.Constants; import org.apache.dolphinscheduler.api.test.core.Constants;
import org.apache.dolphinscheduler.api.test.entity.HttpResponse; import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
import org.apache.dolphinscheduler.api.test.utils.RequestClient; import org.apache.dolphinscheduler.api.test.utils.RequestClient;
@ -29,13 +27,15 @@ import org.apache.dolphinscheduler.dao.entity.User;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import lombok.AllArgsConstructor;
@AllArgsConstructor @AllArgsConstructor
public class WorkerGroupPage { public class WorkerGroupPage {
private String sessionId; private String sessionId;
public HttpResponse saveWorkerGroup(User loginUser, int id, String name, String addrList, String description, String otherParamsJson) { public HttpResponse saveWorkerGroup(User loginUser, int id, String name, String addrList, String description,
String otherParamsJson) {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("loginUser", loginUser); params.put("loginUser", loginUser);
params.put("id", id); params.put("id", id);
@ -96,5 +96,4 @@ public class WorkerGroupPage {
return requestClient.get("/worker-groups/worker-address-list", headers, params); return requestClient.get("/worker-groups/worker-address-list", headers, params);
} }
} }

10
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ExecutorPage.java

@ -34,14 +34,15 @@ import java.util.Map;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@AllArgsConstructor @AllArgsConstructor
public class ExecutorPage { public class ExecutorPage {
private String sessionId; private String sessionId;
public HttpResponse startProcessInstance(User loginUser, long projectCode, long processDefinitionCode, String scheduleTime, FailureStrategy failureStrategy, WarningType warningType) { public HttpResponse startProcessInstance(User loginUser, long projectCode, long processDefinitionCode,
String scheduleTime, FailureStrategy failureStrategy,
WarningType warningType) {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("loginUser", loginUser); params.put("loginUser", loginUser);
params.put("processDefinitionCode", processDefinitionCode); params.put("processDefinitionCode", processDefinitionCode);
@ -93,7 +94,8 @@ public class ExecutorPage {
return requestClient.post(url, headers, params); return requestClient.post(url, headers, params);
} }
public HttpResponse executeTask(User loginUser, long projectCode, int processInstanceId, String startNodeList, TaskDependType taskDependType) { public HttpResponse executeTask(User loginUser, long projectCode, int processInstanceId, String startNodeList,
TaskDependType taskDependType) {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("loginUser", loginUser); params.put("loginUser", loginUser);
params.put("processInstanceId", processInstanceId); params.put("processInstanceId", processInstanceId);
@ -107,4 +109,4 @@ public class ExecutorPage {
return requestClient.post(url, headers, params); return requestClient.post(url, headers, params);
} }
} }

8
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessDefinitionPage.java

@ -25,6 +25,8 @@ import org.apache.dolphinscheduler.api.test.utils.RequestClient;
import org.apache.dolphinscheduler.common.enums.ReleaseState; import org.apache.dolphinscheduler.common.enums.ReleaseState;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.http.client.methods.CloseableHttpResponse;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -32,9 +34,6 @@ import java.util.Map;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
@Slf4j @Slf4j
@AllArgsConstructor @AllArgsConstructor
public class ProcessDefinitionPage { public class ProcessDefinitionPage {
@ -107,7 +106,8 @@ public class ProcessDefinitionPage {
return requestClient.get(url, headers, params); return requestClient.get(url, headers, params);
} }
public HttpResponse releaseProcessDefinition(User loginUser, long projectCode, long code, ReleaseState releaseState) { public HttpResponse releaseProcessDefinition(User loginUser, long projectCode, long code,
ReleaseState releaseState) {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("loginUser", loginUser); params.put("loginUser", loginUser);
params.put("code", code); params.put("code", code);

5
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessInstancePage.java

@ -19,13 +19,9 @@
package org.apache.dolphinscheduler.api.test.pages.workflow; package org.apache.dolphinscheduler.api.test.pages.workflow;
import org.apache.dolphinscheduler.api.enums.ExecuteType;
import org.apache.dolphinscheduler.api.test.core.Constants; import org.apache.dolphinscheduler.api.test.core.Constants;
import org.apache.dolphinscheduler.api.test.entity.HttpResponse; import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
import org.apache.dolphinscheduler.api.test.utils.RequestClient; import org.apache.dolphinscheduler.api.test.utils.RequestClient;
import org.apache.dolphinscheduler.common.enums.FailureStrategy;
import org.apache.dolphinscheduler.common.enums.TaskDependType;
import org.apache.dolphinscheduler.common.enums.WarningType;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import java.util.HashMap; import java.util.HashMap;
@ -34,7 +30,6 @@ import java.util.Map;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@AllArgsConstructor @AllArgsConstructor
public class ProcessInstancePage { public class ProcessInstancePage {

2
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/SchedulerPage.java

@ -30,7 +30,6 @@ import java.util.Map;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@AllArgsConstructor @AllArgsConstructor
public class SchedulerPage { public class SchedulerPage {
@ -63,7 +62,6 @@ public class SchedulerPage {
return requestClient.post(url, headers, params); return requestClient.post(url, headers, params);
} }
public HttpResponse publishScheduleOnline(User loginUser, long projectCode, int scheduleId) { public HttpResponse publishScheduleOnline(User loginUser, long projectCode, int scheduleId) {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("loginUser", loginUser); params.put("loginUser", loginUser);

10
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/JSONUtils.java

@ -17,12 +17,11 @@
package org.apache.dolphinscheduler.api.test.utils; package org.apache.dolphinscheduler.api.test.utils;
import static java.nio.charset.StandardCharsets.UTF_8;
import static com.fasterxml.jackson.databind.DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT; import static com.fasterxml.jackson.databind.DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
import static com.fasterxml.jackson.databind.DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL; import static com.fasterxml.jackson.databind.DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL;
import static com.fasterxml.jackson.databind.MapperFeature.REQUIRE_SETTERS_FOR_GETTERS; import static com.fasterxml.jackson.databind.MapperFeature.REQUIRE_SETTERS_FOR_GETTERS;
import static java.nio.charset.StandardCharsets.UTF_8;
import org.apache.dolphinscheduler.api.test.core.Constants; import org.apache.dolphinscheduler.api.test.core.Constants;
@ -72,8 +71,11 @@ public class JSONUtils {
* can use static singleton, inject: just make sure to reuse! * can use static singleton, inject: just make sure to reuse!
*/ */
private static final ObjectMapper objectMapper = private static final ObjectMapper objectMapper =
new ObjectMapper().configure(FAIL_ON_UNKNOWN_PROPERTIES, false).configure(ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true).configure(READ_UNKNOWN_ENUM_VALUES_AS_NULL, true) new ObjectMapper().configure(FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(REQUIRE_SETTERS_FOR_GETTERS, true).setTimeZone(TimeZone.getDefault()).setDateFormat(new SimpleDateFormat(Constants.YYYY_MM_DD_HH_MM_SS)); .configure(ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true)
.configure(READ_UNKNOWN_ENUM_VALUES_AS_NULL, true)
.configure(REQUIRE_SETTERS_FOR_GETTERS, true).setTimeZone(TimeZone.getDefault())
.setDateFormat(new SimpleDateFormat(Constants.YYYY_MM_DD_HH_MM_SS));
private JSONUtils() { private JSONUtils() {
throw new UnsupportedOperationException("Construct JSONUtils"); throw new UnsupportedOperationException("Construct JSONUtils");

65
dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/RequestClient.java

@ -23,6 +23,15 @@ import org.apache.dolphinscheduler.api.test.core.Constants;
import org.apache.dolphinscheduler.api.test.entity.HttpResponse; import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
import org.apache.dolphinscheduler.api.test.entity.HttpResponseBody; import org.apache.dolphinscheduler.api.test.entity.HttpResponseBody;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.util.HashMap; import java.util.HashMap;
@ -39,17 +48,6 @@ import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
@Slf4j @Slf4j
public class RequestClient { public class RequestClient {
@ -70,10 +68,10 @@ public class RequestClient {
log.info("GET request to {}, Headers: {}", requestUrl, headersBuilder); log.info("GET request to {}, Headers: {}", requestUrl, headersBuilder);
Request request = new Request.Builder() Request request = new Request.Builder()
.url(requestUrl) .url(requestUrl)
.headers(headersBuilder) .headers(headersBuilder)
.get() .get()
.build(); .build();
Response response = this.httpClient.newCall(request).execute(); Response response = this.httpClient.newCall(request).execute();
@ -121,10 +119,10 @@ public class RequestClient {
RequestBody requestBody = FormBody.create(MediaType.parse(Constants.REQUEST_CONTENT_TYPE), getParams(params)); RequestBody requestBody = FormBody.create(MediaType.parse(Constants.REQUEST_CONTENT_TYPE), getParams(params));
log.info("POST request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params); log.info("POST request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params);
Request request = new Request.Builder() Request request = new Request.Builder()
.headers(headersBuilder) .headers(headersBuilder)
.url(requestUrl) .url(requestUrl)
.post(requestBody) .post(requestBody)
.build(); .build();
Response response = this.httpClient.newCall(request).execute(); Response response = this.httpClient.newCall(request).execute();
int responseCode = response.code(); int responseCode = response.code();
HttpResponseBody responseData = null; HttpResponseBody responseData = null;
@ -152,10 +150,10 @@ public class RequestClient {
RequestBody requestBody = FormBody.create(MediaType.parse(Constants.REQUEST_CONTENT_TYPE), getParams(params)); RequestBody requestBody = FormBody.create(MediaType.parse(Constants.REQUEST_CONTENT_TYPE), getParams(params));
log.info("PUT request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params); log.info("PUT request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params);
Request request = new Request.Builder() Request request = new Request.Builder()
.headers(headersBuilder) .headers(headersBuilder)
.url(requestUrl) .url(requestUrl)
.put(requestBody) .put(requestBody)
.build(); .build();
Response response = this.httpClient.newCall(request).execute(); Response response = this.httpClient.newCall(request).execute();
int responseCode = response.code(); int responseCode = response.code();
HttpResponseBody responseData = null; HttpResponseBody responseData = null;
@ -171,17 +169,17 @@ public class RequestClient {
return httpResponse; return httpResponse;
} }
public CloseableHttpResponse postWithFile(String url, Map<String, String> headers, Map<String, Object> params, File file) { public CloseableHttpResponse postWithFile(String url, Map<String, String> headers, Map<String, Object> params,
File file) {
try { try {
Headers headersBuilder = Headers.of(headers); Headers headersBuilder = Headers.of(headers);
MultipartEntityBuilder builder = MultipartEntityBuilder.create(); MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("json", getParams(params), ContentType.MULTIPART_FORM_DATA); builder.addTextBody("json", getParams(params), ContentType.MULTIPART_FORM_DATA);
builder.addBinaryBody( builder.addBinaryBody(
"file", "file",
new FileInputStream(file), new FileInputStream(file),
ContentType.APPLICATION_OCTET_STREAM, ContentType.APPLICATION_OCTET_STREAM,
file.getName() file.getName());
);
HttpEntity multipart = builder.build(); HttpEntity multipart = builder.build();
String requestUrl = String.format("%s%s", Constants.DOLPHINSCHEDULER_API_URL, url); String requestUrl = String.format("%s%s", Constants.DOLPHINSCHEDULER_API_URL, url);
log.info("POST request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params); log.info("POST request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params);
@ -199,7 +197,6 @@ public class RequestClient {
return null; return null;
} }
@SneakyThrows @SneakyThrows
public HttpResponse delete(String url, Map<String, String> headers, Map<String, Object> params) { public HttpResponse delete(String url, Map<String, String> headers, Map<String, Object> params) {
if (headers == null) { if (headers == null) {
@ -214,10 +211,10 @@ public class RequestClient {
log.info("DELETE request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params); log.info("DELETE request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params);
Request request = new Request.Builder() Request request = new Request.Builder()
.headers(headersBuilder) .headers(headersBuilder)
.url(requestUrl) .url(requestUrl)
.delete() .delete()
.build(); .build();
Response response = this.httpClient.newCall(request).execute(); Response response = this.httpClient.newCall(request).execute();

1
dolphinscheduler-api-test/dolphinscheduler-api-test-core/src/main/java/org/apache/dolphinscheduler/api/test/core/DolphinScheduler.java

@ -37,5 +37,6 @@ import org.testcontainers.junit.jupiter.Testcontainers;
@TestMethodOrder(OrderAnnotation.class) @TestMethodOrder(OrderAnnotation.class)
@ExtendWith(DolphinSchedulerExtension.class) @ExtendWith(DolphinSchedulerExtension.class)
public @interface DolphinScheduler { public @interface DolphinScheduler {
String[] composeFiles(); String[] composeFiles();
} }

10
dolphinscheduler-api-test/dolphinscheduler-api-test-core/src/main/java/org/apache/dolphinscheduler/api/test/core/DolphinSchedulerExtension.java

@ -24,22 +24,21 @@ import java.net.URL;
import java.time.Duration; import java.time.Duration;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.ContainerState;
import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.DockerComposeContainer;
import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.containers.wait.strategy.Wait;
import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCallback { final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCallback {
private final boolean localMode = Objects.equals(System.getProperty("local"), "true"); private final boolean localMode = Objects.equals(System.getProperty("local"), "true");
private final String serviceName = "dolphinscheduler_1"; private final String serviceName = "dolphinscheduler_1";
@ -78,7 +77,8 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
.withPull(true) .withPull(true)
.withTailChildContainers(true) .withTailChildContainers(true)
.withLogConsumer(serviceName, outputFrame -> log.info(outputFrame.getUtf8String())) .withLogConsumer(serviceName, outputFrame -> log.info(outputFrame.getUtf8String()))
.waitingFor(serviceName, Wait.forHealthcheck().withStartupTimeout(Duration.ofSeconds(Constants.DOCKER_COMPOSE_DEFAULT_TIMEOUT))); .waitingFor(serviceName, Wait.forHealthcheck()
.withStartupTimeout(Duration.ofSeconds(Constants.DOCKER_COMPOSE_DEFAULT_TIMEOUT)));
return compose; return compose;
} }

219
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClickhouseDataSourceE2ETest.java

@ -1,112 +1,107 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information * distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
* *
*/ */
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import java.time.Duration; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll; import org.openqa.selenium.By;
import org.junit.jupiter.api.Order; import org.openqa.selenium.WebElement;
import org.junit.jupiter.api.Test; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.By; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.WebElement; import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions; @DolphinScheduler(composeFiles = "docker/datasource-clickhouse/docker-compose.yaml")
import org.openqa.selenium.support.ui.WebDriverWait; public class ClickhouseDataSourceE2ETest {
private static RemoteWebDriver browser;
@DolphinScheduler(composeFiles = "docker/datasource-clickhouse/docker-compose.yaml")
public class ClickhouseDataSourceE2ETest { private static final String tenant = System.getProperty("user.name");
private static RemoteWebDriver browser;
private static final String user = "admin";
private static final String tenant = System.getProperty("user.name");
private static final String password = "dolphinscheduler123";
private static final String user = "admin";
private static final String dataSourceType = "CLICKHOUSE";
private static final String password = "dolphinscheduler123";
private static final String dataSourceName = "clickhouse_test";
private static final String dataSourceType = "CLICKHOUSE";
private static final String dataSourceDescription = "clickhouse_test";
private static final String dataSourceName = "clickhouse_test";
private static final String ip = "clickhouse";
private static final String dataSourceDescription = "clickhouse_test";
private static final String port = "8123";
private static final String ip = "clickhouse";
private static final String userName = "ch_test";
private static final String port = "8123";
private static final String pgPassword = "ch_test";
private static final String userName = "ch_test";
private static final String database = "ch_test";
private static final String pgPassword = "ch_test";
private static final String jdbcParams = "";
private static final String database = "ch_test";
@BeforeAll
private static final String jdbcParams = ""; public static void setup() {
new LoginPage(browser)
.login(user, password)
@BeforeAll .goToNav(DataSourcePage.class);
public static void setup() { }
new LoginPage(browser)
.login(user, password) @Test
.goToNav(DataSourcePage.class); @Order(10)
} void testCreateClickhouseDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
@Test
@Order(10) page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword,
void testCreateClickhouseDataSource() { database, jdbcParams);
final DataSourcePage page = new DataSourcePage(browser);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams); new By.ByClassName("dialog-create-data-source")));
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
new By.ByClassName("dialog-create-data-source"))); .as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) .anyMatch(it -> it.contains(dataSourceName)));
.as("DataSource list should contain newly-created database") }
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName))); @Test
} @Order(20)
void testDeleteClickhouseDataSource() {
@Test final DataSourcePage page = new DataSourcePage(browser);
@Order(20)
void testDeleteClickhouseDataSource() { page.delete(dataSourceName);
final DataSourcePage page = new DataSourcePage(browser);
Awaitility.await().untilAsserted(() -> {
page.delete(dataSourceName); browser.navigate().refresh();
Awaitility.await().untilAsserted(() -> { assertThat(
browser.navigate().refresh(); page.dataSourceItemsList()).noneMatch(
it -> it.getText().contains(dataSourceName));
assertThat( });
page.dataSourceItemsList() }
).noneMatch( }
it -> it.getText().contains(dataSourceName)
);
});
}
}

22
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClusterE2ETest.java

@ -19,7 +19,6 @@
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
@ -27,13 +26,13 @@ import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.security.ClusterPage; import org.apache.dolphinscheduler.e2e.pages.security.ClusterPage;
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
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.By;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class ClusterE2ETest { class ClusterE2ETest {
@ -53,8 +52,7 @@ class ClusterE2ETest {
new LoginPage(browser) new LoginPage(browser)
.login("admin", "dolphinscheduler123") .login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class) .goToNav(SecurityPage.class)
.goToTab(ClusterPage.class) .goToTab(ClusterPage.class);
;
} }
@Test @Test
@ -78,10 +76,8 @@ class ClusterE2ETest {
final ClusterPage page = new ClusterPage(browser); final ClusterPage page = new ClusterPage(browser);
page.create(clusterName, clusterConfig, clusterDesc); page.create(clusterName, clusterConfig, clusterDesc);
Awaitility.await().untilAsserted(() -> Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
assertThat(browser.findElement(By.tagName("body")).getText()) .contains("already exists"));
.contains("already exists")
);
page.createClusterForm().buttonCancel().click(); page.createClusterForm().buttonCancel().click();
} }
@ -112,12 +108,10 @@ class ClusterE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat( assertThat(
page.clusterList() page.clusterList())
) .as("Cluster list should not contain deleted cluster")
.as("Cluster list should not contain deleted cluster") .noneMatch(
.noneMatch( it -> it.getText().contains(clusterName) || it.getText().contains(editClusterName));
it -> it.getText().contains(clusterName) || it.getText().contains(editClusterName)
);
}); });
} }
} }

26
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/EnvironmentE2ETest.java

@ -19,7 +19,6 @@
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
@ -27,13 +26,13 @@ import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.security.EnvironmentPage; import org.apache.dolphinscheduler.e2e.pages.security.EnvironmentPage;
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
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.By;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class EnvironmentE2ETest { class EnvironmentE2ETest {
@ -55,8 +54,7 @@ class EnvironmentE2ETest {
new LoginPage(browser) new LoginPage(browser)
.login("admin", "dolphinscheduler123") .login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class) .goToNav(SecurityPage.class)
.goToTab(EnvironmentPage.class) .goToTab(EnvironmentPage.class);
;
} }
@Test @Test
@ -80,10 +78,8 @@ class EnvironmentE2ETest {
final EnvironmentPage page = new EnvironmentPage(browser); final EnvironmentPage page = new EnvironmentPage(browser);
page.create(environmentName, environmentConfig, environmentDesc, environmentWorkerGroup); page.create(environmentName, environmentConfig, environmentDesc, environmentWorkerGroup);
Awaitility.await().untilAsserted(() -> Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
assertThat(browser.findElement(By.tagName("body")).getText()) .contains("already exists"));
.contains("already exists")
);
page.createEnvironmentForm().buttonCancel().click(); page.createEnvironmentForm().buttonCancel().click();
} }
@ -92,7 +88,8 @@ class EnvironmentE2ETest {
@Order(30) @Order(30)
void testEditEnvironment() { void testEditEnvironment() {
final EnvironmentPage page = new EnvironmentPage(browser); final EnvironmentPage page = new EnvironmentPage(browser);
page.update(environmentName, editEnvironmentName, editEnvironmentConfig, editEnvironmentDesc, editEnvironmentWorkerGroup); page.update(environmentName, editEnvironmentName, editEnvironmentConfig, editEnvironmentDesc,
editEnvironmentWorkerGroup);
Awaitility.await().untilAsserted(() -> { Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh(); browser.navigate().refresh();
@ -114,12 +111,11 @@ class EnvironmentE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat( assertThat(
page.environmentList() page.environmentList())
) .as("Environment list should not contain deleted environment")
.as("Environment list should not contain deleted environment") .noneMatch(
.noneMatch( it -> it.getText().contains(environmentName)
it -> it.getText().contains(environmentName) || it.getText().contains(editEnvironmentName) || it.getText().contains(editEnvironmentName));
);
}); });
} }
} }

169
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java

@ -19,7 +19,6 @@
*/ */
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.Constants; import org.apache.dolphinscheduler.e2e.core.Constants;
@ -37,10 +36,10 @@ import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.Duration;
import java.util.Comparator; import java.util.Comparator;
import org.testcontainers.shaded.org.awaitility.Awaitility; import lombok.SneakyThrows;
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;
@ -49,12 +48,11 @@ import org.openqa.selenium.By;
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.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait; import org.testcontainers.shaded.org.awaitility.Awaitility;
import lombok.SneakyThrows;
@DolphinScheduler(composeFiles = "docker/file-manage/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/file-manage/docker-compose.yaml")
public class FileManageE2ETest { public class FileManageE2ETest {
private static RemoteWebDriver browser; private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name"); private static final String tenant = System.getProperty("user.name");
@ -92,19 +90,19 @@ public class FileManageE2ETest {
.create(tenant); .create(tenant);
Awaitility.await().untilAsserted(() -> assertThat(tenantPage.tenantList()) Awaitility.await().untilAsserted(() -> assertThat(tenantPage.tenantList())
.as("Tenant list should contain newly-created tenant") .as("Tenant list should contain newly-created tenant")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant))); .anyMatch(it -> it.contains(tenant)));
UserPage userPage = tenantPage.goToNav(SecurityPage.class) UserPage userPage = tenantPage.goToNav(SecurityPage.class)
.goToTab(UserPage.class); .goToTab(UserPage.class);
WebDriverWaitFactory.createWebDriverWait(userPage.driver()).until(ExpectedConditions.visibilityOfElementLocated( WebDriverWaitFactory.createWebDriverWait(userPage.driver()).until(ExpectedConditions.visibilityOfElementLocated(
new By.ByClassName("name"))); new By.ByClassName("name")));
userPage.update(user, user, email, phone, tenant) userPage.update(user, user, email, phone, tenant)
.goToNav(ResourcePage.class) .goToNav(ResourcePage.class)
.goToTab(FileManagePage.class); .goToTab(FileManagePage.class);
} }
@AfterAll @AfterAll
@ -113,9 +111,9 @@ public class FileManageE2ETest {
Files.deleteIfExists(testUnder1GBFilePath); Files.deleteIfExists(testUnder1GBFilePath);
Files.deleteIfExists(testOver1GBFilePath); Files.deleteIfExists(testOver1GBFilePath);
Files.walk(Constants.HOST_CHROME_DOWNLOAD_PATH) Files.walk(Constants.HOST_CHROME_DOWNLOAD_PATH)
.sorted(Comparator.reverseOrder()) .sorted(Comparator.reverseOrder())
.map(Path::toFile) .map(Path::toFile)
.forEach(File::delete); .forEach(File::delete);
} }
@Test @Test
@ -139,57 +137,57 @@ public class FileManageE2ETest {
page.cancelCreateDirectory(testDirectoryName); page.cancelCreateDirectory(testDirectoryName);
Awaitility.await().untilAsserted(() -> assertThat(page.fileList()) Awaitility.await().untilAsserted(() -> assertThat(page.fileList())
.as("File list should contain newly-created file") .as("File list should contain newly-created file")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(testDirectoryName))); .anyMatch(it -> it.contains(testDirectoryName)));
} }
// @Test // @Test
// @Order(20) // @Order(20)
// void testCreateDuplicateDirectory() { // void testCreateDuplicateDirectory() {
// final FileManagePage page = new FileManagePage(browser); // final FileManagePage page = new FileManagePage(browser);
// //
// page.createDirectory(testDirectoryName, "test_desc"); // page.createDirectory(testDirectoryName, "test_desc");
// //
// await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText()) // await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
// .contains("resource already exists") // .contains("resource already exists")
// ); // );
// //
// page.createDirectoryBox().buttonCancel().click(); // page.createDirectoryBox().buttonCancel().click();
// } // }
// @Test // @Test
// @Order(21) // @Order(21)
// void testCreateSubDirectory() { // void testCreateSubDirectory() {
// final FileManagePage page = new FileManagePage(browser); // final FileManagePage page = new FileManagePage(browser);
// //
// page.createSubDirectory(testDirectoryName, testSubDirectoryName, "test_desc"); // page.createSubDirectory(testDirectoryName, testSubDirectoryName, "test_desc");
// //
// await().untilAsserted(() -> assertThat(page.fileList()) // await().untilAsserted(() -> assertThat(page.fileList())
// .as("File list should contain newly-created file") // .as("File list should contain newly-created file")
// .extracting(WebElement::getText) // .extracting(WebElement::getText)
// .anyMatch(it -> it.contains(testSubDirectoryName))); // .anyMatch(it -> it.contains(testSubDirectoryName)));
// } // }
/* /*
* when the storage is s3,the directory cannot be renamed * when the storage is s3,the directory cannot be renamed
* */ */
// @Test // @Test
// @Order(22) // @Order(22)
// void testRenameDirectory() { // void testRenameDirectory() {
// final FileManagePage page = new FileManagePage(browser); // final FileManagePage page = new FileManagePage(browser);
// //
// page.rename(testDirectoryName, testRenameDirectoryName); // page.rename(testDirectoryName, testRenameDirectoryName);
// //
// await().untilAsserted(() -> { // await().untilAsserted(() -> {
// browser.navigate().refresh(); // browser.navigate().refresh();
// //
// assertThat(page.fileList()) // assertThat(page.fileList())
// .as("File list should contain newly-created file") // .as("File list should contain newly-created file")
// .extracting(WebElement::getText) // .extracting(WebElement::getText)
// .anyMatch(it -> it.contains(testRenameDirectoryName)); // .anyMatch(it -> it.contains(testRenameDirectoryName));
// }); // });
// } // }
@Test @Test
@Order(30) @Order(30)
@ -197,17 +195,15 @@ public class FileManageE2ETest {
final FileManagePage page = new FileManagePage(browser); final FileManagePage page = new FileManagePage(browser);
page.goToNav(ResourcePage.class) page.goToNav(ResourcePage.class)
.goToTab(FileManagePage.class) .goToTab(FileManagePage.class)
.delete(testDirectoryName); .delete(testDirectoryName);
Awaitility.await().untilAsserted(() -> { Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat( assertThat(
page.fileList() page.fileList()).noneMatch(
).noneMatch( it -> it.getText().contains(testDirectoryName));
it -> it.getText().contains(testDirectoryName)
);
}); });
} }
@ -220,9 +216,9 @@ public class FileManageE2ETest {
page.createFile(testFileName, scripts); page.createFile(testFileName, scripts);
Awaitility.await().untilAsserted(() -> assertThat(page.fileList()) Awaitility.await().untilAsserted(() -> assertThat(page.fileList())
.as("File list should contain newly-created file") .as("File list should contain newly-created file")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(testFileName))); .anyMatch(it -> it.contains(testFileName)));
} }
@Test @Test
@ -236,9 +232,9 @@ public class FileManageE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat(page.fileList()) assertThat(page.fileList())
.as("File list should contain newly-created file") .as("File list should contain newly-created file")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(testRenameFileName)); .anyMatch(it -> it.contains(testRenameFileName));
}); });
} }
@ -251,9 +247,9 @@ public class FileManageE2ETest {
page.editFile(testRenameFileName, scripts); page.editFile(testRenameFileName, scripts);
Awaitility.await().untilAsserted(() -> assertThat(page.fileList()) Awaitility.await().untilAsserted(() -> assertThat(page.fileList())
.as("File list should contain newly-created file") .as("File list should contain newly-created file")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(testRenameFileName))); .anyMatch(it -> it.contains(testRenameFileName)));
} }
@Test @Test
@ -267,10 +263,8 @@ public class FileManageE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat( assertThat(
page.fileList() page.fileList()).noneMatch(
).noneMatch( it -> it.getText().contains(testRenameFileName));
it -> it.getText().contains(testRenameFileName)
);
}); });
} }
@ -286,13 +280,14 @@ public class FileManageE2ETest {
page.uploadFile(testUnder1GBFilePath.toFile().getAbsolutePath()); page.uploadFile(testUnder1GBFilePath.toFile().getAbsolutePath());
WebDriverWaitFactory.createWebDriverWait(browser).until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog"))); WebDriverWaitFactory.createWebDriverWait(browser)
.until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog")));
Awaitility.await().untilAsserted(() -> { Awaitility.await().untilAsserted(() -> {
assertThat(page.fileList()) assertThat(page.fileList())
.as("File list should contain newly-created file") .as("File list should contain newly-created file")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(testUnder1GBFileName)); .anyMatch(it -> it.contains(testUnder1GBFileName));
}); });
} }

24
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java

@ -27,8 +27,6 @@ import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import java.time.Duration;
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;
@ -36,11 +34,11 @@ import org.openqa.selenium.By;
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.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testcontainers.shaded.org.awaitility.Awaitility; import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/datasource-hive/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/datasource-hive/docker-compose.yaml")
public class HiveDataSourceE2ETest { public class HiveDataSourceE2ETest {
private static RemoteWebDriver browser; private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name"); private static final String tenant = System.getProperty("user.name");
@ -70,9 +68,8 @@ public class HiveDataSourceE2ETest {
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
new LoginPage(browser) new LoginPage(browser)
.login(user, password) .login(user, password)
.goToNav(DataSourcePage.class); .goToNav(DataSourcePage.class);
} }
@ -81,15 +78,16 @@ public class HiveDataSourceE2ETest {
void testCreateHiveDataSource() { void testCreateHiveDataSource() {
final DataSourcePage page = new DataSourcePage(browser); final DataSourcePage page = new DataSourcePage(browser);
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, hivePassword, database, jdbcParams); page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, hivePassword,
database, jdbcParams);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
new By.ByClassName("dialog-create-data-source"))); new By.ByClassName("dialog-create-data-source")));
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
.as("DataSource list should contain newly-created database") .as("DataSource list should contain newly-created database")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName))); .anyMatch(it -> it.contains(dataSourceName)));
} }
@Test @Test
@ -103,10 +101,8 @@ public class HiveDataSourceE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat( assertThat(
page.dataSourceItemsList() page.dataSourceItemsList()).noneMatch(
).noneMatch( it -> it.getText().contains(dataSourceName));
it -> it.getText().contains(dataSourceName)
);
}); });
} }
} }

221
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/MysqlDataSourceE2ETest.java

@ -1,113 +1,108 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information * distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
* *
*/ */
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import java.time.Duration; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll; import org.openqa.selenium.By;
import org.junit.jupiter.api.Order; import org.openqa.selenium.WebElement;
import org.junit.jupiter.api.Test; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.By; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.WebElement; import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions; @DolphinScheduler(composeFiles = "docker/datasource-mysql/docker-compose.yaml")
import org.openqa.selenium.support.ui.WebDriverWait; public class MysqlDataSourceE2ETest {
private static RemoteWebDriver browser;
@DolphinScheduler(composeFiles = "docker/datasource-mysql/docker-compose.yaml")
public class MysqlDataSourceE2ETest { private static final String tenant = System.getProperty("user.name");
private static RemoteWebDriver browser;
private static final String user = "admin";
private static final String tenant = System.getProperty("user.name");
private static final String password = "dolphinscheduler123";
private static final String user = "admin";
private static final String dataSourceType = "MYSQL";
private static final String password = "dolphinscheduler123";
private static final String dataSourceName = "mysql_test";
private static final String dataSourceType = "MYSQL";
private static final String dataSourceDescription = "mysql_test";
private static final String dataSourceName = "mysql_test";
private static final String ip = "mysql";
private static final String dataSourceDescription = "mysql_test";
private static final String port = "3306";
private static final String ip = "mysql";
private static final String userName = "root";
private static final String port = "3306";
private static final String mysqlPassword = "123456";
private static final String userName = "root";
private static final String database = "mysql";
private static final String mysqlPassword = "123456";
private static final String jdbcParams = "{\"useSSL\": false}";
private static final String database = "mysql";
@BeforeAll
private static final String jdbcParams = "{\"useSSL\": false}"; public static void setup() {
new LoginPage(browser)
.login(user, password)
@BeforeAll .goToNav(DataSourcePage.class);
public static void setup() { }
new LoginPage(browser)
.login(user, password) @Test
.goToNav(DataSourcePage.class); @Order(10)
} void testCreateMysqlDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
@Test
@Order(10) page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, mysqlPassword,
void testCreateMysqlDataSource() { database, jdbcParams);
final DataSourcePage page = new DataSourcePage(browser);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, mysqlPassword, database, jdbcParams); new By.ByClassName("dialog-create-data-source")));
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
new By.ByClassName("dialog-create-data-source"))); .as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) .anyMatch(it -> it.contains(dataSourceName)));
.as("DataSource list should contain newly-created database") }
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName))); @Test
} @Order(20)
void testDeleteMysqlDataSource() {
@Test final DataSourcePage page = new DataSourcePage(browser);
@Order(20)
void testDeleteMysqlDataSource() { page.delete(dataSourceName);
final DataSourcePage page = new DataSourcePage(browser);
Awaitility.await().untilAsserted(() -> {
page.delete(dataSourceName); browser.navigate().refresh();
Awaitility.await().untilAsserted(() -> { assertThat(
browser.navigate().refresh(); page.dataSourceItemsList()).noneMatch(
it -> it.getText().contains(dataSourceName));
assertThat( });
page.dataSourceItemsList() }
).noneMatch(
it -> it.getText().contains(dataSourceName) }
);
});
}
}

219
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/PostgresDataSourceE2ETest.java

@ -1,112 +1,107 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information * distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
* *
*/ */
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import java.time.Duration; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll; import org.openqa.selenium.By;
import org.junit.jupiter.api.Order; import org.openqa.selenium.WebElement;
import org.junit.jupiter.api.Test; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.By; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.WebElement; import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions; @DolphinScheduler(composeFiles = "docker/datasource-postgresql/docker-compose.yaml")
import org.openqa.selenium.support.ui.WebDriverWait; public class PostgresDataSourceE2ETest {
private static RemoteWebDriver browser;
@DolphinScheduler(composeFiles = "docker/datasource-postgresql/docker-compose.yaml")
public class PostgresDataSourceE2ETest { private static final String tenant = System.getProperty("user.name");
private static RemoteWebDriver browser;
private static final String user = "admin";
private static final String tenant = System.getProperty("user.name");
private static final String password = "dolphinscheduler123";
private static final String user = "admin";
private static final String dataSourceType = "POSTGRESQL";
private static final String password = "dolphinscheduler123";
private static final String dataSourceName = "postgres_test";
private static final String dataSourceType = "POSTGRESQL";
private static final String dataSourceDescription = "postgres_test";
private static final String dataSourceName = "postgres_test";
private static final String ip = "postgres";
private static final String dataSourceDescription = "postgres_test";
private static final String port = "5432";
private static final String ip = "postgres";
private static final String userName = "postgres";
private static final String port = "5432";
private static final String pgPassword = "postgres";
private static final String userName = "postgres";
private static final String database = "postgres";
private static final String pgPassword = "postgres";
private static final String jdbcParams = "";
private static final String database = "postgres";
@BeforeAll
private static final String jdbcParams = ""; public static void setup() {
new LoginPage(browser)
.login(user, password)
@BeforeAll .goToNav(DataSourcePage.class);
public static void setup() { }
new LoginPage(browser)
.login(user, password) @Test
.goToNav(DataSourcePage.class); @Order(10)
} void testCreatePostgresDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
@Test
@Order(10) page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword,
void testCreatePostgresDataSource() { database, jdbcParams);
final DataSourcePage page = new DataSourcePage(browser);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams); new By.ByClassName("dialog-create-data-source")));
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
new By.ByClassName("dialog-create-data-source"))); .as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) .anyMatch(it -> it.contains(dataSourceName)));
.as("DataSource list should contain newly-created database") }
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName))); @Test
} @Order(20)
void testDeletePostgresDataSource() {
@Test final DataSourcePage page = new DataSourcePage(browser);
@Order(20)
void testDeletePostgresDataSource() { page.delete(dataSourceName);
final DataSourcePage page = new DataSourcePage(browser);
Awaitility.await().untilAsserted(() -> {
page.delete(dataSourceName); browser.navigate().refresh();
Awaitility.await().untilAsserted(() -> { assertThat(
browser.navigate().refresh(); page.dataSourceItemsList()).noneMatch(
it -> it.getText().contains(dataSourceName));
assertThat( });
page.dataSourceItemsList() }
).noneMatch( }
it -> it.getText().contains(dataSourceName)
);
});
}
}

9
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ProjectE2ETest.java

@ -25,14 +25,15 @@ import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
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.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class ProjectE2ETest { class ProjectE2ETest {
private static final String project = "test-project-1"; private static final String project = "test-project-1";
private static RemoteWebDriver browser; private static RemoteWebDriver browser;
@ -59,10 +60,8 @@ class ProjectE2ETest {
Awaitility.await().untilAsserted(() -> { Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat( assertThat(
page.projectList() page.projectList()).noneMatch(
).noneMatch( it -> it.getText().contains(project));
it -> it.getText().contains(project)
);
}); });
} }
} }

12
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/QueueE2ETest.java

@ -19,7 +19,6 @@
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
@ -27,13 +26,13 @@ import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.security.QueuePage; import org.apache.dolphinscheduler.e2e.pages.security.QueuePage;
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
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.By;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class QueueE2ETest { class QueueE2ETest {
@ -50,8 +49,7 @@ class QueueE2ETest {
new LoginPage(browser) new LoginPage(browser)
.login("admin", "dolphinscheduler123") .login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class) .goToNav(SecurityPage.class)
.goToTab(QueuePage.class) .goToTab(QueuePage.class);
;
} }
@Test @Test
@ -75,10 +73,8 @@ class QueueE2ETest {
final QueuePage page = new QueuePage(browser); final QueuePage page = new QueuePage(browser);
page.create(queueName, queueValue); page.create(queueName, queueValue);
Awaitility.await().untilAsserted(() -> Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
assertThat(browser.findElement(By.tagName("body")).getText()) .contains("already exists"));
.contains("already exists")
);
page.createQueueForm().buttonCancel().click(); page.createQueueForm().buttonCancel().click();
} }

219
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/SqlServerDataSourceE2ETest.java

@ -1,112 +1,107 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information * distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
* *
*/ */
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import java.time.Duration; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll; import org.openqa.selenium.By;
import org.junit.jupiter.api.Order; import org.openqa.selenium.WebElement;
import org.junit.jupiter.api.Test; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.By; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.WebElement; import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions; @DolphinScheduler(composeFiles = "docker/datasource-sqlserver/docker-compose.yaml")
import org.openqa.selenium.support.ui.WebDriverWait; public class SqlServerDataSourceE2ETest {
private static RemoteWebDriver browser;
@DolphinScheduler(composeFiles = "docker/datasource-sqlserver/docker-compose.yaml")
public class SqlServerDataSourceE2ETest { private static final String tenant = System.getProperty("user.name");
private static RemoteWebDriver browser;
private static final String user = "admin";
private static final String tenant = System.getProperty("user.name");
private static final String password = "dolphinscheduler123";
private static final String user = "admin";
private static final String dataSourceType = "SQLSERVER";
private static final String password = "dolphinscheduler123";
private static final String dataSourceName = "sqlserver_test";
private static final String dataSourceType = "SQLSERVER";
private static final String dataSourceDescription = "sqlserver_test";
private static final String dataSourceName = "sqlserver_test";
private static final String ip = "sqlserver";
private static final String dataSourceDescription = "sqlserver_test";
private static final String port = "1433";
private static final String ip = "sqlserver";
private static final String userName = "sa";
private static final String port = "1433";
private static final String pgPassword = "OcP2020123";
private static final String userName = "sa";
private static final String database = "master";
private static final String pgPassword = "OcP2020123";
private static final String jdbcParams = "";
private static final String database = "master";
@BeforeAll
private static final String jdbcParams = ""; public static void setup() {
new LoginPage(browser)
.login(user, password)
@BeforeAll .goToNav(DataSourcePage.class);
public static void setup() { }
new LoginPage(browser)
.login(user, password) @Test
.goToNav(DataSourcePage.class); @Order(10)
} void testCreateSqlServerDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
@Test
@Order(10) page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword,
void testCreateSqlServerDataSource() { database, jdbcParams);
final DataSourcePage page = new DataSourcePage(browser);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams); new By.ByClassName("dialog-create-data-source")));
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
new By.ByClassName("dialog-create-data-source"))); .as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) .anyMatch(it -> it.contains(dataSourceName)));
.as("DataSource list should contain newly-created database") }
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName))); @Test
} @Order(20)
void testDeleteSqlServerDataSource() {
@Test final DataSourcePage page = new DataSourcePage(browser);
@Order(20)
void testDeleteSqlServerDataSource() { page.delete(dataSourceName);
final DataSourcePage page = new DataSourcePage(browser);
Awaitility.await().untilAsserted(() -> {
page.delete(dataSourceName); browser.navigate().refresh();
Awaitility.await().untilAsserted(() -> { assertThat(
browser.navigate().refresh(); page.dataSourceItemsList()).noneMatch(
it -> it.getText().contains(dataSourceName));
assertThat( });
page.dataSourceItemsList() }
).noneMatch( }
it -> it.getText().contains(dataSourceName)
);
});
}
}

34
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TenantE2ETest.java

@ -26,16 +26,17 @@ import org.apache.dolphinscheduler.e2e.pages.LoginPage;
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.testcontainers.shaded.org.awaitility.Awaitility;
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.By;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class TenantE2ETest { class TenantE2ETest {
private static final String tenant = System.getProperty("user.name"); private static final String tenant = System.getProperty("user.name");
private static final String editDescription = "This is a test"; private static final String editDescription = "This is a test";
@ -44,10 +45,9 @@ class TenantE2ETest {
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
new LoginPage(browser) new LoginPage(browser)
.login("admin", "dolphinscheduler123") .login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class) .goToNav(SecurityPage.class)
.goToTab(TenantPage.class) .goToTab(TenantPage.class);
;
} }
@Test @Test
@ -57,9 +57,9 @@ class TenantE2ETest {
page.create(tenant); page.create(tenant);
Awaitility.await().untilAsserted(() -> assertThat(page.tenantList()) Awaitility.await().untilAsserted(() -> assertThat(page.tenantList())
.as("Tenant list should contain newly-created tenant") .as("Tenant list should contain newly-created tenant")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant))); .anyMatch(it -> it.contains(tenant)));
} }
@Test @Test
@ -69,10 +69,8 @@ class TenantE2ETest {
page.create(tenant); page.create(tenant);
Awaitility.await().untilAsserted(() -> Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
assertThat(browser.findElement(By.tagName("body")).getText()) .contains("already exists"));
.contains("already exists")
);
page.tenantForm().buttonCancel().click(); page.tenantForm().buttonCancel().click();
} }
@ -87,9 +85,9 @@ class TenantE2ETest {
Awaitility.await().untilAsserted(() -> { Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat(page.tenantList()) assertThat(page.tenantList())
.as("Tenant list should contain newly-modified tenant") .as("Tenant list should contain newly-modified tenant")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant)); .anyMatch(it -> it.contains(tenant));
}); });
} }
@ -103,10 +101,8 @@ class TenantE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat( assertThat(
page.tenantList() page.tenantList()).noneMatch(
).noneMatch( it -> it.getText().contains(tenant));
it -> it.getText().contains(tenant)
);
}); });
} }
} }

23
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TokenE2ETest.java

@ -26,12 +26,12 @@ import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage;
import org.apache.dolphinscheduler.e2e.pages.security.TokenPage; import org.apache.dolphinscheduler.e2e.pages.security.TokenPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
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.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
public class TokenE2ETest { public class TokenE2ETest {
@ -43,10 +43,9 @@ public class TokenE2ETest {
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
new LoginPage(browser) new LoginPage(browser)
.login("admin", "dolphinscheduler123") .login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class) .goToNav(SecurityPage.class)
.goToTab(TokenPage.class) .goToTab(TokenPage.class);
;
} }
@Test @Test
@ -59,9 +58,9 @@ public class TokenE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat(page.tokenList()) assertThat(page.tokenList())
.as("Token list should contain newly-created token") .as("Token list should contain newly-created token")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(userName)); .anyMatch(it -> it.contains(userName));
}); });
} }
@ -76,9 +75,9 @@ public class TokenE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat(page.tokenList()) assertThat(page.tokenList())
.as("Token list should contain newly-modified token") .as("Token list should contain newly-modified token")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.isNotEqualTo(oldToken); .isNotEqualTo(oldToken);
}); });
} }
@ -92,7 +91,7 @@ public class TokenE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat(page.tokenList()) assertThat(page.tokenList())
.noneMatch(it -> it.getText().contains(userName)); .noneMatch(it -> it.getText().contains(userName));
}); });
} }

39
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java

@ -19,7 +19,6 @@
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
@ -30,9 +29,6 @@ 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.apache.dolphinscheduler.e2e.pages.security.UserPage;
import java.time.Duration;
import org.testcontainers.shaded.org.awaitility.Awaitility;
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;
@ -41,10 +37,11 @@ import org.openqa.selenium.By;
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.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait; import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class UserE2ETest { class UserE2ETest {
private static final String tenant = System.getProperty("user.name"); private static final String tenant = System.getProperty("user.name");
private static final String user = "test_user"; private static final String user = "test_user";
private static final String password = "testUser123"; private static final String password = "testUser123";
@ -78,9 +75,9 @@ class UserE2ETest {
@AfterAll @AfterAll
public static void cleanup() { public static void cleanup() {
new NavBarPage(browser) new NavBarPage(browser)
.goToNav(SecurityPage.class) .goToNav(SecurityPage.class)
.goToTab(TenantPage.class) .goToTab(TenantPage.class)
.delete(tenant); .delete(tenant);
} }
@Test @Test
@ -94,9 +91,9 @@ class UserE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat(page.userList()) assertThat(page.userList())
.as("User list should contain newly-created user") .as("User list should contain newly-created user")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(user)); .anyMatch(it -> it.contains(user));
}); });
} }
@ -107,10 +104,8 @@ class UserE2ETest {
page.create(user, password, email, phone, tenant); page.create(user, password, email, phone, tenant);
Awaitility.await().untilAsserted(() -> Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
assertThat(browser.findElement(By.tagName("body")).getText()) .contains("already exists"));
.contains("already exists")
);
page.createUserForm().buttonCancel().click(); page.createUserForm().buttonCancel().click();
} }
@ -130,12 +125,12 @@ class UserE2ETest {
Awaitility.await().untilAsserted(() -> { Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat(page.userList()) assertThat(page.userList())
.as("User list should contain newly-modified User") .as("User list should contain newly-modified User")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(editUser)); .anyMatch(it -> it.contains(editUser));
}); });
} }
@Test @Test
@Order(40) @Order(40)
void testDeleteUser() { void testDeleteUser() {
@ -147,10 +142,8 @@ class UserE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat( assertThat(
page.userList() page.userList()).noneMatch(
).noneMatch( it -> it.getText().contains(user) || it.getText().contains(editUser));
it -> it.getText().contains(user) || it.getText().contains(editUser)
);
}); });
} }
} }

40
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java

@ -19,7 +19,6 @@
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
@ -28,9 +27,6 @@ import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage;
import org.apache.dolphinscheduler.e2e.pages.security.WorkerGroupPage; import org.apache.dolphinscheduler.e2e.pages.security.WorkerGroupPage;
import java.time.Duration;
import org.testcontainers.shaded.org.awaitility.Awaitility;
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;
@ -38,10 +34,11 @@ import org.openqa.selenium.By;
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.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait; import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class WorkerGroupE2ETest { class WorkerGroupE2ETest {
private static final String workerGroupName = "test_worker_group"; private static final String workerGroupName = "test_worker_group";
private static final String editWorkerGroupName = "edit_worker_group"; private static final String editWorkerGroupName = "edit_worker_group";
@ -50,9 +47,9 @@ class WorkerGroupE2ETest {
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
new LoginPage(browser) new LoginPage(browser)
.login("admin", "dolphinscheduler123") .login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class) .goToNav(SecurityPage.class)
.goToTab(WorkerGroupPage.class); .goToTab(WorkerGroupPage.class);
} }
@Test @Test
@ -61,7 +58,7 @@ class WorkerGroupE2ETest {
final WorkerGroupPage page = new WorkerGroupPage(browser); final WorkerGroupPage page = new WorkerGroupPage(browser);
WebDriverWaitFactory.createWebDriverWait(page.driver()) WebDriverWaitFactory.createWebDriverWait(page.driver())
.until(ExpectedConditions.urlContains("/security/worker-group-manage")); .until(ExpectedConditions.urlContains("/security/worker-group-manage"));
page.create(workerGroupName); page.create(workerGroupName);
@ -69,9 +66,9 @@ class WorkerGroupE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat(page.workerGroupList()) assertThat(page.workerGroupList())
.as("workerGroup list should contain newly-created workerGroup") .as("workerGroup list should contain newly-created workerGroup")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(workerGroupName)); .anyMatch(it -> it.contains(workerGroupName));
}); });
} }
@ -82,10 +79,8 @@ class WorkerGroupE2ETest {
page.create(workerGroupName); page.create(workerGroupName);
Awaitility.await().untilAsserted(() -> Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
assertThat(browser.findElement(By.tagName("body")).getText()) .contains("already exists"));
.contains("already exists")
);
page.createWorkerForm().buttonCancel().click(); page.createWorkerForm().buttonCancel().click();
} }
@ -99,13 +94,12 @@ class WorkerGroupE2ETest {
Awaitility.await().untilAsserted(() -> { Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat(page.workerGroupList()) assertThat(page.workerGroupList())
.as("workerGroup list should contain newly-modified workerGroup") .as("workerGroup list should contain newly-modified workerGroup")
.extracting(WebElement::getText) .extracting(WebElement::getText)
.anyMatch(it -> it.contains(editWorkerGroupName)); .anyMatch(it -> it.contains(editWorkerGroupName));
}); });
} }
@Test @Test
@Order(40) @Order(40)
void testDeleteWorkerGroup() { void testDeleteWorkerGroup() {
@ -117,10 +111,8 @@ class WorkerGroupE2ETest {
browser.navigate().refresh(); browser.navigate().refresh();
assertThat( assertThat(
page.workerGroupList() page.workerGroupList()).noneMatch(
).noneMatch( it -> it.getText().contains(workerGroupName) || it.getText().contains(editWorkerGroupName));
it -> it.getText().contains(workerGroupName) || it.getText().contains(editWorkerGroupName)
);
}); });
} }
} }

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

@ -19,6 +19,8 @@
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.LoginPage;
@ -35,7 +37,6 @@ 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.apache.dolphinscheduler.e2e.pages.security.UserPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
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;
@ -43,14 +44,11 @@ import org.junit.jupiter.api.Test;
import org.openqa.selenium.By; 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.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait; import org.testcontainers.shaded.org.awaitility.Awaitility;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
@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 workflow = "test-workflow-1"; private static final String workflow = "test-workflow-1";
@ -82,58 +80,55 @@ class WorkflowE2ETest {
userPage.update(user, user, email, phone, tenant) userPage.update(user, user, 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)
.delete(workflow); .delete(workflow);
new NavBarPage(browser) new NavBarPage(browser)
.goToNav(ProjectPage.class) .goToNav(ProjectPage.class)
.delete(project); .delete(project);
browser.navigate().refresh(); browser.navigate().refresh();
new NavBarPage(browser) new NavBarPage(browser)
.goToNav(SecurityPage.class) .goToNav(SecurityPage.class)
.goToTab(TenantPage.class) .goToTab(TenantPage.class)
.delete(tenant); .delete(tenant);
} }
@Test @Test
@Order(1) @Order(1)
void testCreateWorkflow() { void testCreateWorkflow() {
WorkflowDefinitionTab workflowDefinitionPage = WorkflowDefinitionTab workflowDefinitionPage =
new ProjectPage(browser) new ProjectPage(browser)
.goTo(project) .goTo(project)
.goToTab(WorkflowDefinitionTab.class); .goToTab(WorkflowDefinitionTab.class);
workflowDefinitionPage workflowDefinitionPage
.createWorkflow() .createWorkflow()
.<ShellTaskForm> addTask(TaskType.SHELL) .<ShellTaskForm>addTask(TaskType.SHELL)
.script("echo ${today}\necho ${global_param}\n") .script("echo ${today}\necho ${global_param}\n")
.name("test-1") .name("test-1")
.addParam("today", "${system.datetime}") .addParam("today", "${system.datetime}")
.submit() .submit()
.submit() .submit()
.name(workflow) .name(workflow)
.addGlobalParam("global_param", "hello world") .addGlobalParam("global_param", "hello world")
.submit() .submit();
;
Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList()) Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList())
.as("Workflow list should contain newly-created workflow") .as("Workflow list should contain newly-created workflow")
.anyMatch( .anyMatch(
it -> it.getText().contains(workflow) it -> it.getText().contains(workflow)));
));
workflowDefinitionPage.publish(workflow); workflowDefinitionPage.publish(workflow);
} }
@ -142,28 +137,26 @@ class WorkflowE2ETest {
void testCreateSubWorkflow() { void testCreateSubWorkflow() {
final String workflow = "test-sub-workflow-1"; final String workflow = "test-sub-workflow-1";
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
.createSubProcessWorkflow() .createSubProcessWorkflow()
.<SubWorkflowTaskForm> addTask(TaskType.SUB_PROCESS) .<SubWorkflowTaskForm>addTask(TaskType.SUB_PROCESS)
.childNode("test-workflow-1") .childNode("test-workflow-1")
.name("test-sub-1") .name("test-sub-1")
.submit() .submit()
.submit() .submit()
.name(workflow) .name(workflow)
.addGlobalParam("global_param", "hello world") .addGlobalParam("global_param", "hello world")
.submit() .submit();
;
Awaitility.await().untilAsserted(() -> assertThat( Awaitility.await().untilAsserted(() -> assertThat(
workflowDefinitionPage.workflowList() workflowDefinitionPage.workflowList()).anyMatch(it -> it.getText().contains(workflow)));
).anyMatch(it -> it.getText().contains(workflow)));
workflowDefinitionPage.publish(workflow); workflowDefinitionPage.publish(workflow);
} }

21
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowHttpTaskE2ETest.java

@ -19,6 +19,8 @@
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.LoginPage;
@ -32,6 +34,7 @@ import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.HttpTaskForm;
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.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;
@ -39,16 +42,10 @@ import org.junit.jupiter.api.Test;
import org.openqa.selenium.By; 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.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testcontainers.shaded.org.awaitility.Awaitility; import org.testcontainers.shaded.org.awaitility.Awaitility;
import java.time.Duration;
import static org.assertj.core.api.Assertions.assertThat;
@DolphinScheduler(composeFiles = "docker/workflow-http/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/workflow-http/docker-compose.yaml")
public class WorkflowHttpTaskE2ETest { public class WorkflowHttpTaskE2ETest {
private static final String project = "test-workflow-1"; private static final String project = "test-workflow-1";
private static final String workflow = "test-workflow-1"; private static final String workflow = "test-workflow-1";
@ -82,8 +79,7 @@ public class WorkflowHttpTaskE2ETest {
userPage.update(user, user, email, phone, tenant) userPage.update(user, user, email, phone, tenant)
.goToNav(ProjectPage.class) .goToNav(ProjectPage.class)
.create(project) .create(project);
;
} }
@AfterAll @AfterAll
@ -116,7 +112,7 @@ public class WorkflowHttpTaskE2ETest {
workflowDefinitionPage workflowDefinitionPage
.createWorkflow() .createWorkflow()
.<HttpTaskForm> addTask(WorkflowForm.TaskType.HTTP) .<HttpTaskForm>addTask(WorkflowForm.TaskType.HTTP)
.url(mockServerUrl) .url(mockServerUrl)
.name("test-1") .name("test-1")
.addParam("today", "${system.datetime}") .addParam("today", "${system.datetime}")
@ -125,18 +121,15 @@ public class WorkflowHttpTaskE2ETest {
.submit() .submit()
.name(workflow) .name(workflow)
.addGlobalParam("global_param", "hello world") .addGlobalParam("global_param", "hello world")
.submit() .submit();
;
Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList()) Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList())
.as("Workflow list should contain newly-created workflow") .as("Workflow list should contain newly-created workflow")
.anyMatch( .anyMatch(
it -> it.getText().contains(workflow) it -> it.getText().contains(workflow)));
));
workflowDefinitionPage.publish(workflow); workflowDefinitionPage.publish(workflow);
} }
@Test @Test
@Order(30) @Order(30)
void testRunWorkflow() { void testRunWorkflow() {

24
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java

@ -19,6 +19,8 @@
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.LoginPage;
@ -33,23 +35,19 @@ import org.apache.dolphinscheduler.e2e.pages.security.EnvironmentPage;
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.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.By;
import org.openqa.selenium.WebElement;
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.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testcontainers.shaded.org.awaitility.Awaitility; 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") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
public class WorkflowJavaTaskE2ETest { public class WorkflowJavaTaskE2ETest {
private static final String project = "test-workflow-1"; private static final String project = "test-workflow-1";
private static final String workflow = "test-workflow-1"; private static final String workflow = "test-workflow-1";
@ -98,8 +96,7 @@ public class WorkflowJavaTaskE2ETest {
userPage.update(user, user, email, phone, tenant) userPage.update(user, user, email, phone, tenant)
.goToNav(ProjectPage.class) .goToNav(ProjectPage.class)
.create(project) .create(project);
;
} }
@AfterAll @AfterAll
@ -122,8 +119,6 @@ public class WorkflowJavaTaskE2ETest {
.delete(tenant); .delete(tenant);
} }
@Test @Test
@Order(1) @Order(1)
void testCreateWorkflow() { void testCreateWorkflow() {
@ -134,7 +129,7 @@ public class WorkflowJavaTaskE2ETest {
workflowDefinitionPage workflowDefinitionPage
.createWorkflow() .createWorkflow()
.<JavaTaskForm> addTask(WorkflowForm.TaskType.JAVA) .<JavaTaskForm>addTask(WorkflowForm.TaskType.JAVA)
.script(javaContent) .script(javaContent)
.name("test-1") .name("test-1")
.addParam("today", "${system.datetime}") .addParam("today", "${system.datetime}")
@ -143,18 +138,15 @@ public class WorkflowJavaTaskE2ETest {
.submit() .submit()
.name(workflow) .name(workflow)
.addGlobalParam("global_param", "hello world") .addGlobalParam("global_param", "hello world")
.submit() .submit();
;
Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList()) Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList())
.as("Workflow list should contain newly-created workflow") .as("Workflow list should contain newly-created workflow")
.anyMatch( .anyMatch(
it -> it.getText().contains(workflow) it -> it.getText().contains(workflow)));
));
workflowDefinitionPage.publish(workflow); workflowDefinitionPage.publish(workflow);
} }
@Test @Test
@Order(30) @Order(30)
void testRunWorkflow() { void testRunWorkflow() {

95
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowSwitchE2ETest.java

@ -19,6 +19,8 @@
package org.apache.dolphinscheduler.e2e.cases; package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
@ -35,19 +37,18 @@ import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SwitchTaskFor
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.testcontainers.shaded.org.awaitility.Awaitility; import java.util.List;
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.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class WorkflowSwitchE2ETest { class WorkflowSwitchE2ETest {
private static final String project = "test-workflow-1"; private static final String project = "test-workflow-1";
private static final String workflow = "test-workflow-1"; private static final String workflow = "test-workflow-1";
private static final String ifBranchName = "key==1"; private static final String ifBranchName = "key==1";
@ -60,31 +61,28 @@ class WorkflowSwitchE2ETest {
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
new LoginPage(browser) 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(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) new NavBarPage(browser)
.goToNav(ProjectPage.class) .goToNav(ProjectPage.class)
.delete(project) .delete(project)
.goToNav(SecurityPage.class) .goToNav(SecurityPage.class)
.goToTab(TenantPage.class) .goToTab(TenantPage.class)
.delete(tenant) .delete(tenant);
;
} }
@Test @Test
@ -92,33 +90,33 @@ class WorkflowSwitchE2ETest {
void testCreateSwitchWorkflow() { void testCreateSwitchWorkflow() {
final WorkflowDefinitionTab workflowDefinitionPage = final WorkflowDefinitionTab workflowDefinitionPage =
new ProjectPage(browser) new ProjectPage(browser)
.goTo(project) .goTo(project)
.goToTab(WorkflowDefinitionTab.class); .goToTab(WorkflowDefinitionTab.class);
WorkflowForm workflowForm = workflowDefinitionPage.createWorkflow(); WorkflowForm workflowForm = workflowDefinitionPage.createWorkflow();
workflowForm.<ShellTaskForm> addTask(TaskType.SHELL) workflowForm.<ShellTaskForm>addTask(TaskType.SHELL)
.script("echo ${today}\necho ${global_param}\n") .script("echo ${today}\necho ${global_param}\n")
.name("pre-task") .name("pre-task")
.submit(); .submit();
SwitchTaskForm switchTaskForm = workflowForm.addTask(TaskType.SWITCH); SwitchTaskForm switchTaskForm = workflowForm.addTask(TaskType.SWITCH);
switchTaskForm.preTask("pre-task") switchTaskForm.preTask("pre-task")
.name("switch") .name("switch")
.submit(); .submit();
workflowForm.<ShellTaskForm>addTask(TaskType.SHELL) workflowForm.<ShellTaskForm>addTask(TaskType.SHELL)
.script("echo ${key}") .script("echo ${key}")
.preTask("switch") .preTask("switch")
.name(ifBranchName) .name(ifBranchName)
.submit(); .submit();
workflowForm.<ShellTaskForm>addTask(TaskType.SHELL) workflowForm.<ShellTaskForm>addTask(TaskType.SHELL)
.script("echo ${key}") .script("echo ${key}")
.preTask("switch") .preTask("switch")
.name(elseBranchName) .name(elseBranchName)
.submit(); .submit();
// format dag // format dag
workflowForm.formatDAG().confirm(); workflowForm.formatDAG().confirm();
@ -130,13 +128,12 @@ class WorkflowSwitchE2ETest {
switchTaskForm.submit(); switchTaskForm.submit();
workflowForm.submit() workflowForm.submit()
.name(workflow) .name(workflow)
.addGlobalParam("key", "1") .addGlobalParam("key", "1")
.submit(); .submit();
Awaitility.await().untilAsserted(() -> assertThat( Awaitility.await().untilAsserted(() -> assertThat(
workflowDefinitionPage.workflowList() workflowDefinitionPage.workflowList()).anyMatch(it -> it.getText().contains(workflow)));
).anyMatch(it -> it.getText().contains(workflow)));
workflowDefinitionPage.publish(workflow); workflowDefinitionPage.publish(workflow);
} }
@ -178,8 +175,10 @@ class WorkflowSwitchE2ETest {
Awaitility.await().untilAsserted(() -> { Awaitility.await().untilAsserted(() -> {
assertThat(taskInstances.size()).isEqualTo(3); assertThat(taskInstances.size()).isEqualTo(3);
assertThat(taskInstances.stream().filter(row -> row.taskInstanceName().contains(ifBranchName)).count()).isEqualTo(1); assertThat(taskInstances.stream().filter(row -> row.taskInstanceName().contains(ifBranchName)).count())
assertThat(taskInstances.stream().noneMatch(row -> row.taskInstanceName().contains(elseBranchName))).isTrue(); .isEqualTo(1);
assertThat(taskInstances.stream().noneMatch(row -> row.taskInstanceName().contains(elseBranchName)))
.isTrue();
}); });
} }
} }

14
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java

@ -17,6 +17,8 @@
package org.apache.dolphinscheduler.e2e.cases.tasks; package org.apache.dolphinscheduler.e2e.cases.tasks;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.cases.workflow.BaseWorkflowE2ETest; import org.apache.dolphinscheduler.e2e.cases.workflow.BaseWorkflowE2ETest;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage;
@ -27,16 +29,12 @@ import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTa
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm;
import org.apache.dolphinscheduler.e2e.pages.resource.FileManagePage; import org.apache.dolphinscheduler.e2e.pages.resource.FileManagePage;
import org.apache.dolphinscheduler.e2e.pages.resource.ResourcePage; import org.apache.dolphinscheduler.e2e.pages.resource.ResourcePage;
import org.junit.FixMethodOrder;
import org.junit.jupiter.api.Order; import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.runners.MethodSorters; import org.junit.jupiter.api.TestMethodOrder;
import org.openqa.selenium.WebElement;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @TestMethodOrder(MethodOrderer.MethodName.class)
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
public class ShellTaskE2ETest extends BaseWorkflowE2ETest { public class ShellTaskE2ETest extends BaseWorkflowE2ETest {

30
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java

@ -17,19 +17,12 @@
package org.apache.dolphinscheduler.e2e.cases.workflow; package org.apache.dolphinscheduler.e2e.cases.workflow;
import java.time.Duration; import static org.assertj.core.api.Assertions.assertThat;
import java.util.List; import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.dolphinscheduler.e2e.core.WebDriverHolder; import org.apache.dolphinscheduler.e2e.core.WebDriverHolder;
import org.apache.dolphinscheduler.e2e.models.tenant.DefaultTenant;
import org.apache.dolphinscheduler.e2e.models.users.AdminUser; import org.apache.dolphinscheduler.e2e.models.users.AdminUser;
import org.apache.dolphinscheduler.e2e.models.users.IUser;
import org.apache.dolphinscheduler.e2e.pages.LoginPage; 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.ProjectDetailPage;
import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; 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.TaskInstanceTab;
@ -38,11 +31,16 @@ import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTa
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.apache.dolphinscheduler.e2e.pages.security.UserPage;
import org.junit.jupiter.api.AfterAll;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
@Slf4j @Slf4j
public abstract class BaseWorkflowE2ETest { public abstract class BaseWorkflowE2ETest {
@ -83,8 +81,7 @@ public abstract class BaseWorkflowE2ETest {
await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList()) await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList())
.as("Workflow list should contain newly-created workflow: %s", workflowName) .as("Workflow list should contain newly-created workflow: %s", workflowName)
.anyMatch( .anyMatch(
it -> it.getText().contains(workflowName) it -> it.getText().contains(workflowName)));
));
} }
protected void runWorkflow(String workflowName) { protected void runWorkflow(String workflowName) {
@ -155,7 +152,8 @@ public abstract class BaseWorkflowE2ETest {
if (workflowInstances.size() > 1) { if (workflowInstances.size() > 1) {
throw new RuntimeException("More than one failed workflow instance found: " + throw new RuntimeException("More than one failed workflow instance found: " +
workflowInstances.stream() workflowInstances.stream()
.map(WorkflowInstanceTab.Row::workflowInstanceName).collect(Collectors.joining(", "))); .map(WorkflowInstanceTab.Row::workflowInstanceName)
.collect(Collectors.joining(", ")));
} }
return workflowInstances.get(0); return workflowInstances.get(0);
}, Objects::nonNull); }, Objects::nonNull);

1
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/DefaultTenant.java

@ -18,6 +18,7 @@
package org.apache.dolphinscheduler.e2e.models.tenant; package org.apache.dolphinscheduler.e2e.models.tenant;
public class DefaultTenant implements ITenant { public class DefaultTenant implements ITenant {
@Override @Override
public String getTenantCode() { public String getTenantCode() {
return "default"; return "default";

3
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/AdminUser.java

@ -17,10 +17,11 @@
package org.apache.dolphinscheduler.e2e.models.users; package org.apache.dolphinscheduler.e2e.models.users;
import lombok.Data;
import org.apache.dolphinscheduler.e2e.models.tenant.BootstrapTenant; import org.apache.dolphinscheduler.e2e.models.tenant.BootstrapTenant;
import org.apache.dolphinscheduler.e2e.models.tenant.ITenant; import org.apache.dolphinscheduler.e2e.models.tenant.ITenant;
import lombok.Data;
@Data @Data
public class AdminUser implements IUser { public class AdminUser implements IUser {

3
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/IUser.java

@ -17,8 +17,6 @@
package org.apache.dolphinscheduler.e2e.models.users; package org.apache.dolphinscheduler.e2e.models.users;
import org.apache.dolphinscheduler.e2e.models.tenant.ITenant;
public interface IUser { public interface IUser {
String getUserName(); String getUserName();
@ -31,5 +29,4 @@ public interface IUser {
String getTenant(); String getTenant();
} }

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

@ -22,31 +22,28 @@ package org.apache.dolphinscheduler.e2e.pages;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.models.users.IUser; import org.apache.dolphinscheduler.e2e.models.users.IUser;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.apache.dolphinscheduler.e2e.pages.security.TenantPage;
import lombok.Getter;
import lombok.SneakyThrows;
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;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
import lombok.SneakyThrows;
import java.time.Duration;
@Getter @Getter
public final class LoginPage extends NavBarPage { public final class LoginPage extends NavBarPage {
@FindBys({ @FindBys({
@FindBy(className = "input-user-name"), @FindBy(className = "input-user-name"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private WebElement inputUsername; private WebElement inputUsername;
@FindBys( { @FindBys({
@FindBy(className = "input-password"), @FindBy(className = "input-password"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private WebElement inputPassword; private WebElement inputPassword;
@ -67,7 +64,8 @@ public final class LoginPage extends NavBarPage {
@SneakyThrows @SneakyThrows
public NavBarPage login(String username, String password) { public NavBarPage login(String username, String password) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(buttonSwitchLanguage)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(buttonSwitchLanguage));
buttonSwitchLanguage().click(); buttonSwitchLanguage().click();
inputUsername().sendKeys(username); inputUsername().sendKeys(username);

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

@ -20,25 +20,23 @@
package org.apache.dolphinscheduler.e2e.pages.common; package org.apache.dolphinscheduler.e2e.pages.common;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import lombok.Getter;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter;
import java.time.Duration;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@Getter @Getter
public final class CodeEditor { public final class CodeEditor {
@FindBys({ @FindBys({
@FindBy(className = "monaco-editor"), @FindBy(className = "monaco-editor"),
@FindBy(className = "view-line"), @FindBy(className = "view-line"),
}) })
private WebElement editor; private WebElement editor;

11
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/HttpInput.java

@ -18,23 +18,22 @@
* *
*/ */
package org.apache.dolphinscheduler.e2e.pages.common; package org.apache.dolphinscheduler.e2e.pages.common;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import lombok.Getter;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
@Getter @Getter
public class HttpInput { public class HttpInput {
@FindBys({ @FindBys({
@FindBy(className = "input-url-name"), @FindBy(className = "input-url-name"),
@FindBy(tagName = "input") @FindBy(tagName = "input")
@ -43,8 +42,6 @@ public class HttpInput {
private WebDriver driver; private WebDriver driver;
public HttpInput(WebDriver driver) { public HttpInput(WebDriver driver) {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
this.driver = driver; this.driver = driver;

23
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java

@ -26,20 +26,18 @@ import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage;
import org.apache.dolphinscheduler.e2e.pages.resource.ResourcePage; import org.apache.dolphinscheduler.e2e.pages.resource.ResourcePage;
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage;
import lombok.Getter;
import org.openqa.selenium.JavascriptExecutor; 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;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
import java.time.Duration;
@Getter @Getter
public class NavBarPage { public class NavBarPage {
protected final RemoteWebDriver driver; protected final RemoteWebDriver driver;
@FindBy(xpath = "//div[contains(@class, 'tab-horizontal')]//div[contains(@role,'menubar')]//span[contains(text(), 'Project')]") @FindBy(xpath = "//div[contains(@class, 'tab-horizontal')]//div[contains(@role,'menubar')]//span[contains(text(), 'Project')]")
@ -72,21 +70,26 @@ public class NavBarPage {
} }
if (nav == SecurityPage.class) { if (nav == SecurityPage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(securityTab)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(securityTab));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", securityTab()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", securityTab());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/tenant-manage")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/tenant-manage"));
return nav.cast(new SecurityPage(driver)); return nav.cast(new SecurityPage(driver));
} }
if (nav == ResourcePage.class) { if (nav == ResourcePage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(resourceTab)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(resourceTab));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", resourceTab()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", resourceTab());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file-manage")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/resource/file-manage"));
return nav.cast(new ResourcePage(driver)); return nav.cast(new ResourcePage(driver));
} }
if (nav == DataSourcePage.class) { if (nav == DataSourcePage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(dataSourceTab)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(dataSourceTab));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", dataSourceTab()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", dataSourceTab());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/datasource")); WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/datasource"));
return nav.cast(new DataSourcePage(driver)); return nav.cast(new DataSourcePage(driver));

405
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java

@ -1,204 +1,201 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information * distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
* *
*/ */
package org.apache.dolphinscheduler.e2e.pages.datasource; package org.apache.dolphinscheduler.e2e.pages.datasource;
import lombok.Getter; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import java.util.List;
import java.security.Key; import lombok.Getter;
import java.time.Duration;
import java.util.List; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.By; import org.openqa.selenium.Keys;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebElement;
import org.openqa.selenium.Keys; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; @Getter
import org.openqa.selenium.support.ui.ExpectedCondition; public class DataSourcePage extends NavBarPage implements NavBarPage.NavBarItem {
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait; @FindBy(className = "btn-create-data-source")
private WebElement buttonCreateDataSource;
@Getter @FindBy(className = "data-source-items")
public class DataSourcePage extends NavBarPage implements NavBarPage.NavBarItem { private List<WebElement> dataSourceItemsList;
@FindBy(className = "btn-create-data-source") @FindBys({
private WebElement buttonCreateDataSource; @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
@FindBy(className = "data-source-items") })
private List<WebElement> dataSourceItemsList; private WebElement buttonConfirm;
@FindBys({ @FindBys({
@FindBy(className = "n-popconfirm__action"), @FindBy(className = "dialog-source-modal"),
@FindBy(className = "n-button--primary-type"), })
}) private WebElement dataSourceModal;
private WebElement buttonConfirm;
private final CreateDataSourceForm createDataSourceForm;
@FindBys({
@FindBy(className = "dialog-source-modal"), public DataSourcePage(RemoteWebDriver driver) {
}) super(driver);
private WebElement dataSourceModal;
createDataSourceForm = new CreateDataSourceForm();
private final CreateDataSourceForm createDataSourceForm; }
public DataSourcePage(RemoteWebDriver driver) { public DataSourcePage createDataSource(String dataSourceType, String dataSourceName, String dataSourceDescription,
super(driver); String ip, String port, String userName, String password, String database,
String jdbcParams) {
createDataSourceForm = new CreateDataSourceForm(); buttonCreateDataSource().click();
}
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(
public DataSourcePage createDataSource(String dataSourceType, String dataSourceName, String dataSourceDescription, String ip, String port, String userName, String password, String database, new By.ByClassName("dialog-source-modal")));
String jdbcParams) {
buttonCreateDataSource().click(); dataSourceModal().findElement(By.className(dataSourceType.toUpperCase() + "-box")).click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated( WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.textToBePresentInElement(
new By.ByClassName("dialog-source-modal"))); driver.findElement(By.className("dialog-create-data-source")), dataSourceType.toUpperCase()));
dataSourceModal().findElement(By.className(dataSourceType.toUpperCase()+"-box")).click(); createDataSourceForm().inputDataSourceName().sendKeys(dataSourceName);
createDataSourceForm().inputDataSourceDescription().sendKeys(dataSourceDescription);
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.className("dialog-create-data-source")), dataSourceType.toUpperCase())); createDataSourceForm().inputIP().sendKeys(ip);
createDataSourceForm().inputPort().sendKeys(Keys.CONTROL + "a");
createDataSourceForm().inputDataSourceName().sendKeys(dataSourceName); createDataSourceForm().inputPort().sendKeys(Keys.BACK_SPACE);
createDataSourceForm().inputDataSourceDescription().sendKeys(dataSourceDescription); createDataSourceForm().inputPort().sendKeys(port);
createDataSourceForm().inputIP().sendKeys(ip); createDataSourceForm().inputUserName().sendKeys(userName);
createDataSourceForm().inputPort().sendKeys(Keys.CONTROL + "a"); createDataSourceForm().inputPassword().sendKeys(password);
createDataSourceForm().inputPort().sendKeys(Keys.BACK_SPACE); createDataSourceForm().inputDataBase().sendKeys(database);
createDataSourceForm().inputPort().sendKeys(port);
createDataSourceForm().inputUserName().sendKeys(userName); if (!"".equals(jdbcParams)) {
createDataSourceForm().inputPassword().sendKeys(password); createDataSourceForm().inputJdbcParams().sendKeys(jdbcParams);
createDataSourceForm().inputDataBase().sendKeys(database); }
if (!"".equals(jdbcParams)) { createDataSourceForm().buttonSubmit().click();
createDataSourceForm().inputJdbcParams().sendKeys(jdbcParams);
} return this;
}
createDataSourceForm().buttonSubmit().click();
public DataSourcePage delete(String name) {
return this; dataSourceItemsList()
} .stream()
.filter(it -> it.getText().contains(name))
public DataSourcePage delete(String name) { .flatMap(it -> it.findElements(By.className("btn-delete")).stream())
dataSourceItemsList() .filter(WebElement::isDisplayed)
.stream() .findFirst()
.filter(it -> it.getText().contains(name)) .orElseThrow(() -> new RuntimeException("No delete button in data source list"))
.flatMap(it -> it.findElements(By.className("btn-delete")).stream()) .click();
.filter(WebElement::isDisplayed)
.findFirst() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.orElseThrow(() -> new RuntimeException("No delete button in data source list"))
.click(); return this;
}
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
@Getter
return this; public class CreateDataSourceForm {
}
CreateDataSourceForm() {
@Getter PageFactory.initElements(driver, this);
public class CreateDataSourceForm { }
CreateDataSourceForm() {
PageFactory.initElements(driver, this); @FindBy(className = "n-base-select-option__content")
} private List<WebElement> selectDataSourceType;
@FindBy(className = "n-base-select-option__content") @FindBys({
private List<WebElement> selectDataSourceType; @FindBy(className = "btn-data-source-type-drop-down"),
@FindBy(className = "n-base-selection"),
@FindBys({ })
@FindBy(className = "btn-data-source-type-drop-down"), private WebElement btnDataSourceTypeDropdown;
@FindBy(className = "n-base-selection"),
}) @FindBys({
private WebElement btnDataSourceTypeDropdown; @FindBy(className = "input-data-source-name"),
@FindBy(tagName = "input"),
@FindBys({ })
@FindBy(className = "input-data-source-name"), private WebElement inputDataSourceName;
@FindBy(tagName = "input"),
}) @FindBys({
private WebElement inputDataSourceName; @FindBy(className = "input-data-source-description"),
@FindBy(tagName = "textarea"),
@FindBys({ })
@FindBy(className = "input-data-source-description"), private WebElement inputDataSourceDescription;
@FindBy(tagName = "textarea"),
}) @FindBys({
private WebElement inputDataSourceDescription; @FindBy(className = "input-ip"),
@FindBy(tagName = "input"),
@FindBys({ })
@FindBy(className = "input-ip"), private WebElement inputIP;
@FindBy(tagName = "input"),
}) @FindBys({
private WebElement inputIP; @FindBy(className = "input-port"),
@FindBy(tagName = "input"),
@FindBys({ })
@FindBy(className = "input-port"), private WebElement inputPort;
@FindBy(tagName = "input"),
}) @FindBys({
private WebElement inputPort; @FindBy(className = "input-username"),
@FindBy(tagName = "input"),
@FindBys({ })
@FindBy(className = "input-username"), private WebElement inputUserName;
@FindBy(tagName = "input"),
}) @FindBys({
private WebElement inputUserName; @FindBy(className = "input-password"),
@FindBy(tagName = "input"),
@FindBys({ })
@FindBy(className = "input-password"), private WebElement inputPassword;
@FindBy(tagName = "input"),
}) @FindBys({
private WebElement inputPassword; @FindBy(className = "input-data-base"),
@FindBy(tagName = "input"),
@FindBys({ })
@FindBy(className = "input-data-base"), private WebElement inputDataBase;
@FindBy(tagName = "input"),
}) @FindBys({
private WebElement inputDataBase; @FindBy(className = "input-jdbc-params"),
@FindBy(tagName = "textarea"),
@FindBys({ })
@FindBy(className = "input-jdbc-params"), private WebElement inputJdbcParams;
@FindBy(tagName = "textarea"),
}) @FindBy(className = "btn-submit")
private WebElement inputJdbcParams; private WebElement buttonSubmit;
@FindBy(className = "btn-submit") @FindBy(className = "btn-cancel")
private WebElement buttonSubmit; private WebElement buttonCancel;
@FindBy(className = "btn-cancel") @FindBy(className = "btn-test-connection")
private WebElement buttonCancel; private WebElement btnTestConnection;
@FindBy(className = "btn-test-connection") @FindBys({
private WebElement btnTestConnection; @FindBy(className = "input-zeppelin_rest_endpoint"),
@FindBy(tagName = "input"),
@FindBys({ })
@FindBy(className = "input-zeppelin_rest_endpoint"), private WebElement inputZeppelinRestEndpoint;
@FindBy(tagName = "input"),
}) @FindBys({
private WebElement inputZeppelinRestEndpoint; @FindBy(className = "input-kubeConfig"),
@FindBy(tagName = "textarea"),
@FindBys({ })
@FindBy(className = "input-kubeConfig"), private WebElement inputKubeConfig;
@FindBy(tagName = "textarea"),
}) }
private WebElement inputKubeConfig; }
}
}

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

@ -19,22 +19,23 @@
*/ */
package org.apache.dolphinscheduler.e2e.pages.project; package org.apache.dolphinscheduler.e2e.pages.project;
import lombok.SneakyThrows;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab; 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.WorkflowDefinitionTab;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab;
import lombok.Getter;
import lombok.SneakyThrows;
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;
import lombok.Getter;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
@Getter @Getter
public final class ProjectDetailPage extends NavBarPage { public final class ProjectDetailPage extends NavBarPage {
@FindBy(css = ".tab-vertical .n-submenu:nth-of-type(2) .n-menu-item:nth-of-type(2) > .n-menu-item-content") @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;
@ -52,12 +53,14 @@ public final class ProjectDetailPage extends NavBarPage {
public <T extends Tab> T goToTab(Class<T> tab) { public <T extends Tab> T goToTab(Class<T> tab) {
if (tab == WorkflowDefinitionTab.class) { if (tab == WorkflowDefinitionTab.class) {
menuProcessDefinition().click(); menuProcessDefinition().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/workflow-definition")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/workflow-definition"));
return tab.cast(new WorkflowDefinitionTab(driver)); return tab.cast(new WorkflowDefinitionTab(driver));
} }
if (tab == WorkflowInstanceTab.class) { if (tab == WorkflowInstanceTab.class) {
menuProcessInstances().click(); menuProcessInstances().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/workflow/instances")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/workflow/instances"));
return tab.cast(new WorkflowInstanceTab(driver)); return tab.cast(new WorkflowInstanceTab(driver));
} }
if (tab == TaskInstanceTab.class) { if (tab == TaskInstanceTab.class) {

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

@ -19,11 +19,16 @@
*/ */
package org.apache.dolphinscheduler.e2e.pages.project; package org.apache.dolphinscheduler.e2e.pages.project;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage.NavBarItem; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage.NavBarItem;
import java.util.List; import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
@ -31,15 +36,10 @@ import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
@Getter @Getter
public final class ProjectPage extends NavBarPage implements NavBarItem { public final class ProjectPage extends NavBarPage implements NavBarItem {
@FindBy(className = "btn-create-project") @FindBy(className = "btn-create-project")
private WebElement buttonCreateProject; private WebElement buttonCreateProject;
@ -77,7 +77,6 @@ public final class ProjectPage extends NavBarPage implements NavBarItem {
return this; return this;
} }
public ProjectPage delete(String project) { public ProjectPage delete(String project) {
projectList() projectList()
.stream() .stream()
@ -104,6 +103,7 @@ public final class ProjectPage extends NavBarPage implements NavBarItem {
@Getter @Getter
public class CreateProjectForm { public class CreateProjectForm {
CreateProjectForm() { CreateProjectForm() {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }

22
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/TaskInstanceTab.java

@ -20,18 +20,19 @@
package org.apache.dolphinscheduler.e2e.pages.project.workflow; 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.common.NavBarPage;
import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage;
import java.util.List;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.openqa.selenium.By; import org.openqa.selenium.By;
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;
import org.openqa.selenium.support.FindBys;
import java.util.List;
import java.util.stream.Collectors;
@Getter @Getter
public final class TaskInstanceTab extends NavBarPage implements ProjectDetailPage.Tab { public final class TaskInstanceTab extends NavBarPage implements ProjectDetailPage.Tab {
@ -45,14 +46,15 @@ public final class TaskInstanceTab extends NavBarPage implements ProjectDetailPa
public List<Row> instances() { public List<Row> instances() {
return instanceList() return instanceList()
.stream() .stream()
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.map(Row::new) .map(Row::new)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@RequiredArgsConstructor @RequiredArgsConstructor
public static class Row { public static class Row {
private final WebElement row; private final WebElement row;
public String taskInstanceName() { public String taskInstanceName() {

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

@ -27,6 +27,8 @@ import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
@ -35,10 +37,9 @@ import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.testcontainers.shaded.org.awaitility.Awaitility; import org.testcontainers.shaded.org.awaitility.Awaitility;
import lombok.Getter;
@Getter @Getter
public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDetailPage.Tab { public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDetailPage.Tab {
@FindBy(className = "btn-create-process") @FindBy(className = "btn-create-process")
private WebElement buttonCreateProcess; private WebElement buttonCreateProcess;
@ -61,8 +62,8 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
private WebElement buttonConfirm; private WebElement buttonConfirm;
@FindBys({ @FindBys({
@FindBy(className = "n-dialog__action"), @FindBy(className = "n-dialog__action"),
@FindBy(className = "n-button--default-type"), @FindBy(className = "n-button--default-type"),
}) })
private WebElement publishSuccessButtonCancel; private WebElement publishSuccessButtonCancel;
@ -91,13 +92,13 @@ 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("workflow-name")).getAttribute("innerText").equals(workflow)) .filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("btn-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"))
.click(); .click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
@ -108,13 +109,13 @@ 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("workflow-name")).getAttribute("innerText").equals(workflow)) .filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("btn-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"))
.click(); .click();
return new WorkflowRunDialog(this); return new WorkflowRunDialog(this);
} }
@ -136,19 +137,18 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
public WorkflowDefinitionTab delete(String workflow) { public WorkflowDefinitionTab delete(String workflow) {
Awaitility.await().untilAsserted(() -> assertThat(workflowList()) Awaitility.await().untilAsserted(() -> assertThat(workflowList())
.as("Workflow list should contain newly-created workflow") .as("Workflow list should contain newly-created workflow")
.anyMatch( .anyMatch(
it -> it.getText().contains(workflow) it -> it.getText().contains(workflow)));
));
workflowList() workflowList()
.stream() .stream()
.filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow)) .filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("btn-delete")).stream()) .flatMap(it -> it.findElements(By.className("btn-delete")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("Can not find delete button in workflow definition")) .orElseThrow(() -> new RuntimeException("Can not find delete button in workflow definition"))
.click(); .click();
return this; return this;
} }

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

@ -21,15 +21,16 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.HttpTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.HttpTaskForm;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.JavaTaskForm;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm; 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.project.workflow.task.SwitchTaskForm; 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.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.Getter;
import lombok.SneakyThrows;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
@ -38,17 +39,14 @@ import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import com.google.common.io.Resources; import com.google.common.io.Resources;
import lombok.Getter;
import lombok.SneakyThrows;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@SuppressWarnings("UnstableApiUsage") @SuppressWarnings("UnstableApiUsage")
@Getter @Getter
public final class WorkflowForm { public final class WorkflowForm {
private WebDriver driver; private WebDriver driver;
private final WorkflowSaveDialog saveForm; private final WorkflowSaveDialog saveForm;
private final WorkflowFormatDialog formatDialog; private final WorkflowFormatDialog formatDialog;
@ -95,7 +93,8 @@ public final class WorkflowForm {
public WebElement getTask(String taskName) { public WebElement getTask(String taskName) {
List<WebElement> tasks = WebDriverWaitFactory.createWebDriverWait(driver) List<WebElement> tasks = WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("svg > g > g[class^='x6-graph-svg-stage'] > g[data-shape^='dag-task']"))); .until(ExpectedConditions.visibilityOfAllElementsLocatedBy(
By.cssSelector("svg > g > g[class^='x6-graph-svg-stage'] > g[data-shape^='dag-task']")));
WebElement task = tasks.stream() WebElement task = tasks.stream()
.filter(t -> t.getText().contains(taskName)) .filter(t -> t.getText().contains(taskName))
@ -110,7 +109,8 @@ public final class WorkflowForm {
public WorkflowSaveDialog submit() { public WorkflowSaveDialog submit() {
buttonSave().click(); buttonSave().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(.,'Basic Information')]"))); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(.,'Basic Information')]")));
return new WorkflowSaveDialog(this); return new WorkflowSaveDialog(this);
} }

11
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowFormatDialog.java

@ -19,22 +19,19 @@
*/ */
package org.apache.dolphinscheduler.e2e.pages.project.workflow; package org.apache.dolphinscheduler.e2e.pages.project.workflow;
import java.util.List;
import lombok.Getter; import lombok.Getter;
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;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; 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 @Getter
public final class WorkflowFormatDialog { public final class WorkflowFormatDialog {
private final WebDriver driver; private final WebDriver driver;
private final WorkflowForm parent; private final WorkflowForm parent;

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

@ -25,25 +25,26 @@ import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; 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;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.openqa.selenium.support.pagefactory.ByChained; 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;
@FindBys({ @FindBys({
@FindBy(className = "btn-selected"), @FindBy(className = "btn-selected"),
@FindBy(className = "n-checkbox-box"), @FindBy(className = "n-checkbox-box"),
}) })
private WebElement checkBoxSelectAll; private WebElement checkBoxSelectAll;
@ -62,10 +63,10 @@ public final class WorkflowInstanceTab extends NavBarPage implements ProjectDeta
public List<Row> instances() { public List<Row> instances() {
return instanceList() return instanceList()
.stream() .stream()
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.map(Row::new) .map(Row::new)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public WorkflowInstanceTab deleteAll() { public WorkflowInstanceTab deleteAll() {
@ -84,6 +85,7 @@ public final class WorkflowInstanceTab extends NavBarPage implements ProjectDeta
@RequiredArgsConstructor @RequiredArgsConstructor
public static class Row { public static class Row {
private final WebElement row; private final WebElement row;
public String workflowInstanceName() { public String workflowInstanceName() {
@ -108,11 +110,11 @@ public final class WorkflowInstanceTab extends NavBarPage implements ProjectDeta
public Row rerun() { public Row rerun() {
row.findElements(new ByChained(By.className("btn-rerun"), By.className("n-button__content"))) row.findElements(new ByChained(By.className("btn-rerun"), By.className("n-button__content")))
.stream() .stream()
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("Cannot find rerun button")) .orElseThrow(() -> new RuntimeException("Cannot find rerun button"))
.click(); .click();
return this; return this;
} }

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

@ -21,20 +21,17 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter;
import java.time.Duration;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@Getter @Getter
public final class WorkflowRunDialog { public final class WorkflowRunDialog {
private final WorkflowDefinitionTab parent; private final WorkflowDefinitionTab parent;
@FindBy(className = "btn-submit") @FindBy(className = "btn-submit")
@ -47,9 +44,12 @@ public final class WorkflowRunDialog {
} }
public WorkflowDefinitionTab submit() { public WorkflowDefinitionTab submit() {
By runDialogTitleXpath = By.xpath(String.format("//*[contains(text(), '%s')]", "Please set the parameters before starting")); By runDialogTitleXpath =
WebDriverWaitFactory.createWebDriverWait(parent.driver()).until(ExpectedConditions.visibilityOfElementLocated(runDialogTitleXpath)); By.xpath(String.format("//*[contains(text(), '%s')]", "Please set the parameters before starting"));
WebDriverWaitFactory.createWebDriverWait(parent.driver()).until(ExpectedConditions.elementToBeClickable(buttonSubmit())); WebDriverWaitFactory.createWebDriverWait(parent.driver())
.until(ExpectedConditions.visibilityOfElementLocated(runDialogTitleXpath));
WebDriverWaitFactory.createWebDriverWait(parent.driver())
.until(ExpectedConditions.elementToBeClickable(buttonSubmit()));
buttonSubmit().click(); buttonSubmit().click();

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

@ -19,26 +19,21 @@
*/ */
package org.apache.dolphinscheduler.e2e.pages.project.workflow; package org.apache.dolphinscheduler.e2e.pages.project.workflow;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; 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.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.List;
import java.util.stream.Stream;
@Getter @Getter
public final class WorkflowSaveDialog { public final class WorkflowSaveDialog {
private final WebDriver driver; private final WebDriver driver;
private final WorkflowForm parent; private final WorkflowForm parent;
@ -82,10 +77,10 @@ public final class WorkflowSaveDialog {
globalParamsItems().findElements(By.tagName("input")).get(0).sendKeys(key); globalParamsItems().findElements(By.tagName("input")).get(0).sendKeys(key);
globalParamsItems().findElements(By.tagName("input")).get(1).sendKeys(value); globalParamsItems().findElements(By.tagName("input")).get(1).sendKeys(value);
} else { } else {
globalParamsItems().findElements(By.tagName("button")).get(len-1).click(); 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).sendKeys(key);
globalParamsItems().findElements(By.tagName("input")).get(len+1).sendKeys(value); globalParamsItems().findElements(By.tagName("input")).get(len + 1).sendKeys(value);
} }
return this; return this;

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

@ -22,14 +22,15 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow.task;
import org.apache.dolphinscheduler.e2e.pages.common.HttpInput; import org.apache.dolphinscheduler.e2e.pages.common.HttpInput;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
public class HttpTaskForm extends TaskNodeForm{ public class HttpTaskForm extends TaskNodeForm {
private WebDriver driver; private WebDriver driver;
private HttpInput httpInput; private HttpInput httpInput;
public HttpTaskForm(WorkflowForm parent) { public HttpTaskForm(WorkflowForm parent) {
super(parent); super(parent);
this.httpInput = new HttpInput(parent.driver()); this.httpInput = new HttpInput(parent.driver());

4
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/JavaTaskForm.java

@ -22,9 +22,11 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow.task;
import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; 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 org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
public class JavaTaskForm extends TaskNodeForm{ public class JavaTaskForm extends TaskNodeForm {
private CodeEditor codeEditor; private CodeEditor codeEditor;
private WebDriver driver; private WebDriver driver;

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

@ -23,11 +23,12 @@ 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; import org.openqa.selenium.WebDriver;
@Getter @Getter
public final class ShellTaskForm extends TaskNodeForm { public final class ShellTaskForm extends TaskNodeForm {
private CodeEditor codeEditor; private CodeEditor codeEditor;
private WebDriver driver; private WebDriver driver;

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

@ -22,20 +22,20 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow.task;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm;
import java.util.List;
import lombok.Getter; import lombok.Getter;
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;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.List;
@Getter @Getter
public final class SubWorkflowTaskForm extends TaskNodeForm { public final class SubWorkflowTaskForm extends TaskNodeForm {
@FindBys({ @FindBys({
@FindBy(className = "select-child-node"), @FindBy(className = "select-child-node"),
@FindBy(className = "n-base-selection"), @FindBy(className = "n-base-selection"),
@ -47,7 +47,6 @@ public final class SubWorkflowTaskForm extends TaskNodeForm {
private WebDriver driver; private WebDriver driver;
public SubWorkflowTaskForm(WorkflowForm parent) { public SubWorkflowTaskForm(WorkflowForm parent) {
super(parent); super(parent);
@ -55,12 +54,14 @@ public final class SubWorkflowTaskForm extends TaskNodeForm {
} }
public SubWorkflowTaskForm childNode(String node) { public SubWorkflowTaskForm childNode(String node) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(btnSelectChildNodeDropdown)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(btnSelectChildNodeDropdown));
btnSelectChildNodeDropdown().click(); btnSelectChildNodeDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(By.className( WebDriverWaitFactory.createWebDriverWait(driver)
"n-base-select-option__content"))); .until(ExpectedConditions.visibilityOfElementLocated(By.className(
"n-base-select-option__content")));
selectChildNode() selectChildNode()
.stream() .stream()

21
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskForm.java

@ -19,19 +19,19 @@
*/ */
package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; package org.apache.dolphinscheduler.e2e.pages.project.workflow.task;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.List;
@Getter @Getter
public final class SwitchTaskForm extends TaskNodeForm { public final class SwitchTaskForm extends TaskNodeForm {
@ -51,14 +51,14 @@ public final class SwitchTaskForm extends TaskNodeForm {
} }
public SwitchTaskForm elseBranch(String elseBranchName) { public SwitchTaskForm elseBranch(String elseBranchName) {
((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", inputElseBranch()); ((JavascriptExecutor) parent().driver()).executeScript("arguments[0].click();", inputElseBranch());
final By optionsLocator = By.className("option-else-branches"); final By optionsLocator = By.className("option-else-branches");
WebDriverWaitFactory.createWebDriverWait(parent().driver()) WebDriverWaitFactory.createWebDriverWait(parent().driver())
.until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); .until(ExpectedConditions.visibilityOfElementLocated(optionsLocator));
List<WebElement> webElements = parent().driver().findElements(optionsLocator); List<WebElement> webElements = parent().driver().findElements(optionsLocator);
webElements.stream() webElements.stream()
.filter(it -> it.getText().contains(elseBranchName)) .filter(it -> it.getText().contains(elseBranchName))
.findFirst() .findFirst()
@ -71,19 +71,20 @@ public final class SwitchTaskForm extends TaskNodeForm {
} }
public SwitchTaskForm addIfBranch(String switchScript, String ifBranchName) { public SwitchTaskForm addIfBranch(String switchScript, String ifBranchName) {
((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", buttonAddBranch); ((JavascriptExecutor) parent().driver()).executeScript("arguments[0].click();", buttonAddBranch);
SwitchTaskIfBranch switchTaskIfBranch = new SwitchTaskIfBranch(this); SwitchTaskIfBranch switchTaskIfBranch = new SwitchTaskIfBranch(this);
switchTaskIfBranch.codeEditor().content(switchScript); switchTaskIfBranch.codeEditor().content(switchScript);
((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", switchTaskIfBranch.inputIfBranch()); ((JavascriptExecutor) parent().driver()).executeScript("arguments[0].click();",
switchTaskIfBranch.inputIfBranch());
final By optionsLocator = By.className("option-if-branches"); final By optionsLocator = By.className("option-if-branches");
WebDriverWaitFactory.createWebDriverWait(parent().driver()) WebDriverWaitFactory.createWebDriverWait(parent().driver())
.until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); .until(ExpectedConditions.visibilityOfElementLocated(optionsLocator));
List<WebElement> webElements = parent().driver().findElements(optionsLocator); List<WebElement> webElements = parent().driver().findElements(optionsLocator);
webElements.stream() webElements.stream()
.filter(it -> it.getText().contains(ifBranchName)) .filter(it -> it.getText().contains(ifBranchName))
.findFirst() .findFirst()

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

@ -19,8 +19,10 @@
*/ */
package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; package org.apache.dolphinscheduler.e2e.pages.project.workflow.task;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor;
import lombok.Getter;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
@ -29,6 +31,7 @@ import org.openqa.selenium.support.PageFactory;
@Getter @Getter
public final class SwitchTaskIfBranch { public final class SwitchTaskIfBranch {
private final WebDriver driver; private final WebDriver driver;
private final SwitchTaskForm parent; private final SwitchTaskForm parent;

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

@ -19,9 +19,13 @@
*/ */
package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; package org.apache.dolphinscheduler.e2e.pages.project.workflow.task;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
@ -30,13 +34,10 @@ import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.List;
@Getter @Getter
public abstract class TaskNodeForm { public abstract class TaskNodeForm {
@FindBys({ @FindBys({
@FindBy(className = "input-node-name"), @FindBy(className = "input-node-name"),
@FindBy(tagName = "input") @FindBy(tagName = "input")
@ -85,7 +86,6 @@ public abstract class TaskNodeForm {
}) })
private WebElement selectResource; private WebElement selectResource;
private final WorkflowForm parent; private final WorkflowForm parent;
TaskNodeForm(WorkflowForm parent) { TaskNodeForm(WorkflowForm parent) {
@ -168,7 +168,8 @@ public abstract class TaskNodeForm {
final By optionsLocator = By.className("n-tree-node-content__text"); final By optionsLocator = By.className("n-tree-node-content__text");
WebDriverWaitFactory.createWebDriverWait(parent().driver()).until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); WebDriverWaitFactory.createWebDriverWait(parent().driver())
.until(ExpectedConditions.visibilityOfElementLocated(optionsLocator));
parent().driver() parent().driver()
.findElements(optionsLocator) .findElements(optionsLocator)

664
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java

@ -1,331 +1,333 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information * distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
* *
*/ */
package org.apache.dolphinscheduler.e2e.pages.resource; package org.apache.dolphinscheduler.e2e.pages.resource;
import lombok.Getter; import static org.assertj.core.api.Assertions.assertThat;
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import java.util.List;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver; import lombok.Getter;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.LocalFileDetector; import org.openqa.selenium.By;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.Keys;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory;
import java.io.File; import org.openqa.selenium.support.ui.ExpectedConditions;
import java.time.Duration;
import java.util.List; @Getter
import static org.assertj.core.api.Assertions.assertThat; public class FileManagePage extends NavBarPage implements ResourcePage.Tab {
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
@FindBy(className = "btn-create-directory")
private WebElement buttonCreateDirectory;
@Getter
public class FileManagePage extends NavBarPage implements ResourcePage.Tab { @FindBy(className = "btn-create-file")
@FindBy(className = "btn-create-directory") private WebElement buttonCreateFile;
private WebElement buttonCreateDirectory;
@FindBy(className = "btn-upload-resource")
@FindBy(className = "btn-create-file") private WebElement buttonUploadFile;
private WebElement buttonCreateFile;
private final CreateDirectoryBox createDirectoryBox;
@FindBy(className = "btn-upload-resource")
private WebElement buttonUploadFile; private final RenameBox renameBox;
private final CreateDirectoryBox createDirectoryBox; private final UploadFileBox uploadFileBox;
private final RenameBox renameBox; private final EditFileBox editFileBox;
private final UploadFileBox uploadFileBox; @FindBy(className = "items")
private List<WebElement> fileList;
private final EditFileBox editFileBox;
@FindBys({
@FindBy(className = "items") @FindBy(className = "n-popconfirm__action"),
private List<WebElement> fileList; @FindBy(className = "n-button--primary-type"),
})
@FindBys({ private WebElement buttonConfirm;
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"), @FindBys({
}) @FindBy(className = "monaco-editor"),
private WebElement buttonConfirm; @FindBy(className = "view-line"),
})
@FindBys({ private WebElement editor;
@FindBy(className = "monaco-editor"),
@FindBy(className = "view-line"), public FileManagePage(RemoteWebDriver driver) {
}) super(driver);
private WebElement editor;
createDirectoryBox = new CreateDirectoryBox();
public FileManagePage(RemoteWebDriver driver) {
super(driver); renameBox = new RenameBox();
createDirectoryBox = new CreateDirectoryBox(); uploadFileBox = new UploadFileBox();
renameBox = new RenameBox(); editFileBox = new EditFileBox();
uploadFileBox = new UploadFileBox(); }
editFileBox = new EditFileBox(); public FileManagePage createDirectory(String name) {
buttonCreateDirectory().click();
}
createDirectoryBox().inputDirectoryName().sendKeys(name);
public FileManagePage createDirectory(String name) { createDirectoryBox().buttonSubmit().click();
buttonCreateDirectory().click();
return this;
createDirectoryBox().inputDirectoryName().sendKeys(name); }
createDirectoryBox().buttonSubmit().click();
public FileManagePage cancelCreateDirectory(String name) {
return this; buttonCreateDirectory().click();
}
createDirectoryBox().inputDirectoryName().sendKeys(name);
public FileManagePage cancelCreateDirectory(String name) { createDirectoryBox().buttonCancel().click();
buttonCreateDirectory().click();
return this;
createDirectoryBox().inputDirectoryName().sendKeys(name); }
createDirectoryBox().buttonCancel().click();
public FileManagePage rename(String currentName, String AfterName) {
return this; fileList()
} .stream()
.filter(it -> it.getText().contains(currentName))
public FileManagePage rename(String currentName, String AfterName) { .flatMap(it -> it.findElements(By.className("btn-rename")).stream())
fileList() .filter(WebElement::isDisplayed)
.stream() .findFirst()
.filter(it -> it.getText().contains(currentName)) .orElseThrow(() -> new RuntimeException("No rename button in file manage list"))
.flatMap(it -> it.findElements(By.className("btn-rename")).stream()) .click();
.filter(WebElement::isDisplayed)
.findFirst() renameBox().inputName().sendKeys(Keys.CONTROL + "a");
.orElseThrow(() -> new RuntimeException("No rename button in file manage list")) renameBox().inputName().sendKeys(Keys.BACK_SPACE);
.click(); renameBox().inputName().sendKeys(AfterName);
renameBox().buttonSubmit().click();
renameBox().inputName().sendKeys(Keys.CONTROL + "a");
renameBox().inputName().sendKeys(Keys.BACK_SPACE); return this;
renameBox().inputName().sendKeys(AfterName); }
renameBox().buttonSubmit().click();
public FileManagePage createSubDirectory(String directoryName, String subDirectoryName) {
return this; fileList()
} .stream()
.filter(it -> it.getText().contains(directoryName))
public FileManagePage createSubDirectory(String directoryName, String subDirectoryName) { .filter(WebElement::isDisplayed)
fileList() .findFirst()
.stream() .orElseThrow(() -> new RuntimeException(String.format("No %s in file manage list", directoryName)))
.filter(it -> it.getText().contains(directoryName)) .click();
.filter(WebElement::isDisplayed)
.findFirst() buttonCreateDirectory().click();
.orElseThrow(() -> new RuntimeException(String.format("No %s in file manage list", directoryName)))
.click(); createDirectoryBox().inputDirectoryName().sendKeys(subDirectoryName);
createDirectoryBox().buttonSubmit().click();
buttonCreateDirectory().click();
return this;
createDirectoryBox().inputDirectoryName().sendKeys(subDirectoryName); }
createDirectoryBox().buttonSubmit().click();
public FileManagePage delete(String name) {
return this; fileList()
} .stream()
.filter(it -> it.getText().contains(name))
public FileManagePage delete(String name) { .flatMap(it -> it.findElements(By.className("btn-delete")).stream())
fileList() .filter(WebElement::isDisplayed)
.stream() .findFirst()
.filter(it -> it.getText().contains(name)) .orElseThrow(() -> new RuntimeException("No delete button in file manage list"))
.flatMap(it -> it.findElements(By.className("btn-delete")).stream()) .click();
.filter(WebElement::isDisplayed)
.findFirst() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.orElseThrow(() -> new RuntimeException("No delete button in file manage list"))
.click(); return this;
}
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
// todo: add file type
return this; public FileManagePage createFile(String fileName, String scripts) {
}
WebDriverWaitFactory.createWebDriverWait(driver)
// todo: add file type .until(ExpectedConditions.elementToBeClickable(buttonCreateFile()));
public FileManagePage createFile(String fileName, String scripts) {
buttonCreateFile().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(buttonCreateFile()));
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file/create"));
buttonCreateFile().click();
CreateFileBox createFileBox = new CreateFileBox();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file/create")); createFileBox.inputFileName().sendKeys(fileName);
createFileBox.codeEditor().content(scripts);
CreateFileBox createFileBox = new CreateFileBox(); createFileBox.buttonSubmit().click();
createFileBox.inputFileName().sendKeys(fileName); WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file-manage"));
createFileBox.codeEditor().content(scripts); return this;
createFileBox.buttonSubmit().click(); }
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file-manage"));
return this; public FileManagePage createFileUntilSuccess(String fileName, String scripts) {
}
createFile(fileName, scripts);
public FileManagePage createFileUntilSuccess(String fileName, String scripts) {
await()
createFile(fileName, scripts); .untilAsserted(() -> assertThat(fileList())
.as("File list should contain newly-created file: " + fileName)
await() .extracting(WebElement::getText)
.untilAsserted(() -> .anyMatch(it -> it.contains(fileName)));
assertThat(fileList()) return this;
.as("File list should contain newly-created file: " + fileName) }
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(fileName))); public FileManagePage editFile(String fileName, String scripts) {
return this; fileList()
} .stream()
.filter(it -> it.getText().contains(fileName))
public FileManagePage editFile(String fileName, String scripts) { .flatMap(it -> it.findElements(By.className("btn-edit")).stream())
fileList() .filter(WebElement::isDisplayed)
.stream() .findFirst()
.filter(it -> it.getText().contains(fileName)) .orElseThrow(() -> new RuntimeException("No edit button in file manage list"))
.flatMap(it -> it.findElements(By.className("btn-edit")).stream()) .click();
.filter(WebElement::isDisplayed)
.findFirst() WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/edit"));
.orElseThrow(() -> new RuntimeException("No edit button in file manage list"))
.click(); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.tagName("body")), fileName));
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/edit"));
editFileBox().codeEditor().content(scripts);
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.tagName("body")), fileName)); editFileBox().buttonSubmit().click();
editFileBox().codeEditor().content(scripts); return this;
editFileBox().buttonSubmit().click(); }
return this; public FileManagePage uploadFile(String filePath) {
} buttonUploadFile().click();
public FileManagePage uploadFile(String filePath) { driver.setFileDetector(new LocalFileDetector());
buttonUploadFile().click();
uploadFileBox().buttonUpload().sendKeys(filePath);
driver.setFileDetector(new LocalFileDetector()); uploadFileBox().buttonSubmit().click();
uploadFileBox().buttonUpload().sendKeys(filePath); return this;
uploadFileBox().buttonSubmit().click(); }
return this; public FileManagePage downloadFile(String fileName) {
} fileList()
.stream()
public FileManagePage downloadFile(String fileName) { .filter(it -> it.getText().contains(fileName))
fileList() .flatMap(it -> it.findElements(By.className("btn-download")).stream())
.stream() .filter(WebElement::isDisplayed)
.filter(it -> it.getText().contains(fileName)) .findFirst()
.flatMap(it -> it.findElements(By.className("btn-download")).stream()) .orElseThrow(() -> new RuntimeException("No download button in file manage list"))
.filter(WebElement::isDisplayed) .click();
.findFirst()
.orElseThrow(() -> new RuntimeException("No download button in file manage list")) return this;
.click(); }
return this; @Getter
} public class CreateDirectoryBox {
@Getter CreateDirectoryBox() {
public class CreateDirectoryBox { PageFactory.initElements(driver, this);
CreateDirectoryBox() { }
PageFactory.initElements(driver, this);
} @FindBys({
@FindBy(className = "input-directory-name"),
@FindBys({ @FindBy(tagName = "input"),
@FindBy(className = "input-directory-name"), })
@FindBy(tagName = "input"), private WebElement inputDirectoryName;
})
private WebElement inputDirectoryName; @FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-submit")
private WebElement buttonSubmit; @FindBy(className = "btn-cancel")
private WebElement buttonCancel;
@FindBy(className = "btn-cancel") }
private WebElement buttonCancel;
} @Getter
public class RenameBox {
@Getter
public class RenameBox { RenameBox() {
RenameBox() { PageFactory.initElements(driver, this);
PageFactory.initElements(driver, this); }
}
@FindBys({
@FindBys({ @FindBy(className = "input-name"),
@FindBy(className = "input-name"), @FindBy(tagName = "input"),
@FindBy(tagName = "input"), })
}) private WebElement inputName;
private WebElement inputName;
@FindBy(className = "btn-submit")
@FindBy(className = "btn-submit") private WebElement buttonSubmit;
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
@FindBy(className = "btn-cancel") private WebElement buttonCancel;
private WebElement buttonCancel; }
}
@Getter
@Getter public class CreateFileBox {
public class CreateFileBox {
CreateFileBox() { CreateFileBox() {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBys({ @FindBys({
@FindBy(className = "input-file-name"), @FindBy(className = "input-file-name"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private WebElement inputFileName; private WebElement inputFileName;
private final CodeEditor codeEditor = new CodeEditor(driver); private final CodeEditor codeEditor = new CodeEditor(driver);
@FindBy(className = "btn-submit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(className = "btn-cancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
@Getter @Getter
public class EditFileBox { public class EditFileBox {
EditFileBox() {
PageFactory.initElements(driver, this); EditFileBox() {
} PageFactory.initElements(driver, this);
}
CodeEditor codeEditor = new CodeEditor(driver);
CodeEditor codeEditor = new CodeEditor(driver);
@FindBy(className = "btn-submit")
private WebElement buttonSubmit; @FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel; @FindBy(className = "btn-cancel")
} private WebElement buttonCancel;
}
@Getter
public class UploadFileBox { @Getter
UploadFileBox() { public class UploadFileBox {
PageFactory.initElements(driver, this);
} UploadFileBox() {
PageFactory.initElements(driver, this);
@FindBys({ }
@FindBy(className = "btn-upload"),
@FindBy(tagName = "input"), @FindBys({
}) @FindBy(className = "btn-upload"),
private WebElement buttonUpload; @FindBy(tagName = "input"),
})
@FindBy(className = "btn-submit") private WebElement buttonUpload;
private WebElement buttonSubmit;
@FindBy(className = "btn-submit")
@FindBy(className = "btn-cancel") private WebElement buttonSubmit;
private WebElement buttonCancel;
} @FindBy(className = "btn-cancel")
} private WebElement buttonCancel;
}
}

124
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java

@ -1,63 +1,61 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information * distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the * KIND, either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
* *
*/ */
package org.apache.dolphinscheduler.e2e.pages.resource; package org.apache.dolphinscheduler.e2e.pages.resource;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.time.Duration; import lombok.Getter;
import org.openqa.selenium.JavascriptExecutor; 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;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@Getter
import lombok.Getter; public class ResourcePage extends NavBarPage implements NavBarPage.NavBarItem {
@FindBy(css = ".tab-vertical > .n-menu-item:nth-child(1) > .n-menu-item-content")
@Getter private WebElement fileManageTab;
public class ResourcePage extends NavBarPage implements NavBarPage.NavBarItem {
@FindBy(css = ".tab-vertical > .n-menu-item:nth-child(1) > .n-menu-item-content") public ResourcePage(RemoteWebDriver driver) {
private WebElement fileManageTab; super(driver);
public ResourcePage(RemoteWebDriver driver) { PageFactory.initElements(driver, this);
super(driver); }
PageFactory.initElements(driver, this); public <T extends ResourcePage.Tab> T goToTab(Class<T> tab) {
} if (tab == FileManagePage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource"));
public <T extends ResourcePage.Tab> T goToTab(Class<T> tab) { WebDriverWaitFactory.createWebDriverWait(driver)
if (tab == FileManagePage.class) { .until(ExpectedConditions.elementToBeClickable(fileManageTab));
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource")); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", fileManageTab());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(fileManageTab)); WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/file-manage"));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", fileManageTab()); return tab.cast(new FileManagePage(driver));
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/file-manage")); }
return tab.cast(new FileManagePage(driver));
} throw new UnsupportedOperationException("Unknown tab: " + tab.getName());
}
throw new UnsupportedOperationException("Unknown tab: " + tab.getName());
} public interface Tab {
}
public interface Tab { }
}
}

29
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/ClusterPage.java

@ -23,6 +23,8 @@ import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.util.List; import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys; import org.openqa.selenium.Keys;
@ -31,13 +33,10 @@ import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
@Getter @Getter
public final class ClusterPage extends NavBarPage implements SecurityPage.Tab { public final class ClusterPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-cluster") @FindBy(className = "btn-create-cluster")
private WebElement buttonCreateCluster; private WebElement buttonCreateCluster;
@ -45,8 +44,8 @@ public final class ClusterPage extends NavBarPage implements SecurityPage.Tab {
private List<WebElement> clusterList; private List<WebElement> clusterList;
@FindBys({ @FindBys({
@FindBy(className = "n-popconfirm__action"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"), @FindBy(className = "n-button--primary-type"),
}) })
private WebElement buttonConfirm; private WebElement buttonConfirm;
@ -79,7 +78,6 @@ public final class ClusterPage extends NavBarPage implements SecurityPage.Tab {
.orElseThrow(() -> new RuntimeException("No edit button in cluster list")) .orElseThrow(() -> new RuntimeException("No edit button in cluster list"))
.click(); .click();
editClusterForm().inputClusterName().sendKeys(Keys.CONTROL + "a"); editClusterForm().inputClusterName().sendKeys(Keys.CONTROL + "a");
editClusterForm().inputClusterName().sendKeys(Keys.BACK_SPACE); editClusterForm().inputClusterName().sendKeys(Keys.BACK_SPACE);
editClusterForm().inputClusterName().sendKeys(name); editClusterForm().inputClusterName().sendKeys(name);
@ -114,31 +112,32 @@ public final class ClusterPage extends NavBarPage implements SecurityPage.Tab {
@Getter @Getter
public class ClusterForm { public class ClusterForm {
ClusterForm() { ClusterForm() {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBys({ @FindBys({
@FindBy(className = "input-cluster-name"), @FindBy(className = "input-cluster-name"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private WebElement inputClusterName; private WebElement inputClusterName;
@FindBys({ @FindBys({
@FindBy(className = "input-cluster-config"), @FindBy(className = "input-cluster-config"),
@FindBy(tagName = "textarea"), @FindBy(tagName = "textarea"),
}) })
private WebElement inputClusterConfig; private WebElement inputClusterConfig;
@FindBys({ @FindBys({
@FindBy(className = "input-cluster-desc"), @FindBy(className = "input-cluster-desc"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private WebElement inputClusterDesc; private WebElement inputClusterDesc;
@FindBys({ @FindBys({
@FindBy(className = "n-base-selection-tags"), @FindBy(className = "n-base-selection-tags"),
@FindBy(className = "n-tag__content"), @FindBy(className = "n-tag__content"),
}) })
private WebElement selectedWorkerGroup; private WebElement selectedWorkerGroup;

42
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java

@ -22,9 +22,10 @@ package org.apache.dolphinscheduler.e2e.pages.security;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.time.Duration;
import java.util.List; import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys; import org.openqa.selenium.Keys;
@ -33,13 +34,11 @@ import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@Getter @Getter
public final class EnvironmentPage extends NavBarPage implements SecurityPage.Tab { public final class EnvironmentPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-environment") @FindBy(className = "btn-create-environment")
private WebElement buttonCreateEnvironment; private WebElement buttonCreateEnvironment;
@ -47,8 +46,8 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
private List<WebElement> environmentList; private List<WebElement> environmentList;
@FindBys({ @FindBys({
@FindBy(className = "n-popconfirm__action"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"), @FindBy(className = "n-button--primary-type"),
}) })
private WebElement buttonConfirm; private WebElement buttonConfirm;
@ -68,8 +67,9 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
createEnvironmentForm().inputEnvironmentDesc().sendKeys(desc); createEnvironmentForm().inputEnvironmentDesc().sendKeys(desc);
editEnvironmentForm().btnSelectWorkerGroupDropdown().click(); editEnvironmentForm().btnSelectWorkerGroupDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( WebDriverWaitFactory.createWebDriverWait(driver)
"n-base-select-option__content"))); .until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
editEnvironmentForm().selectWorkerGroupList() editEnvironmentForm().selectWorkerGroupList()
.stream() .stream()
.filter(it -> it.getText().contains(workerGroup)) .filter(it -> it.getText().contains(workerGroup))
@ -85,14 +85,14 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
public EnvironmentPage update(String oldName, String name, String config, String desc, String workerGroup) { public EnvironmentPage update(String oldName, String name, String config, String desc, String workerGroup) {
environmentList() environmentList()
.stream() .stream()
.filter(it -> it.findElement(By.className("environment-name")).getAttribute("innerHTML").contains(oldName)) .filter(it -> it.findElement(By.className("environment-name")).getAttribute("innerHTML")
.contains(oldName))
.flatMap(it -> it.findElements(By.className("edit")).stream()) .flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in environment list")) .orElseThrow(() -> new RuntimeException("No edit button in environment list"))
.click(); .click();
editEnvironmentForm().inputEnvironmentName().sendKeys(Keys.CONTROL + "a"); editEnvironmentForm().inputEnvironmentName().sendKeys(Keys.CONTROL + "a");
editEnvironmentForm().inputEnvironmentName().sendKeys(Keys.BACK_SPACE); editEnvironmentForm().inputEnvironmentName().sendKeys(Keys.BACK_SPACE);
editEnvironmentForm().inputEnvironmentName().sendKeys(name); editEnvironmentForm().inputEnvironmentName().sendKeys(name);
@ -107,8 +107,9 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
if (editEnvironmentForm().selectedWorkerGroup().getAttribute("innerHTML").equals(workerGroup)) { if (editEnvironmentForm().selectedWorkerGroup().getAttribute("innerHTML").equals(workerGroup)) {
editEnvironmentForm().btnSelectWorkerGroupDropdown().click(); editEnvironmentForm().btnSelectWorkerGroupDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( WebDriverWaitFactory.createWebDriverWait(driver)
"n-base-select-option__content"))); .until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
editEnvironmentForm().selectWorkerGroupList() editEnvironmentForm().selectWorkerGroupList()
.stream() .stream()
.filter(it -> it.getText().contains(workerGroup)) .filter(it -> it.getText().contains(workerGroup))
@ -140,25 +141,26 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
@Getter @Getter
public class EnvironmentForm { public class EnvironmentForm {
EnvironmentForm() { EnvironmentForm() {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBys({ @FindBys({
@FindBy(className = "input-environment-name"), @FindBy(className = "input-environment-name"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private WebElement inputEnvironmentName; private WebElement inputEnvironmentName;
@FindBys({ @FindBys({
@FindBy(className = "input-environment-config"), @FindBy(className = "input-environment-config"),
@FindBy(tagName = "textarea"), @FindBy(tagName = "textarea"),
}) })
private WebElement inputEnvironmentConfig; private WebElement inputEnvironmentConfig;
@FindBys({ @FindBys({
@FindBy(className = "input-environment-desc"), @FindBy(className = "input-environment-desc"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private WebElement inputEnvironmentDesc; private WebElement inputEnvironmentDesc;
@ -172,8 +174,8 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
private List<WebElement> selectWorkerGroupList; private List<WebElement> selectWorkerGroupList;
@FindBys({ @FindBys({
@FindBy(className = "n-base-selection-tags"), @FindBy(className = "n-base-selection-tags"),
@FindBy(className = "n-tag__content"), @FindBy(className = "n-tag__content"),
}) })
private WebElement selectedWorkerGroup; private WebElement selectedWorkerGroup;

9
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/NamespacePage.java

@ -23,16 +23,17 @@ import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.util.List; import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
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;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter;
@Getter @Getter
public final class NamespacePage extends NavBarPage implements SecurityPage.Tab { public final class NamespacePage extends NavBarPage implements SecurityPage.Tab {
@FindBy(id = "btnCreateNamespace") @FindBy(id = "btnCreateNamespace")
private WebElement buttonCreateNamespace; private WebElement buttonCreateNamespace;
@ -59,7 +60,8 @@ public final class NamespacePage extends NavBarPage implements SecurityPage.Tab
public NamespacePage update(String namespaceName, String editNamespaceName, String editNamespaceValue) { public NamespacePage update(String namespaceName, String editNamespaceName, String editNamespaceValue) {
namespaceList() namespaceList()
.stream() .stream()
.filter(it -> it.findElement(By.className("namespaceName")).getAttribute("innerHTML").contains(namespaceName)) .filter(it -> it.findElement(By.className("namespaceName")).getAttribute("innerHTML")
.contains(namespaceName))
.flatMap(it -> it.findElements(By.className("edit")).stream()) .flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
@ -75,6 +77,7 @@ public final class NamespacePage extends NavBarPage implements SecurityPage.Tab
@Getter @Getter
public class NamespaceForm { public class NamespaceForm {
NamespaceForm() { NamespaceForm() {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }

11
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/QueuePage.java

@ -21,9 +21,10 @@ package org.apache.dolphinscheduler.e2e.pages.security;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.security.Key;
import java.util.List; import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.Keys; import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
@ -32,10 +33,9 @@ import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter;
@Getter @Getter
public final class QueuePage extends NavBarPage implements SecurityPage.Tab { public final class QueuePage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-queue") @FindBy(className = "btn-create-queue")
private WebElement buttonCreateQueue; private WebElement buttonCreateQueue;
@ -84,13 +84,14 @@ public final class QueuePage extends NavBarPage implements SecurityPage.Tab {
@Getter @Getter
public class QueueForm { public class QueueForm {
QueueForm() { QueueForm() {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBys({ @FindBys({
@FindBy(className = "input-queue-name"), @FindBy(className = "input-queue-name"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private WebElement inputQueueName; private WebElement inputQueueName;

56
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java

@ -24,17 +24,13 @@ import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage.NavBarItem; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage.NavBarItem;
import lombok.Getter;
import org.openqa.selenium.JavascriptExecutor; 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;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
import java.time.Duration;
@Getter @Getter
public class SecurityPage extends NavBarPage implements NavBarItem { public class SecurityPage extends NavBarPage implements NavBarItem {
@ -70,58 +66,74 @@ public class SecurityPage extends NavBarPage implements NavBarItem {
public <T extends SecurityPage.Tab> T goToTab(Class<T> tab) { public <T extends SecurityPage.Tab> T goToTab(Class<T> tab) {
if (tab == TenantPage.class) { if (tab == TenantPage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuTenantManage)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(menuTenantManage));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuTenantManage()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuTenantManage());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/tenant-manage")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/tenant-manage"));
return tab.cast(new TenantPage(driver)); return tab.cast(new TenantPage(driver));
} }
if (tab == UserPage.class) { if (tab == UserPage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menUserManage)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(menUserManage));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", menUserManage()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menUserManage());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/user-manage")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/user-manage"));
return tab.cast(new UserPage(driver)); return tab.cast(new UserPage(driver));
} }
if (tab == WorkerGroupPage.class) { if (tab == WorkerGroupPage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menWorkerGroupManage)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(menWorkerGroupManage));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", menWorkerGroupManage()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menWorkerGroupManage());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/worker-group-manage")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/worker-group-manage"));
return tab.cast(new WorkerGroupPage(driver)); return tab.cast(new WorkerGroupPage(driver));
} }
if (tab == QueuePage.class) { if (tab == QueuePage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuQueueManage)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(menuQueueManage));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuQueueManage()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuQueueManage());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/yarn-queue-manage")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/yarn-queue-manage"));
return tab.cast(new QueuePage(driver)); return tab.cast(new QueuePage(driver));
} }
if (tab == EnvironmentPage.class) { if (tab == EnvironmentPage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuEnvironmentManage)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(menuEnvironmentManage));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuEnvironmentManage()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuEnvironmentManage());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/environment-manage")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/environment-manage"));
return tab.cast(new EnvironmentPage(driver)); return tab.cast(new EnvironmentPage(driver));
} }
if (tab == ClusterPage.class) { if (tab == ClusterPage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuClusterManage)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(menuClusterManage));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuClusterManage()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuClusterManage());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/cluster-manage")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/cluster-manage"));
return tab.cast(new ClusterPage(driver)); return tab.cast(new ClusterPage(driver));
} }
if (tab == TokenPage.class) { if (tab == TokenPage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuTokenManage)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(menuTokenManage));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuTokenManage()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuTokenManage());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/token-manage")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/token-manage"));
return tab.cast(new TokenPage(driver)); return tab.cast(new TokenPage(driver));
} }
if (tab == NamespacePage.class) { if (tab == NamespacePage.class) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuNamespaceManage)); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(menuNamespaceManage));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuNamespaceManage()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuNamespaceManage());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/k8s-namespace-manage")); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/k8s-namespace-manage"));
return tab.cast(new NamespacePage(driver)); return tab.cast(new NamespacePage(driver));
} }

15
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java

@ -19,14 +19,15 @@
package org.apache.dolphinscheduler.e2e.pages.security; package org.apache.dolphinscheduler.e2e.pages.security;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.apache.dolphinscheduler.e2e.models.tenant.ITenant; import org.apache.dolphinscheduler.e2e.models.tenant.ITenant;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys; import org.openqa.selenium.Keys;
@ -36,13 +37,9 @@ import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter;
import org.openqa.selenium.support.pagefactory.ByChained;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
@Getter @Getter
public final class TenantPage extends NavBarPage implements SecurityPage.Tab { public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-tenant") @FindBy(className = "btn-create-tenant")
private WebElement buttonCreateTenant; private WebElement buttonCreateTenant;
@ -132,6 +129,7 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
@Getter @Getter
public class TenantForm { public class TenantForm {
TenantForm() { TenantForm() {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@ -160,6 +158,7 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
@RequiredArgsConstructor @RequiredArgsConstructor
public static class Row { public static class Row {
private final WebElement row; private final WebElement row;
public String tenantCode() { public String tenantCode() {

73
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java

@ -23,9 +23,10 @@ import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage.Tab; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage.Tab;
import java.time.Duration;
import java.util.List; import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
@ -34,14 +35,12 @@ import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
import com.google.common.base.Strings; import com.google.common.base.Strings;
@Getter @Getter
public final class TokenPage extends NavBarPage implements Tab { public final class TokenPage extends NavBarPage implements Tab {
@FindBy(className = "btn-create-token") @FindBy(className = "btn-create-token")
private WebElement buttonCreateToken; private WebElement buttonCreateToken;
@ -49,8 +48,8 @@ public final class TokenPage extends NavBarPage implements Tab {
private List<WebElement> tokenList; private List<WebElement> tokenList;
@FindBys({ @FindBys({
@FindBy(className = "n-popconfirm__action"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"), @FindBy(className = "n-button--primary-type"),
}) })
private WebElement buttonConfirm; private WebElement buttonConfirm;
@ -70,10 +69,12 @@ public final class TokenPage extends NavBarPage implements Tab {
public TokenPage create(String userName) { public TokenPage create(String userName) {
buttonCreateToken().click(); buttonCreateToken().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(createTokenForm().selectUserNameDropdown())); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(createTokenForm().selectUserNameDropdown()));
createTokenForm().selectUserNameDropdown().click(); createTokenForm().selectUserNameDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( WebDriverWaitFactory.createWebDriverWait(driver)
"n-base-select-option__content"))); .until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
createTokenForm().selectUserNameList() createTokenForm().selectUserNameList()
.stream() .stream()
.filter(it -> it.getText().contains(userName)) .filter(it -> it.getText().contains(userName))
@ -82,7 +83,8 @@ public final class TokenPage extends NavBarPage implements Tab {
userName))) userName)))
.click(); .click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(createTokenForm().buttonGenerateToken())); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(createTokenForm().buttonGenerateToken()));
createTokenForm().buttonGenerateToken().click(); createTokenForm().buttonGenerateToken().click();
createTokenForm().buttonSubmit().click(); createTokenForm().buttonSubmit().click();
@ -92,16 +94,18 @@ public final class TokenPage extends NavBarPage implements Tab {
public TokenPage update(String userName) { public TokenPage update(String userName) {
tokenList().stream() tokenList().stream()
.filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName)) .filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName))
.flatMap(it -> it.findElements(By.className("edit")).stream()) .flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in token list")) .orElseThrow(() -> new RuntimeException("No edit button in token list"))
.click(); .click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken())); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken()));
editTokenForm().buttonGenerateToken().click(); editTokenForm().buttonGenerateToken().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken())); WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken()));
editTokenForm().buttonSubmit().click(); editTokenForm().buttonSubmit().click();
@ -110,23 +114,23 @@ public final class TokenPage extends NavBarPage implements Tab {
public String getToken(String userName) { public String getToken(String userName) {
return tokenList().stream() return tokenList().stream()
.filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName)) .filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName))
.flatMap(it -> it.findElements(By.className("token")).stream()) .flatMap(it -> it.findElements(By.className("token")).stream())
.filter(it -> !Strings.isNullOrEmpty(it.getAttribute("innerHTML"))) .filter(it -> !Strings.isNullOrEmpty(it.getAttribute("innerHTML")))
.map(it -> it.getAttribute("innerHTML")) .map(it -> it.getAttribute("innerHTML"))
.findFirst() .findFirst()
.orElseThrow(() -> new IllegalArgumentException("No token for such user: " + userName)); .orElseThrow(() -> new IllegalArgumentException("No token for such user: " + userName));
} }
public TokenPage delete(String userName) { public TokenPage delete(String userName) {
tokenList() tokenList()
.stream() .stream()
.filter(it -> it.getText().contains(userName)) .filter(it -> it.getText().contains(userName))
.flatMap(it -> it.findElements(By.className("delete")).stream()) .flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in token list")) .orElseThrow(() -> new RuntimeException("No delete button in token list"))
.click(); .click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
@ -135,13 +139,14 @@ public final class TokenPage extends NavBarPage implements Tab {
@Getter @Getter
public class TokenForm { public class TokenForm {
TokenForm() { TokenForm() {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBys({ @FindBys({
@FindBy(className = "input-username"), @FindBy(className = "input-username"),
@FindBy(className = "n-base-selection"), @FindBy(className = "n-base-selection"),
}) })
private WebElement selectUserNameDropdown; private WebElement selectUserNameDropdown;

79
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java

@ -23,9 +23,10 @@ import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.models.users.IUser; import org.apache.dolphinscheduler.e2e.models.users.IUser;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.time.Duration;
import java.util.List; import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys; import org.openqa.selenium.Keys;
@ -34,13 +35,11 @@ import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@Getter @Getter
public final class UserPage extends NavBarPage implements SecurityPage.Tab { public final class UserPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-user") @FindBy(className = "btn-create-user")
private WebElement buttonCreateUser; private WebElement buttonCreateUser;
@ -48,15 +47,14 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
private List<WebElement> userList; private List<WebElement> userList;
@FindBys({ @FindBys({
@FindBy(className = "n-popconfirm__action"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"), @FindBy(className = "n-button--primary-type"),
}) })
private WebElement buttonConfirm; private WebElement buttonConfirm;
private final UserForm createUserForm = new UserForm(); private final UserForm createUserForm = new UserForm();
private final UserForm editUserForm = new UserForm(); private final UserForm editUserForm = new UserForm();
public UserPage(RemoteWebDriver driver) { public UserPage(RemoteWebDriver driver) {
super(driver); super(driver);
} }
@ -69,15 +67,16 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
createUserForm().btnSelectTenantDropdown().click(); createUserForm().btnSelectTenantDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( WebDriverWaitFactory.createWebDriverWait(driver)
"n-base-select-option__content"))); .until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
createUserForm().selectTenant() createUserForm().selectTenant()
.stream() .stream()
.filter(it -> it.getText().contains(tenant)) .filter(it -> it.getText().contains(tenant))
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException(String.format("No %s in tenant dropdown list", tenant))) .orElseThrow(() -> new RuntimeException(String.format("No %s in tenant dropdown list", tenant)))
.click(); .click();
createUserForm().inputEmail().sendKeys(email); createUserForm().inputEmail().sendKeys(email);
createUserForm().inputPhone().sendKeys(phone); createUserForm().inputPhone().sendKeys(phone);
@ -101,21 +100,22 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
String editPhone, String editPhone,
String tenant) { String tenant) {
userList().stream() userList().stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user)) .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user))
.flatMap(it -> it.findElements(By.className("edit")).stream()) .flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in user list")) .orElseThrow(() -> new RuntimeException("No edit button in user list"))
.click(); .click();
editUserForm().inputUserName().sendKeys(Keys.CONTROL+"a"); editUserForm().inputUserName().sendKeys(Keys.CONTROL + "a");
editUserForm().inputUserName().sendKeys(Keys.BACK_SPACE); editUserForm().inputUserName().sendKeys(Keys.BACK_SPACE);
editUserForm().inputUserName().sendKeys(editUser); editUserForm().inputUserName().sendKeys(editUser);
createUserForm().btnSelectTenantDropdown().click(); createUserForm().btnSelectTenantDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( WebDriverWaitFactory.createWebDriverWait(driver)
"n-base-select-option__content"))); .until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
createUserForm().selectTenant() createUserForm().selectTenant()
.stream() .stream()
@ -124,11 +124,11 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
.orElseThrow(() -> new RuntimeException(String.format("No %s in tenant dropdown list", tenant))) .orElseThrow(() -> new RuntimeException(String.format("No %s in tenant dropdown list", tenant)))
.click(); .click();
editUserForm().inputEmail().sendKeys(Keys.CONTROL+"a"); editUserForm().inputEmail().sendKeys(Keys.CONTROL + "a");
editUserForm().inputEmail().sendKeys(Keys.BACK_SPACE); editUserForm().inputEmail().sendKeys(Keys.BACK_SPACE);
editUserForm().inputEmail().sendKeys(editEmail); editUserForm().inputEmail().sendKeys(editEmail);
editUserForm().inputPhone().sendKeys(Keys.CONTROL+"a"); editUserForm().inputPhone().sendKeys(Keys.CONTROL + "a");
editUserForm().inputPhone().sendKeys(Keys.BACK_SPACE); editUserForm().inputPhone().sendKeys(Keys.BACK_SPACE);
editUserForm().inputPhone().sendKeys(editPhone); editUserForm().inputPhone().sendKeys(editPhone);
@ -139,13 +139,13 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
public UserPage delete(String user) { public UserPage delete(String user) {
userList() userList()
.stream() .stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user)) .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user))
.flatMap(it -> it.findElements(By.className("delete")).stream()) .flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in user list")) .orElseThrow(() -> new RuntimeException("No delete button in user list"))
.click(); .click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
@ -154,25 +154,26 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
@Getter @Getter
public class UserForm { public class UserForm {
UserForm() { UserForm() {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBys({ @FindBys({
@FindBy(className = "input-username"), @FindBy(className = "input-username"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private WebElement inputUserName; private WebElement inputUserName;
@FindBys({ @FindBys({
@FindBy(className = "input-password"), @FindBy(className = "input-password"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private WebElement inputUserPassword; private WebElement inputUserPassword;
@FindBys({ @FindBys({
@FindBy(className = "select-tenant"), @FindBy(className = "select-tenant"),
@FindBy(className = "n-base-selection"), @FindBy(className = "n-base-selection"),
}) })
private WebElement btnSelectTenantDropdown; private WebElement btnSelectTenantDropdown;

40
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/WorkerGroupPage.java

@ -19,8 +19,12 @@
package org.apache.dolphinscheduler.e2e.pages.security; package org.apache.dolphinscheduler.e2e.pages.security;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys; import org.openqa.selenium.Keys;
@ -30,11 +34,9 @@ import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import java.util.List;
@Getter @Getter
public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Tab { public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-worker-group") @FindBy(className = "btn-create-worker-group")
private WebElement buttonCreateWorkerGroup; private WebElement buttonCreateWorkerGroup;
@ -42,16 +44,14 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
private List<WebElement> workerGroupList; private List<WebElement> workerGroupList;
@FindBys({ @FindBys({
@FindBy(className = "n-popconfirm__action"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"), @FindBy(className = "n-button--primary-type"),
}) })
private WebElement buttonConfirm; private WebElement buttonConfirm;
private final WorkerGroupForm createWorkerForm = new WorkerGroupForm(); private final WorkerGroupForm createWorkerForm = new WorkerGroupForm();
private final WorkerGroupForm editWorkerForm = new WorkerGroupForm(); private final WorkerGroupForm editWorkerForm = new WorkerGroupForm();
public WorkerGroupPage(RemoteWebDriver driver) { public WorkerGroupPage(RemoteWebDriver driver) {
super(driver); super(driver);
} }
@ -87,16 +87,15 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
return this; return this;
} }
public WorkerGroupPage delete(String Worker) { public WorkerGroupPage delete(String Worker) {
workerGroupList() workerGroupList()
.stream() .stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(Worker)) .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(Worker))
.flatMap(it -> it.findElements(By.className("delete")).stream()) .flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in workerGroup list")) .orElseThrow(() -> new RuntimeException("No delete button in workerGroup list"))
.click(); .click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
@ -105,19 +104,20 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
@Getter @Getter
public class WorkerGroupForm { public class WorkerGroupForm {
WorkerGroupForm() { WorkerGroupForm() {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBys({ @FindBys({
@FindBy(className = "input-worker-group-name"), @FindBy(className = "input-worker-group-name"),
@FindBy(tagName = "input"), @FindBy(tagName = "input"),
}) })
private WebElement inputWorkerGroupName; private WebElement inputWorkerGroupName;
@FindBys({ @FindBys({
@FindBy(className = "select-worker-address"), @FindBy(className = "select-worker-address"),
@FindBy(className = "n-base-selection"), @FindBy(className = "n-base-selection"),
}) })
private WebElement btnSelectWorkerAddress; private WebElement btnSelectWorkerAddress;

5
dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/Constants.java

@ -17,13 +17,14 @@
package org.apache.dolphinscheduler.e2e.core; package org.apache.dolphinscheduler.e2e.core;
import lombok.experimental.UtilityClass;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import lombok.experimental.UtilityClass;
@UtilityClass @UtilityClass
public final class Constants { public final class Constants {
/** /**
* tmp directory path * tmp directory path
*/ */

1
dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinScheduler.java

@ -37,5 +37,6 @@ import org.testcontainers.junit.jupiter.Testcontainers;
@TestMethodOrder(OrderAnnotation.class) @TestMethodOrder(OrderAnnotation.class)
@ExtendWith(DolphinSchedulerExtension.class) @ExtendWith(DolphinSchedulerExtension.class)
public @interface DolphinScheduler { public @interface DolphinScheduler {
String[] composeFiles(); String[] composeFiles();
} }

37
dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java

@ -37,6 +37,8 @@ import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.BeforeEachCallback;
@ -54,10 +56,9 @@ import org.testcontainers.utility.DockerImageName;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.net.HostAndPort; import com.google.common.net.HostAndPort;
import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback { final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback {
private final boolean LOCAL_MODE = Objects.equals(System.getProperty("local"), "true"); private final boolean LOCAL_MODE = Objects.equals(System.getProperty("local"), "true");
private final boolean M1_CHIP_FLAG = Objects.equals(System.getProperty("m1_chip"), "true"); private final boolean M1_CHIP_FLAG = Objects.equals(System.getProperty("m1_chip"), "true");
@ -101,10 +102,10 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
driver = new RemoteWebDriver(browser.getSeleniumAddress(), new ChromeOptions()); driver = new RemoteWebDriver(browser.getSeleniumAddress(), new ChromeOptions());
driver.manage().timeouts() driver.manage().timeouts()
.implicitlyWait(Duration.ofSeconds(10)) .implicitlyWait(Duration.ofSeconds(10))
.pageLoadTimeout(Duration.ofSeconds(10)); .pageLoadTimeout(Duration.ofSeconds(10));
driver.manage().window() driver.manage().window()
.maximize(); .maximize();
driver.get(new URL("http", address.getHost(), address.getPort(), rootPath).toString()); driver.get(new URL("http", address.getHost(), address.getPort(), rootPath).toString());
@ -112,9 +113,9 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
final Class<?> clazz = context.getRequiredTestClass(); final Class<?> clazz = context.getRequiredTestClass();
Stream.of(clazz.getDeclaredFields()) Stream.of(clazz.getDeclaredFields())
.filter(it -> Modifier.isStatic(it.getModifiers())) .filter(it -> Modifier.isStatic(it.getModifiers()))
.filter(f -> WebDriver.class.isAssignableFrom(f.getType())) .filter(f -> WebDriver.class.isAssignableFrom(f.getType()))
.forEach(it -> setDriver(clazz, it)); .forEach(it -> setDriver(clazz, it));
WebDriverHolder.setWebDriver(driver); WebDriverHolder.setWebDriver(driver);
} }
@ -128,7 +129,8 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
compose = createDockerCompose(context); compose = createDockerCompose(context);
compose.start(); compose.start();
address = HostAndPort.fromParts("host.testcontainers.internal", compose.getServicePort(serviceName, DOCKER_PORT)); address =
HostAndPort.fromParts("host.testcontainers.internal", compose.getServicePort(serviceName, DOCKER_PORT));
rootPath = "/dolphinscheduler/ui/"; rootPath = "/dolphinscheduler/ui/";
} }
@ -183,8 +185,8 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
public void beforeEach(ExtensionContext context) { public void beforeEach(ExtensionContext context) {
final Object instance = context.getRequiredTestInstance(); final Object instance = context.getRequiredTestInstance();
Stream.of(instance.getClass().getDeclaredFields()) Stream.of(instance.getClass().getDeclaredFields())
.filter(f -> WebDriver.class.isAssignableFrom(f.getType())) .filter(f -> WebDriver.class.isAssignableFrom(f.getType()))
.forEach(it -> setDriver(instance, it)); .forEach(it -> setDriver(instance, it));
} }
private void setDriver(Object object, Field field) { private void setDriver(Object object, Field field) {
@ -200,13 +202,13 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
final Class<?> clazz = context.getRequiredTestClass(); final Class<?> clazz = context.getRequiredTestClass();
final DolphinScheduler annotation = clazz.getAnnotation(DolphinScheduler.class); final DolphinScheduler annotation = clazz.getAnnotation(DolphinScheduler.class);
final List<File> files = Stream.of(annotation.composeFiles()) final List<File> files = Stream.of(annotation.composeFiles())
.map(it -> DolphinScheduler.class.getClassLoader().getResource(it)) .map(it -> DolphinScheduler.class.getClassLoader().getResource(it))
.filter(Objects::nonNull) .filter(Objects::nonNull)
.map(URL::getPath) .map(URL::getPath)
.map(File::new) .map(File::new)
.collect(Collectors.toList()); .collect(Collectors.toList());
ComposeContainer compose = new ComposeContainer(files) ComposeContainer compose = new ComposeContainer(files)
.withPull(true) .withPull(true)
.withTailChildContainers(true) .withTailChildContainers(true)
.withLocalCompose(true) .withLocalCompose(true)
@ -216,7 +218,6 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
.withLogConsumer(serviceName, outputFrame -> LOGGER.info(outputFrame.getUtf8String())) .withLogConsumer(serviceName, outputFrame -> LOGGER.info(outputFrame.getUtf8String()))
.waitingFor(serviceName, Wait.forHealthcheck().withStartupTimeout(Duration.ofSeconds(300))); .waitingFor(serviceName, Wait.forHealthcheck().withStartupTimeout(Duration.ofSeconds(300)));
return compose; return compose;
} }
} }

5
dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/TestDescription.java

@ -24,12 +24,13 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import org.junit.jupiter.api.extension.ExtensionContext;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.junit.jupiter.api.extension.ExtensionContext;
@RequiredArgsConstructor @RequiredArgsConstructor
final class TestDescription implements org.testcontainers.lifecycle.TestDescription { final class TestDescription implements org.testcontainers.lifecycle.TestDescription {
private static final String UNKNOWN_NAME = "unknown"; private static final String UNKNOWN_NAME = "unknown";
private final ExtensionContext context; private final ExtensionContext context;

1
dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java

@ -18,6 +18,7 @@
package org.apache.dolphinscheduler.e2e.core; package org.apache.dolphinscheduler.e2e.core;
import java.time.Duration; import java.time.Duration;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.WebDriverWait;

4
dolphinscheduler-e2e/pom.xml

@ -31,8 +31,8 @@
</modules> </modules>
<properties> <properties>
<maven.compiler.source>8</maven.compiler.source> <maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target> <maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.8.1</junit.version> <junit.version>5.8.1</junit.version>

8
pom.xml

@ -707,6 +707,14 @@
<searchRegex>import\s+io\.kubernetes\.client\.[^\*\s]*(|\*);(\r\n|\r|\n)</searchRegex> <searchRegex>import\s+io\.kubernetes\.client\.[^\*\s]*(|\*);(\r\n|\r|\n)</searchRegex>
<replacement>$1</replacement> <replacement>$1</replacement>
</replaceRegex> </replaceRegex>
<includes>
<include>src/main/java/**/*.java</include>
<include>src/test/java/**/*.java</include>
<include>dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/**/*.java</include>
<include>dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/**/*.java</include>
<include>dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/**/*.java</include>
<include>dolphinscheduler-api-test/dolphinscheduler-api-test-core/src/main/java/**/*.java</include>
</includes>
</java> </java>
<pom> <pom>
<sortPom> <sortPom>

Loading…
Cancel
Save