Browse Source

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

dev
xiangzihao 4 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: |
./mvnw -B -f dolphinscheduler-api-test/pom.xml -am \
-DfailIfNoTests=false \
-Dspotless.skip=false \
-Dspotless.skip=true \
-Dtest=${{ matrix.case.class }} test
- uses: actions/upload-artifact@v4
if: always()

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

@ -30,6 +30,7 @@ env:
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- uses: actions/checkout@v4
with:
@ -47,4 +48,4 @@ jobs:
continue-on-error: true
with:
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.UserType;
import org.apache.dolphinscheduler.common.enums.WarningType;
import org.apache.dolphinscheduler.dao.entity.Project;
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.util.EntityUtils;
@ -51,6 +42,14 @@ import java.util.Date;
import java.util.LinkedHashMap;
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.
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j
@ -80,7 +79,8 @@ public class ExecutorAPITest {
public static void setup() {
LoginPage loginPage = new LoginPage();
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);
processDefinitionPage = new ProcessDefinitionPage(sessionId);
projectPage = new ProjectPage(sessionId);
@ -103,24 +103,30 @@ public class ExecutorAPITest {
HttpResponse createProjectResponse = projectPage.createProject(loginUser, "project-test");
HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser);
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
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("workflow-json/test.json").getFile());
CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage
.importProcessDefinition(loginUser, projectCode, file);
.importProcessDefinition(loginUser, projectCode, file);
String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity());
Assertions.assertTrue(data.contains("\"success\":true"));
// 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().getData().toString().contains("hello world"));
processDefinitionCode = (long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("code");
Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString()
.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
HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.ONLINE);
HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser,
projectCode, processDefinitionCode, ReleaseState.ONLINE);
Assertions.assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess());
// trigger workflow instance
@ -128,11 +134,12 @@ public class ExecutorAPITest {
Date date = new Date();
String scheduleTime = String.format("%s,%s", formatter.format(date), formatter.format(date));
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());
triggerCode = (long) startProcessInstanceResponse.getBody().getData();
} catch (Exception e) {
} catch (Exception e) {
log.error("failed", e);
Assertions.fail();
}
@ -141,7 +148,8 @@ public class ExecutorAPITest {
@Test
@Order(2)
public void testStartCheckProcessDefinition() {
HttpResponse testStartCheckProcessDefinitionResponse = executorPage.startCheckProcessDefinition(loginUser, projectCode, processDefinitionCode);
HttpResponse testStartCheckProcessDefinitionResponse =
executorPage.startCheckProcessDefinition(loginUser, projectCode, processDefinitionCode);
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.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.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;
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")
@Slf4j
public class ProcessDefinitionAPITest {
@ -67,12 +67,12 @@ public class ProcessDefinitionAPITest {
private static String processDefinitionName;
@BeforeAll
public static void setup() {
LoginPage loginPage = new LoginPage();
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);
projectPage = new ProjectPage(sessionId);
loginUser = new User();
@ -93,14 +93,15 @@ public class ProcessDefinitionAPITest {
HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser);
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();
File file = new File(classLoader.getResource("workflow-json/test.json").getFile());
CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage
.importProcessDefinition(loginUser, projectCode, file);
.importProcessDefinition(loginUser, projectCode, file);
String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity());
Assertions.assertTrue(data.contains("\"success\":true"));
} catch (Exception e) {
} catch (Exception e) {
log.error("failed", e);
Assertions.fail();
}
@ -109,72 +110,92 @@ public class ProcessDefinitionAPITest {
@Test
@Order(2)
public void testQueryAllProcessDefinitionByProjectCode() {
HttpResponse queryAllProcessDefinitionByProjectCodeResponse = processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode);
HttpResponse queryAllProcessDefinitionByProjectCodeResponse =
processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode);
Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess());
Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString().contains("hello world"));
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");
Assertions.assertTrue(
queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString().contains("hello world"));
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
@Order(3)
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().getData().toString().contains("hello world"));
Assertions.assertTrue(
queryProcessDefinitionByCodeResponse.getBody().getData().toString().contains("hello world"));
}
@Test
@Order(4)
public void testgetProcessListByProjectCode() {
HttpResponse getProcessListByProjectCodeResponse = processDefinitionPage.getProcessListByProjectCode(loginUser, projectCode);
HttpResponse getProcessListByProjectCodeResponse =
processDefinitionPage.getProcessListByProjectCode(loginUser, projectCode);
Assertions.assertTrue(getProcessListByProjectCodeResponse.getBody().getSuccess());
Assertions.assertTrue(getProcessListByProjectCodeResponse.getBody().getData().toString().contains("test_import"));
Assertions
.assertTrue(getProcessListByProjectCodeResponse.getBody().getData().toString().contains("test_import"));
}
@Test
@Order(5)
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().getData().toString().contains("hello world"));
Assertions.assertTrue(
queryProcessDefinitionByNameResponse.getBody().getData().toString().contains("hello world"));
}
@Test
@Order(6)
public void testQueryProcessDefinitionList() {
HttpResponse queryProcessDefinitionListResponse = processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode);
HttpResponse queryProcessDefinitionListResponse =
processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode);
Assertions.assertTrue(queryProcessDefinitionListResponse.getBody().getSuccess());
Assertions.assertTrue(queryProcessDefinitionListResponse.getBody().getData().toString().contains("hello world"));
Assertions
.assertTrue(queryProcessDefinitionListResponse.getBody().getData().toString().contains("hello world"));
}
@Test
@Order(7)
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());
HttpResponse queryProcessDefinitionByCodeResponse = processDefinitionPage.queryProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode);
HttpResponse queryProcessDefinitionByCodeResponse =
processDefinitionPage.queryProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode);
Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getSuccess());
Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getData().toString().contains("releaseState=ONLINE"));
Assertions.assertTrue(
queryProcessDefinitionByCodeResponse.getBody().getData().toString().contains("releaseState=ONLINE"));
}
@Test
@Order(8)
public void testDeleteProcessDefinitionByCode() {
HttpResponse deleteProcessDefinitionByCodeResponse = processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode);
HttpResponse deleteProcessDefinitionByCodeResponse =
processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode);
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());
deleteProcessDefinitionByCodeResponse = processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode);
deleteProcessDefinitionByCodeResponse =
processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode);
Assertions.assertTrue(deleteProcessDefinitionByCodeResponse.getBody().getSuccess());
HttpResponse queryProcessDefinitionListResponse = processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode);
HttpResponse queryProcessDefinitionListResponse =
processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode);
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.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
@ -55,8 +57,6 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import lombok.extern.slf4j.Slf4j;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j
public class ProcessInstanceAPITest {
@ -89,7 +89,8 @@ public class ProcessInstanceAPITest {
public static void setup() {
LoginPage loginPage = new LoginPage();
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);
executorPage = new ExecutorPage(sessionId);
processDefinitionPage = new ProcessDefinitionPage(sessionId);
@ -113,24 +114,30 @@ public class ProcessInstanceAPITest {
HttpResponse createProjectResponse = projectPage.createProject(loginUser, "project-test");
HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser);
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
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("workflow-json/test.json").getFile());
CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage
.importProcessDefinition(loginUser, projectCode, file);
.importProcessDefinition(loginUser, projectCode, file);
String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity());
assertTrue(data.contains("\"success\":true"));
// get workflow definition code
HttpResponse queryAllProcessDefinitionByProjectCodeResponse = processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode);
HttpResponse queryAllProcessDefinitionByProjectCodeResponse =
processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode);
assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess());
assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString().contains("hello world"));
processDefinitionCode = (long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("code");
assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString()
.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
HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.ONLINE);
HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser,
projectCode, processDefinitionCode, ReleaseState.ONLINE);
assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess());
// trigger workflow instance
@ -138,23 +145,27 @@ public class ProcessInstanceAPITest {
Date date = new Date();
String scheduleTime = String.format("%s,%s", formatter.format(date), formatter.format(date));
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());
// make sure process instance has completed and successfully persisted into db
Awaitility.await()
.atMost(30, TimeUnit.SECONDS)
.untilAsserted(() -> {
// query workflow instance by trigger code
triggerCode = (long) startProcessInstanceResponse.getBody().getData();
HttpResponse queryProcessInstancesByTriggerCodeResponse = processInstancePage.queryProcessInstancesByTriggerCode(loginUser, projectCode, triggerCode);
assertTrue(queryProcessInstancesByTriggerCodeResponse.getBody().getSuccess());
List<LinkedHashMap<String, Object>> body = (List<LinkedHashMap<String, Object>>) queryProcessInstancesByTriggerCodeResponse.getBody().getData();
assertTrue(CollectionUtils.isNotEmpty(body));
assertEquals("SUCCESS", body.get(0).get("state"));
processInstanceId = (int) body.get(0).get("id");
});
} catch (Exception e) {
.atMost(30, TimeUnit.SECONDS)
.untilAsserted(() -> {
// query workflow instance by trigger code
triggerCode = (long) startProcessInstanceResponse.getBody().getData();
HttpResponse queryProcessInstancesByTriggerCodeResponse = processInstancePage
.queryProcessInstancesByTriggerCode(loginUser, projectCode, triggerCode);
assertTrue(queryProcessInstancesByTriggerCodeResponse.getBody().getSuccess());
List<LinkedHashMap<String, Object>> body =
(List<LinkedHashMap<String, Object>>) queryProcessInstancesByTriggerCodeResponse
.getBody().getData();
assertTrue(CollectionUtils.isNotEmpty(body));
assertEquals("SUCCESS", body.get(0).get("state"));
processInstanceId = (int) body.get(0).get("id");
});
} catch (Exception e) {
log.error("failed", e);
Assertions.fail();
}
@ -163,7 +174,8 @@ public class ProcessInstanceAPITest {
@Test
@Order(2)
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().getData().toString().contains("test_import"));
}
@ -171,7 +183,8 @@ public class ProcessInstanceAPITest {
@Test
@Order(3)
public void testQueryTaskListByProcessId() {
HttpResponse queryTaskListByProcessIdResponse = processInstancePage.queryTaskListByProcessId(loginUser, projectCode, processInstanceId);
HttpResponse queryTaskListByProcessIdResponse =
processInstancePage.queryTaskListByProcessId(loginUser, projectCode, processInstanceId);
assertTrue(queryTaskListByProcessIdResponse.getBody().getSuccess());
assertTrue(queryTaskListByProcessIdResponse.getBody().getData().toString().contains("test_import"));
}
@ -179,7 +192,8 @@ public class ProcessInstanceAPITest {
@Test
@Order(4)
public void testQueryProcessInstanceById() {
HttpResponse queryProcessInstanceByIdResponse = processInstancePage.queryProcessInstanceById(loginUser, projectCode, processInstanceId);
HttpResponse queryProcessInstanceByIdResponse =
processInstancePage.queryProcessInstanceById(loginUser, projectCode, processInstanceId);
assertTrue(queryProcessInstanceByIdResponse.getBody().getSuccess());
assertTrue(queryProcessInstanceByIdResponse.getBody().getData().toString().contains("test_import"));
}
@ -187,10 +201,12 @@ public class ProcessInstanceAPITest {
@Test
@Order(5)
public void testDeleteProcessInstanceById() {
HttpResponse deleteProcessInstanceByIdResponse = processInstancePage.deleteProcessInstanceById(loginUser, projectCode, processInstanceId);
HttpResponse deleteProcessInstanceByIdResponse =
processInstancePage.deleteProcessInstanceById(loginUser, projectCode, processInstanceId);
assertTrue(deleteProcessInstanceByIdResponse.getBody().getSuccess());
HttpResponse queryProcessInstanceListResponse = processInstancePage.queryProcessInstanceList(loginUser, projectCode, 1, 10);
HttpResponse queryProcessInstanceListResponse =
processInstancePage.queryProcessInstanceList(loginUser, projectCode, 1, 10);
assertTrue(queryProcessInstanceListResponse.getBody().getSuccess());
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.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.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 java.util.LinkedHashMap;
import java.util.List;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j
// TODO: Add more detailed permission control related cases after userPage test cases completed
@ -59,7 +59,8 @@ public class ProjectAPITest {
public static void setup() {
LoginPage loginPage = new LoginPage();
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);
loginUser = new User();
loginUser.setUserName("admin");
@ -98,7 +99,8 @@ public class ProjectAPITest {
List<LinkedHashMap> projects = (List<LinkedHashMap>) queryAllProjectListResponse.getBody().getData();
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());
queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser);
@ -133,17 +135,21 @@ public class ProjectAPITest {
@Test
@Order(6)
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().getData().toString().contains("project-new"));
Assertions.assertTrue(queryProjectWithAuthorizedLevelListPagingResponse.getBody().getData().toString()
.contains("project-new"));
}
@Test
@Order(7)
public void testQueryUnauthorizedProject() {
HttpResponse queryUnauthorizedProjectResponse = projectPage.queryUnauthorizedProject(loginUser, loginUser.getId());
HttpResponse queryUnauthorizedProjectResponse =
projectPage.queryUnauthorizedProject(loginUser, loginUser.getId());
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"));
}
@ -152,17 +158,21 @@ public class ProjectAPITest {
public void testQueryAuthorizedProject() {
HttpResponse queryAuthorizedProjectResponse = projectPage.queryAuthorizedProject(loginUser, loginUser.getId());
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"));
}
@Test
@Order(9)
public void testQueryProjectWithAuthorizedLevel() {
HttpResponse queryProjectWithAuthorizedLevelResponse = projectPage.queryProjectWithAuthorizedLevel(loginUser, loginUser.getId());
HttpResponse queryProjectWithAuthorizedLevelResponse =
projectPage.queryProjectWithAuthorizedLevel(loginUser, loginUser.getId());
Assertions.assertTrue(queryProjectWithAuthorizedLevelResponse.getBody().getSuccess());
// queryProjectWithAuthorizedLevel api returns a joint-set of projects both created by and authorized to the user
Assertions.assertTrue(queryProjectWithAuthorizedLevelResponse.getBody().getData().toString().contains("project-new"));
// queryProjectWithAuthorizedLevel api returns a joint-set of projects both created by and authorized to the
// user
Assertions.assertTrue(
queryProjectWithAuthorizedLevelResponse.getBody().getData().toString().contains("project-new"));
}
@Test
@ -181,10 +191,13 @@ public class ProjectAPITest {
@Test
@Order(11)
public void testQueryProjectCreatedAndAuthorizedByUser() {
HttpResponse queryProjectCreatedAndAuthorizedByUserResponse = projectPage.queryProjectCreatedAndAuthorizedByUser(loginUser);
HttpResponse queryProjectCreatedAndAuthorizedByUserResponse =
projectPage.queryProjectCreatedAndAuthorizedByUser(loginUser);
Assertions.assertTrue(queryProjectCreatedAndAuthorizedByUserResponse.getBody().getSuccess());
// queryProjectCreatedAndAuthorizedByUser api returns a joint-set of projects both created by and authorized to the user
Assertions.assertTrue(queryProjectCreatedAndAuthorizedByUserResponse.getBody().getData().toString().contains("project-new"));
// queryProjectCreatedAndAuthorizedByUser api returns a joint-set of projects both created by and authorized to
// the user
Assertions.assertTrue(
queryProjectCreatedAndAuthorizedByUserResponse.getBody().getData().toString().contains("project-new"));
}
@Test
@ -192,7 +205,8 @@ public class ProjectAPITest {
public void testQueryAllProjectListForDependent() {
HttpResponse queryAllProjectListForDependentResponse = projectPage.queryAllProjectListForDependent(loginUser);
Assertions.assertTrue(queryAllProjectListForDependentResponse.getBody().getSuccess());
Assertions.assertTrue(queryAllProjectListForDependentResponse.getBody().getData().toString().contains("project-new"));
Assertions.assertTrue(
queryAllProjectListForDependentResponse.getBody().getData().toString().contains("project-new"));
}
@Test
@ -203,8 +217,7 @@ public class ProjectAPITest {
Long code = (Long) projects.get(0).get("code");
HttpResponse queryAllProjectListForDependentResponse = projectPage.deleteProject(loginUser, code);
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.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;
import lombok.extern.slf4j.Slf4j;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j
public class SchedulerAPITest {
@ -67,12 +67,12 @@ public class SchedulerAPITest {
private static int scheduleId;
@BeforeAll
public static void setup() {
LoginPage loginPage = new LoginPage();
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);
schedulerPage = new SchedulerPage(sessionId);
processDefinitionPage = new ProcessDefinitionPage(sessionId);
@ -94,17 +94,24 @@ public class SchedulerAPITest {
HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser);
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();
File file = new File(classLoader.getResource("workflow-json/test.json").getFile());
processDefinitionPage.importProcessDefinition(loginUser, projectCode, file);
HttpResponse queryAllProcessDefinitionByProjectCodeResponse = processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode);
HttpResponse queryAllProcessDefinitionByProjectCodeResponse =
processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode);
Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess());
processDefinitionCode = (long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("code");
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);
processDefinitionCode =
(long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllProcessDefinitionByProjectCodeResponse
.getBody().getData()).get(0)).get("processDefinition")).get("code");
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().getData().toString().contains("2019-08-08"));
}
@ -115,13 +122,15 @@ public class SchedulerAPITest {
HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode);
Assertions.assertTrue(queryScheduleListResponse.getBody().getSuccess());
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
@Order(3)
public void testPublishScheduleOnline() {
HttpResponse publishScheduleOnlineResponse = schedulerPage.publishScheduleOnline(loginUser, projectCode, scheduleId);
HttpResponse publishScheduleOnlineResponse =
schedulerPage.publishScheduleOnline(loginUser, projectCode, scheduleId);
Assertions.assertTrue(publishScheduleOnlineResponse.getBody().getSuccess());
HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode);
@ -137,14 +146,17 @@ public class SchedulerAPITest {
HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode);
Assertions.assertTrue(queryScheduleListResponse.getBody().getSuccess());
Assertions.assertTrue(queryScheduleListResponse.getBody().getData().toString().contains("releaseState=OFFLINE"));
Assertions
.assertTrue(queryScheduleListResponse.getBody().getData().toString().contains("releaseState=OFFLINE"));
}
@Test
@Order(5)
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 * * ? *\"}";
HttpResponse updateScheduleResponse = schedulerPage.updateSchedule(loginUser, projectCode, scheduleId, schedule);
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 * * ? *\"}";
HttpResponse updateScheduleResponse =
schedulerPage.updateSchedule(loginUser, projectCode, scheduleId, schedule);
Assertions.assertTrue(updateScheduleResponse.getBody().getSuccess());
HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode);
@ -163,5 +175,3 @@ public class SchedulerAPITest {
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.utils.JSONUtils;
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;
import lombok.extern.slf4j.Slf4j;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j
public class TenantAPITest {
private static final String tenant = System.getProperty("user.name");
private static final String user = "admin";
@ -54,7 +55,8 @@ public class TenantAPITest {
LoginPage loginPage = new LoginPage();
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
@ -90,7 +92,9 @@ public class TenantAPITest {
HttpResponse createTenantHttpResponse = tenantPage.getTenantListPaging(sessionId, 1, 10, "");
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)) {
result = true;
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.Set;
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;
import lombok.extern.slf4j.Slf4j;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@Slf4j
public class WorkerGroupAPITest {
@ -59,7 +59,8 @@ public class WorkerGroupAPITest {
public static void setup() {
LoginPage loginPage = new LoginPage();
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);
loginUser = new User();
loginUser.setId(123);
@ -75,7 +76,7 @@ public class WorkerGroupAPITest {
@Order(1)
public void testSaveWorkerGroup() {
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());
HttpResponse queryAllWorkerGroupsResponse = workerGroupPage.queryAllWorkerGroups(loginUser);
@ -88,9 +89,10 @@ public class WorkerGroupAPITest {
@Test
@Order(2)
public void testQueryAllWorkerGroupsPaging() {
HttpResponse queryAllWorkerGroupsPagingResponse = workerGroupPage.queryAllWorkerGroupsPaging(loginUser, 1, 2, null);
HttpResponse queryAllWorkerGroupsPagingResponse =
workerGroupPage.queryAllWorkerGroupsPaging(loginUser, 1, 2, null);
Assertions.assertTrue(queryAllWorkerGroupsPagingResponse.getBody().getSuccess());
String workerGroupPageInfoData = queryAllWorkerGroupsPagingResponse.getBody().getData().toString();
String workerGroupPageInfoData = queryAllWorkerGroupsPagingResponse.getBody().getData().toString();
Assertions.assertTrue(workerGroupPageInfoData.contains("test_worker_group"));
}
@ -100,7 +102,7 @@ public class WorkerGroupAPITest {
HttpResponse queryAllWorkerGroupsResponse = workerGroupPage.queryAllWorkerGroups(loginUser);
Assertions.assertTrue(queryAllWorkerGroupsResponse.getBody().getSuccess());
String workerGroupPageInfoData = queryAllWorkerGroupsResponse.getBody().getData().toString();
String workerGroupPageInfoData = queryAllWorkerGroupsResponse.getBody().getData().toString();
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
@Data
public class TenantListPagingResponseData {
private Integer currentPage;
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
@Data
public class TenantListPagingResponseTotalList {
private Date createTime;
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;
public final class LoginPage {
public HttpResponse login(String username, String password) {
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;
import lombok.AllArgsConstructor;
import org.apache.dolphinscheduler.api.test.core.Constants;
import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
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.Map;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public final class ProjectPage {
private String sessionId;
public HttpResponse createProject(User loginUser, String projectName) {
@ -90,7 +91,8 @@ public final class ProjectPage {
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<>();
params.put("loginUser", loginUser);
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;
public final class TenantPage {
public HttpResponse createTenant(String sessionId, String tenant, Integer queueId, String description) {
Map<String, Object> params = new HashMap<>();
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;
import lombok.AllArgsConstructor;
import org.apache.dolphinscheduler.api.test.core.Constants;
import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
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.Map;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class WorkerGroupPage {
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<>();
params.put("loginUser", loginUser);
params.put("id", id);
@ -96,5 +96,4 @@ public class WorkerGroupPage {
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.extern.slf4j.Slf4j;
@Slf4j
@AllArgsConstructor
public class ExecutorPage {
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<>();
params.put("loginUser", loginUser);
params.put("processDefinitionCode", processDefinitionCode);
@ -93,7 +94,8 @@ public class ExecutorPage {
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<>();
params.put("loginUser", loginUser);
params.put("processInstanceId", processInstanceId);
@ -107,4 +109,4 @@ public class ExecutorPage {
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.dao.entity.User;
import org.apache.http.client.methods.CloseableHttpResponse;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
@ -32,9 +34,6 @@ import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
@Slf4j
@AllArgsConstructor
public class ProcessDefinitionPage {
@ -107,7 +106,8 @@ public class ProcessDefinitionPage {
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<>();
params.put("loginUser", loginUser);
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;
import org.apache.dolphinscheduler.api.enums.ExecuteType;
import org.apache.dolphinscheduler.api.test.core.Constants;
import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
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 java.util.HashMap;
@ -34,7 +30,6 @@ import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@AllArgsConstructor
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.extern.slf4j.Slf4j;
@Slf4j
@AllArgsConstructor
public class SchedulerPage {
@ -63,7 +62,6 @@ public class SchedulerPage {
return requestClient.post(url, headers, params);
}
public HttpResponse publishScheduleOnline(User loginUser, long projectCode, int scheduleId) {
Map<String, Object> params = new HashMap<>();
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;
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.FAIL_ON_UNKNOWN_PROPERTIES;
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 java.nio.charset.StandardCharsets.UTF_8;
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!
*/
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)
.configure(REQUIRE_SETTERS_FOR_GETTERS, true).setTimeZone(TimeZone.getDefault()).setDateFormat(new SimpleDateFormat(Constants.YYYY_MM_DD_HH_MM_SS));
new ObjectMapper().configure(FAIL_ON_UNKNOWN_PROPERTIES, false)
.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() {
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.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.FileInputStream;
import java.util.HashMap;
@ -39,17 +48,6 @@ import okhttp3.Request;
import okhttp3.RequestBody;
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
public class RequestClient {
@ -70,10 +68,10 @@ public class RequestClient {
log.info("GET request to {}, Headers: {}", requestUrl, headersBuilder);
Request request = new Request.Builder()
.url(requestUrl)
.headers(headersBuilder)
.get()
.build();
.url(requestUrl)
.headers(headersBuilder)
.get()
.build();
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));
log.info("POST request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params);
Request request = new Request.Builder()
.headers(headersBuilder)
.url(requestUrl)
.post(requestBody)
.build();
.headers(headersBuilder)
.url(requestUrl)
.post(requestBody)
.build();
Response response = this.httpClient.newCall(request).execute();
int responseCode = response.code();
HttpResponseBody responseData = null;
@ -152,10 +150,10 @@ public class RequestClient {
RequestBody requestBody = FormBody.create(MediaType.parse(Constants.REQUEST_CONTENT_TYPE), getParams(params));
log.info("PUT request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params);
Request request = new Request.Builder()
.headers(headersBuilder)
.url(requestUrl)
.put(requestBody)
.build();
.headers(headersBuilder)
.url(requestUrl)
.put(requestBody)
.build();
Response response = this.httpClient.newCall(request).execute();
int responseCode = response.code();
HttpResponseBody responseData = null;
@ -171,17 +169,17 @@ public class RequestClient {
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 {
Headers headersBuilder = Headers.of(headers);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("json", getParams(params), ContentType.MULTIPART_FORM_DATA);
builder.addBinaryBody(
"file",
new FileInputStream(file),
ContentType.APPLICATION_OCTET_STREAM,
file.getName()
);
"file",
new FileInputStream(file),
ContentType.APPLICATION_OCTET_STREAM,
file.getName());
HttpEntity multipart = builder.build();
String requestUrl = String.format("%s%s", Constants.DOLPHINSCHEDULER_API_URL, url);
log.info("POST request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params);
@ -199,7 +197,6 @@ public class RequestClient {
return null;
}
@SneakyThrows
public HttpResponse delete(String url, Map<String, String> headers, Map<String, Object> params) {
if (headers == null) {
@ -214,10 +211,10 @@ public class RequestClient {
log.info("DELETE request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params);
Request request = new Request.Builder()
.headers(headersBuilder)
.url(requestUrl)
.delete()
.build();
.headers(headersBuilder)
.url(requestUrl)
.delete()
.build();
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)
@ExtendWith(DolphinSchedulerExtension.class)
public @interface DolphinScheduler {
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.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.testcontainers.containers.ContainerState;
import org.testcontainers.containers.DockerComposeContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import lombok.extern.slf4j.Slf4j;
@Slf4j
final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCallback {
private final boolean localMode = Objects.equals(System.getProperty("local"), "true");
private final String serviceName = "dolphinscheduler_1";
@ -78,7 +77,8 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
.withPull(true)
.withTailChildContainers(true)
.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;
}

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
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import java.time.Duration;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@DolphinScheduler(composeFiles = "docker/datasource-clickhouse/docker-compose.yaml")
public class ClickhouseDataSourceE2ETest {
private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name");
private static final String user = "admin";
private static final String password = "dolphinscheduler123";
private static final String dataSourceType = "CLICKHOUSE";
private static final String dataSourceName = "clickhouse_test";
private static final String dataSourceDescription = "clickhouse_test";
private static final String ip = "clickhouse";
private static final String port = "8123";
private static final String userName = "ch_test";
private static final String pgPassword = "ch_test";
private static final String database = "ch_test";
private static final String jdbcParams = "";
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login(user, password)
.goToNav(DataSourcePage.class);
}
@Test
@Order(10)
void testCreateClickhouseDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
new By.ByClassName("dialog-create-data-source")));
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
.as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName)));
}
@Test
@Order(20)
void testDeleteClickhouseDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.delete(dataSourceName);
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(
page.dataSourceItemsList()
).noneMatch(
it -> it.getText().contains(dataSourceName)
);
});
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/datasource-clickhouse/docker-compose.yaml")
public class ClickhouseDataSourceE2ETest {
private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name");
private static final String user = "admin";
private static final String password = "dolphinscheduler123";
private static final String dataSourceType = "CLICKHOUSE";
private static final String dataSourceName = "clickhouse_test";
private static final String dataSourceDescription = "clickhouse_test";
private static final String ip = "clickhouse";
private static final String port = "8123";
private static final String userName = "ch_test";
private static final String pgPassword = "ch_test";
private static final String database = "ch_test";
private static final String jdbcParams = "";
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login(user, password)
.goToNav(DataSourcePage.class);
}
@Test
@Order(10)
void testCreateClickhouseDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword,
database, jdbcParams);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
new By.ByClassName("dialog-create-data-source")));
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
.as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName)));
}
@Test
@Order(20)
void testDeleteClickhouseDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.delete(dataSourceName);
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
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;
import static org.assertj.core.api.Assertions.assertThat;
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.SecurityPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class ClusterE2ETest {
@ -53,8 +52,7 @@ class ClusterE2ETest {
new LoginPage(browser)
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(ClusterPage.class)
;
.goToTab(ClusterPage.class);
}
@Test
@ -78,10 +76,8 @@ class ClusterE2ETest {
final ClusterPage page = new ClusterPage(browser);
page.create(clusterName, clusterConfig, clusterDesc);
Awaitility.await().untilAsserted(() ->
assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists")
);
Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists"));
page.createClusterForm().buttonCancel().click();
}
@ -112,12 +108,10 @@ class ClusterE2ETest {
browser.navigate().refresh();
assertThat(
page.clusterList()
)
.as("Cluster list should not contain deleted cluster")
.noneMatch(
it -> it.getText().contains(clusterName) || it.getText().contains(editClusterName)
);
page.clusterList())
.as("Cluster list should not contain deleted cluster")
.noneMatch(
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;
import static org.assertj.core.api.Assertions.assertThat;
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.SecurityPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class EnvironmentE2ETest {
@ -55,8 +54,7 @@ class EnvironmentE2ETest {
new LoginPage(browser)
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(EnvironmentPage.class)
;
.goToTab(EnvironmentPage.class);
}
@Test
@ -80,10 +78,8 @@ class EnvironmentE2ETest {
final EnvironmentPage page = new EnvironmentPage(browser);
page.create(environmentName, environmentConfig, environmentDesc, environmentWorkerGroup);
Awaitility.await().untilAsserted(() ->
assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists")
);
Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists"));
page.createEnvironmentForm().buttonCancel().click();
}
@ -92,7 +88,8 @@ class EnvironmentE2ETest {
@Order(30)
void testEditEnvironment() {
final EnvironmentPage page = new EnvironmentPage(browser);
page.update(environmentName, editEnvironmentName, editEnvironmentConfig, editEnvironmentDesc, editEnvironmentWorkerGroup);
page.update(environmentName, editEnvironmentName, editEnvironmentConfig, editEnvironmentDesc,
editEnvironmentWorkerGroup);
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
@ -114,12 +111,11 @@ class EnvironmentE2ETest {
browser.navigate().refresh();
assertThat(
page.environmentList()
)
.as("Environment list should not contain deleted environment")
.noneMatch(
it -> it.getText().contains(environmentName) || it.getText().contains(editEnvironmentName)
);
page.environmentList())
.as("Environment list should not contain deleted environment")
.noneMatch(
it -> it.getText().contains(environmentName)
|| 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;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.Constants;
@ -37,10 +36,10 @@ import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
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.BeforeAll;
import org.junit.jupiter.api.Order;
@ -49,12 +48,11 @@ import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.SneakyThrows;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/file-manage/docker-compose.yaml")
public class FileManageE2ETest {
private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name");
@ -92,19 +90,19 @@ public class FileManageE2ETest {
.create(tenant);
Awaitility.await().untilAsserted(() -> assertThat(tenantPage.tenantList())
.as("Tenant list should contain newly-created tenant")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant)));
.as("Tenant list should contain newly-created tenant")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant)));
UserPage userPage = tenantPage.goToNav(SecurityPage.class)
.goToTab(UserPage.class);
.goToTab(UserPage.class);
WebDriverWaitFactory.createWebDriverWait(userPage.driver()).until(ExpectedConditions.visibilityOfElementLocated(
new By.ByClassName("name")));
userPage.update(user, user, email, phone, tenant)
.goToNav(ResourcePage.class)
.goToTab(FileManagePage.class);
.goToNav(ResourcePage.class)
.goToTab(FileManagePage.class);
}
@AfterAll
@ -113,9 +111,9 @@ public class FileManageE2ETest {
Files.deleteIfExists(testUnder1GBFilePath);
Files.deleteIfExists(testOver1GBFilePath);
Files.walk(Constants.HOST_CHROME_DOWNLOAD_PATH)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
}
@Test
@ -139,57 +137,57 @@ public class FileManageE2ETest {
page.cancelCreateDirectory(testDirectoryName);
Awaitility.await().untilAsserted(() -> assertThat(page.fileList())
.as("File list should contain newly-created file")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(testDirectoryName)));
.as("File list should contain newly-created file")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(testDirectoryName)));
}
// @Test
// @Order(20)
// void testCreateDuplicateDirectory() {
// final FileManagePage page = new FileManagePage(browser);
//
// page.createDirectory(testDirectoryName, "test_desc");
//
// await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
// .contains("resource already exists")
// );
//
// page.createDirectoryBox().buttonCancel().click();
// }
// @Test
// @Order(21)
// void testCreateSubDirectory() {
// final FileManagePage page = new FileManagePage(browser);
//
// page.createSubDirectory(testDirectoryName, testSubDirectoryName, "test_desc");
//
// await().untilAsserted(() -> assertThat(page.fileList())
// .as("File list should contain newly-created file")
// .extracting(WebElement::getText)
// .anyMatch(it -> it.contains(testSubDirectoryName)));
// }
/*
* when the storage is s3,the directory cannot be renamed
* */
// @Test
// @Order(22)
// void testRenameDirectory() {
// final FileManagePage page = new FileManagePage(browser);
//
// page.rename(testDirectoryName, testRenameDirectoryName);
//
// await().untilAsserted(() -> {
// browser.navigate().refresh();
//
// assertThat(page.fileList())
// .as("File list should contain newly-created file")
// .extracting(WebElement::getText)
// .anyMatch(it -> it.contains(testRenameDirectoryName));
// });
// }
// @Test
// @Order(20)
// void testCreateDuplicateDirectory() {
// final FileManagePage page = new FileManagePage(browser);
//
// page.createDirectory(testDirectoryName, "test_desc");
//
// await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
// .contains("resource already exists")
// );
//
// page.createDirectoryBox().buttonCancel().click();
// }
// @Test
// @Order(21)
// void testCreateSubDirectory() {
// final FileManagePage page = new FileManagePage(browser);
//
// page.createSubDirectory(testDirectoryName, testSubDirectoryName, "test_desc");
//
// await().untilAsserted(() -> assertThat(page.fileList())
// .as("File list should contain newly-created file")
// .extracting(WebElement::getText)
// .anyMatch(it -> it.contains(testSubDirectoryName)));
// }
/*
* when the storage is s3,the directory cannot be renamed
*/
// @Test
// @Order(22)
// void testRenameDirectory() {
// final FileManagePage page = new FileManagePage(browser);
//
// page.rename(testDirectoryName, testRenameDirectoryName);
//
// await().untilAsserted(() -> {
// browser.navigate().refresh();
//
// assertThat(page.fileList())
// .as("File list should contain newly-created file")
// .extracting(WebElement::getText)
// .anyMatch(it -> it.contains(testRenameDirectoryName));
// });
// }
@Test
@Order(30)
@ -197,17 +195,15 @@ public class FileManageE2ETest {
final FileManagePage page = new FileManagePage(browser);
page.goToNav(ResourcePage.class)
.goToTab(FileManagePage.class)
.delete(testDirectoryName);
.goToTab(FileManagePage.class)
.delete(testDirectoryName);
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(
page.fileList()
).noneMatch(
it -> it.getText().contains(testDirectoryName)
);
page.fileList()).noneMatch(
it -> it.getText().contains(testDirectoryName));
});
}
@ -220,9 +216,9 @@ public class FileManageE2ETest {
page.createFile(testFileName, scripts);
Awaitility.await().untilAsserted(() -> assertThat(page.fileList())
.as("File list should contain newly-created file")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(testFileName)));
.as("File list should contain newly-created file")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(testFileName)));
}
@Test
@ -236,9 +232,9 @@ public class FileManageE2ETest {
browser.navigate().refresh();
assertThat(page.fileList())
.as("File list should contain newly-created file")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(testRenameFileName));
.as("File list should contain newly-created file")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(testRenameFileName));
});
}
@ -251,9 +247,9 @@ public class FileManageE2ETest {
page.editFile(testRenameFileName, scripts);
Awaitility.await().untilAsserted(() -> assertThat(page.fileList())
.as("File list should contain newly-created file")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(testRenameFileName)));
.as("File list should contain newly-created file")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(testRenameFileName)));
}
@Test
@ -267,10 +263,8 @@ public class FileManageE2ETest {
browser.navigate().refresh();
assertThat(
page.fileList()
).noneMatch(
it -> it.getText().contains(testRenameFileName)
);
page.fileList()).noneMatch(
it -> it.getText().contains(testRenameFileName));
});
}
@ -286,13 +280,14 @@ public class FileManageE2ETest {
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(() -> {
assertThat(page.fileList())
.as("File list should contain newly-created file")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(testUnder1GBFileName));
.as("File list should contain newly-created file")
.extracting(WebElement::getText)
.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.datasource.DataSourcePage;
import java.time.Duration;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@ -36,11 +34,11 @@ import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/datasource-hive/docker-compose.yaml")
public class HiveDataSourceE2ETest {
private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name");
@ -70,9 +68,8 @@ public class HiveDataSourceE2ETest {
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login(user, password)
.goToNav(DataSourcePage.class);
.login(user, password)
.goToNav(DataSourcePage.class);
}
@ -81,15 +78,16 @@ public class HiveDataSourceE2ETest {
void testCreateHiveDataSource() {
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(
new By.ByClassName("dialog-create-data-source")));
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
.as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName)));
.as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName)));
}
@Test
@ -103,10 +101,8 @@ public class HiveDataSourceE2ETest {
browser.navigate().refresh();
assertThat(
page.dataSourceItemsList()
).noneMatch(
it -> it.getText().contains(dataSourceName)
);
page.dataSourceItemsList()).noneMatch(
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
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import java.time.Duration;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@DolphinScheduler(composeFiles = "docker/datasource-mysql/docker-compose.yaml")
public class MysqlDataSourceE2ETest {
private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name");
private static final String user = "admin";
private static final String password = "dolphinscheduler123";
private static final String dataSourceType = "MYSQL";
private static final String dataSourceName = "mysql_test";
private static final String dataSourceDescription = "mysql_test";
private static final String ip = "mysql";
private static final String port = "3306";
private static final String userName = "root";
private static final String mysqlPassword = "123456";
private static final String database = "mysql";
private static final String jdbcParams = "{\"useSSL\": false}";
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login(user, password)
.goToNav(DataSourcePage.class);
}
@Test
@Order(10)
void testCreateMysqlDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, mysqlPassword, database, jdbcParams);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
new By.ByClassName("dialog-create-data-source")));
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
.as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName)));
}
@Test
@Order(20)
void testDeleteMysqlDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.delete(dataSourceName);
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(
page.dataSourceItemsList()
).noneMatch(
it -> it.getText().contains(dataSourceName)
);
});
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/datasource-mysql/docker-compose.yaml")
public class MysqlDataSourceE2ETest {
private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name");
private static final String user = "admin";
private static final String password = "dolphinscheduler123";
private static final String dataSourceType = "MYSQL";
private static final String dataSourceName = "mysql_test";
private static final String dataSourceDescription = "mysql_test";
private static final String ip = "mysql";
private static final String port = "3306";
private static final String userName = "root";
private static final String mysqlPassword = "123456";
private static final String database = "mysql";
private static final String jdbcParams = "{\"useSSL\": false}";
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login(user, password)
.goToNav(DataSourcePage.class);
}
@Test
@Order(10)
void testCreateMysqlDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, mysqlPassword,
database, jdbcParams);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
new By.ByClassName("dialog-create-data-source")));
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
.as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName)));
}
@Test
@Order(20)
void testDeleteMysqlDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.delete(dataSourceName);
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
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
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import java.time.Duration;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@DolphinScheduler(composeFiles = "docker/datasource-postgresql/docker-compose.yaml")
public class PostgresDataSourceE2ETest {
private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name");
private static final String user = "admin";
private static final String password = "dolphinscheduler123";
private static final String dataSourceType = "POSTGRESQL";
private static final String dataSourceName = "postgres_test";
private static final String dataSourceDescription = "postgres_test";
private static final String ip = "postgres";
private static final String port = "5432";
private static final String userName = "postgres";
private static final String pgPassword = "postgres";
private static final String database = "postgres";
private static final String jdbcParams = "";
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login(user, password)
.goToNav(DataSourcePage.class);
}
@Test
@Order(10)
void testCreatePostgresDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
new By.ByClassName("dialog-create-data-source")));
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
.as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName)));
}
@Test
@Order(20)
void testDeletePostgresDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.delete(dataSourceName);
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(
page.dataSourceItemsList()
).noneMatch(
it -> it.getText().contains(dataSourceName)
);
});
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/datasource-postgresql/docker-compose.yaml")
public class PostgresDataSourceE2ETest {
private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name");
private static final String user = "admin";
private static final String password = "dolphinscheduler123";
private static final String dataSourceType = "POSTGRESQL";
private static final String dataSourceName = "postgres_test";
private static final String dataSourceDescription = "postgres_test";
private static final String ip = "postgres";
private static final String port = "5432";
private static final String userName = "postgres";
private static final String pgPassword = "postgres";
private static final String database = "postgres";
private static final String jdbcParams = "";
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login(user, password)
.goToNav(DataSourcePage.class);
}
@Test
@Order(10)
void testCreatePostgresDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword,
database, jdbcParams);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
new By.ByClassName("dialog-create-data-source")));
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
.as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName)));
}
@Test
@Order(20)
void testDeletePostgresDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.delete(dataSourceName);
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
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.project.ProjectPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class ProjectE2ETest {
private static final String project = "test-project-1";
private static RemoteWebDriver browser;
@ -59,10 +60,8 @@ class ProjectE2ETest {
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(
page.projectList()
).noneMatch(
it -> it.getText().contains(project)
);
page.projectList()).noneMatch(
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;
import static org.assertj.core.api.Assertions.assertThat;
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.SecurityPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class QueueE2ETest {
@ -50,8 +49,7 @@ class QueueE2ETest {
new LoginPage(browser)
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(QueuePage.class)
;
.goToTab(QueuePage.class);
}
@Test
@ -75,10 +73,8 @@ class QueueE2ETest {
final QueuePage page = new QueuePage(browser);
page.create(queueName, queueValue);
Awaitility.await().untilAsserted(() ->
assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists")
);
Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists"));
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
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import java.time.Duration;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@DolphinScheduler(composeFiles = "docker/datasource-sqlserver/docker-compose.yaml")
public class SqlServerDataSourceE2ETest {
private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name");
private static final String user = "admin";
private static final String password = "dolphinscheduler123";
private static final String dataSourceType = "SQLSERVER";
private static final String dataSourceName = "sqlserver_test";
private static final String dataSourceDescription = "sqlserver_test";
private static final String ip = "sqlserver";
private static final String port = "1433";
private static final String userName = "sa";
private static final String pgPassword = "OcP2020123";
private static final String database = "master";
private static final String jdbcParams = "";
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login(user, password)
.goToNav(DataSourcePage.class);
}
@Test
@Order(10)
void testCreateSqlServerDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
new By.ByClassName("dialog-create-data-source")));
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
.as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName)));
}
@Test
@Order(20)
void testDeleteSqlServerDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.delete(dataSourceName);
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(
page.dataSourceItemsList()
).noneMatch(
it -> it.getText().contains(dataSourceName)
);
});
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.cases;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/datasource-sqlserver/docker-compose.yaml")
public class SqlServerDataSourceE2ETest {
private static RemoteWebDriver browser;
private static final String tenant = System.getProperty("user.name");
private static final String user = "admin";
private static final String password = "dolphinscheduler123";
private static final String dataSourceType = "SQLSERVER";
private static final String dataSourceName = "sqlserver_test";
private static final String dataSourceDescription = "sqlserver_test";
private static final String ip = "sqlserver";
private static final String port = "1433";
private static final String userName = "sa";
private static final String pgPassword = "OcP2020123";
private static final String database = "master";
private static final String jdbcParams = "";
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login(user, password)
.goToNav(DataSourcePage.class);
}
@Test
@Order(10)
void testCreateSqlServerDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword,
database, jdbcParams);
WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated(
new By.ByClassName("dialog-create-data-source")));
Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList())
.as("DataSource list should contain newly-created database")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(dataSourceName)));
}
@Test
@Order(20)
void testDeleteSqlServerDataSource() {
final DataSourcePage page = new DataSourcePage(browser);
page.delete(dataSourceName);
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
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.TenantPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class TenantE2ETest {
private static final String tenant = System.getProperty("user.name");
private static final String editDescription = "This is a test";
@ -44,10 +45,9 @@ class TenantE2ETest {
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(TenantPage.class)
;
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(TenantPage.class);
}
@Test
@ -57,9 +57,9 @@ class TenantE2ETest {
page.create(tenant);
Awaitility.await().untilAsserted(() -> assertThat(page.tenantList())
.as("Tenant list should contain newly-created tenant")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant)));
.as("Tenant list should contain newly-created tenant")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant)));
}
@Test
@ -69,10 +69,8 @@ class TenantE2ETest {
page.create(tenant);
Awaitility.await().untilAsserted(() ->
assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists")
);
Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists"));
page.tenantForm().buttonCancel().click();
}
@ -87,9 +85,9 @@ class TenantE2ETest {
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(page.tenantList())
.as("Tenant list should contain newly-modified tenant")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant));
.as("Tenant list should contain newly-modified tenant")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant));
});
}
@ -103,10 +101,8 @@ class TenantE2ETest {
browser.navigate().refresh();
assertThat(
page.tenantList()
).noneMatch(
it -> it.getText().contains(tenant)
);
page.tenantList()).noneMatch(
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.TokenPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
public class TokenE2ETest {
@ -43,10 +43,9 @@ public class TokenE2ETest {
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(TokenPage.class)
;
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(TokenPage.class);
}
@Test
@ -59,9 +58,9 @@ public class TokenE2ETest {
browser.navigate().refresh();
assertThat(page.tokenList())
.as("Token list should contain newly-created token")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(userName));
.as("Token list should contain newly-created token")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(userName));
});
}
@ -76,9 +75,9 @@ public class TokenE2ETest {
browser.navigate().refresh();
assertThat(page.tokenList())
.as("Token list should contain newly-modified token")
.extracting(WebElement::getText)
.isNotEqualTo(oldToken);
.as("Token list should contain newly-modified token")
.extracting(WebElement::getText)
.isNotEqualTo(oldToken);
});
}
@ -92,7 +91,7 @@ public class TokenE2ETest {
browser.navigate().refresh();
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;
import static org.assertj.core.api.Assertions.assertThat;
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.UserPage;
import java.time.Duration;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
@ -41,10 +37,11 @@ import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class UserE2ETest {
private static final String tenant = System.getProperty("user.name");
private static final String user = "test_user";
private static final String password = "testUser123";
@ -78,9 +75,9 @@ class UserE2ETest {
@AfterAll
public static void cleanup() {
new NavBarPage(browser)
.goToNav(SecurityPage.class)
.goToTab(TenantPage.class)
.delete(tenant);
.goToNav(SecurityPage.class)
.goToTab(TenantPage.class)
.delete(tenant);
}
@Test
@ -94,9 +91,9 @@ class UserE2ETest {
browser.navigate().refresh();
assertThat(page.userList())
.as("User list should contain newly-created user")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(user));
.as("User list should contain newly-created user")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(user));
});
}
@ -107,10 +104,8 @@ class UserE2ETest {
page.create(user, password, email, phone, tenant);
Awaitility.await().untilAsserted(() ->
assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists")
);
Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists"));
page.createUserForm().buttonCancel().click();
}
@ -130,12 +125,12 @@ class UserE2ETest {
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(page.userList())
.as("User list should contain newly-modified User")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(editUser));
.as("User list should contain newly-modified User")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(editUser));
});
}
@Test
@Order(40)
void testDeleteUser() {
@ -147,10 +142,8 @@ class UserE2ETest {
browser.navigate().refresh();
assertThat(
page.userList()
).noneMatch(
it -> it.getText().contains(user) || it.getText().contains(editUser)
);
page.userList()).noneMatch(
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;
import static org.assertj.core.api.Assertions.assertThat;
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.WorkerGroupPage;
import java.time.Duration;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@ -38,10 +34,11 @@ import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class WorkerGroupE2ETest {
private static final String workerGroupName = "test_worker_group";
private static final String editWorkerGroupName = "edit_worker_group";
@ -50,9 +47,9 @@ class WorkerGroupE2ETest {
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(WorkerGroupPage.class);
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(WorkerGroupPage.class);
}
@Test
@ -61,7 +58,7 @@ class WorkerGroupE2ETest {
final WorkerGroupPage page = new WorkerGroupPage(browser);
WebDriverWaitFactory.createWebDriverWait(page.driver())
.until(ExpectedConditions.urlContains("/security/worker-group-manage"));
.until(ExpectedConditions.urlContains("/security/worker-group-manage"));
page.create(workerGroupName);
@ -69,9 +66,9 @@ class WorkerGroupE2ETest {
browser.navigate().refresh();
assertThat(page.workerGroupList())
.as("workerGroup list should contain newly-created workerGroup")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(workerGroupName));
.as("workerGroup list should contain newly-created workerGroup")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(workerGroupName));
});
}
@ -82,10 +79,8 @@ class WorkerGroupE2ETest {
page.create(workerGroupName);
Awaitility.await().untilAsserted(() ->
assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists")
);
Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists"));
page.createWorkerForm().buttonCancel().click();
}
@ -99,13 +94,12 @@ class WorkerGroupE2ETest {
Awaitility.await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(page.workerGroupList())
.as("workerGroup list should contain newly-modified workerGroup")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(editWorkerGroupName));
.as("workerGroup list should contain newly-modified workerGroup")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(editWorkerGroupName));
});
}
@Test
@Order(40)
void testDeleteWorkerGroup() {
@ -117,10 +111,8 @@ class WorkerGroupE2ETest {
browser.navigate().refresh();
assertThat(
page.workerGroupList()
).noneMatch(
it -> it.getText().contains(workerGroupName) || it.getText().contains(editWorkerGroupName)
);
page.workerGroupList()).noneMatch(
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;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
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.UserPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
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.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class WorkflowE2ETest {
private static final String project = "test-workflow-1";
private static final String workflow = "test-workflow-1";
@ -82,58 +80,55 @@ class WorkflowE2ETest {
userPage.update(user, user, email, phone, tenant)
.goToNav(ProjectPage.class)
.create(project)
;
.create(project);
}
@AfterAll
public static void cleanup() {
new NavBarPage(browser)
.goToNav(ProjectPage.class)
.goTo(project)
.goToTab(WorkflowDefinitionTab.class)
.delete(workflow);
.goToNav(ProjectPage.class)
.goTo(project)
.goToTab(WorkflowDefinitionTab.class)
.delete(workflow);
new NavBarPage(browser)
.goToNav(ProjectPage.class)
.delete(project);
.goToNav(ProjectPage.class)
.delete(project);
browser.navigate().refresh();
new NavBarPage(browser)
.goToNav(SecurityPage.class)
.goToTab(TenantPage.class)
.delete(tenant);
.goToNav(SecurityPage.class)
.goToTab(TenantPage.class)
.delete(tenant);
}
@Test
@Order(1)
void testCreateWorkflow() {
WorkflowDefinitionTab workflowDefinitionPage =
new ProjectPage(browser)
.goTo(project)
.goToTab(WorkflowDefinitionTab.class);
new ProjectPage(browser)
.goTo(project)
.goToTab(WorkflowDefinitionTab.class);
workflowDefinitionPage
.createWorkflow()
.createWorkflow()
.<ShellTaskForm> addTask(TaskType.SHELL)
.script("echo ${today}\necho ${global_param}\n")
.name("test-1")
.addParam("today", "${system.datetime}")
.submit()
.<ShellTaskForm>addTask(TaskType.SHELL)
.script("echo ${today}\necho ${global_param}\n")
.name("test-1")
.addParam("today", "${system.datetime}")
.submit()
.submit()
.name(workflow)
.addGlobalParam("global_param", "hello world")
.submit()
;
.submit()
.name(workflow)
.addGlobalParam("global_param", "hello world")
.submit();
Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList())
.as("Workflow list should contain newly-created workflow")
.anyMatch(
it -> it.getText().contains(workflow)
));
it -> it.getText().contains(workflow)));
workflowDefinitionPage.publish(workflow);
}
@ -142,28 +137,26 @@ class WorkflowE2ETest {
void testCreateSubWorkflow() {
final String workflow = "test-sub-workflow-1";
WorkflowDefinitionTab workflowDefinitionPage =
new ProjectPage(browser)
.goToNav(ProjectPage.class)
.goTo(project)
.goToTab(WorkflowDefinitionTab.class);
new ProjectPage(browser)
.goToNav(ProjectPage.class)
.goTo(project)
.goToTab(WorkflowDefinitionTab.class);
workflowDefinitionPage
.createSubProcessWorkflow()
.createSubProcessWorkflow()
.<SubWorkflowTaskForm> addTask(TaskType.SUB_PROCESS)
.childNode("test-workflow-1")
.name("test-sub-1")
.submit()
.<SubWorkflowTaskForm>addTask(TaskType.SUB_PROCESS)
.childNode("test-workflow-1")
.name("test-sub-1")
.submit()
.submit()
.name(workflow)
.addGlobalParam("global_param", "hello world")
.submit()
;
.submit()
.name(workflow)
.addGlobalParam("global_param", "hello world")
.submit();
Awaitility.await().untilAsserted(() -> assertThat(
workflowDefinitionPage.workflowList()
).anyMatch(it -> it.getText().contains(workflow)));
workflowDefinitionPage.workflowList()).anyMatch(it -> it.getText().contains(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;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
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.TenantPage;
import org.apache.dolphinscheduler.e2e.pages.security.UserPage;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
@ -39,16 +42,10 @@ import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import java.time.Duration;
import static org.assertj.core.api.Assertions.assertThat;
@DolphinScheduler(composeFiles = "docker/workflow-http/docker-compose.yaml")
public class WorkflowHttpTaskE2ETest {
private static final String project = "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)
.goToNav(ProjectPage.class)
.create(project)
;
.create(project);
}
@AfterAll
@ -116,7 +112,7 @@ public class WorkflowHttpTaskE2ETest {
workflowDefinitionPage
.createWorkflow()
.<HttpTaskForm> addTask(WorkflowForm.TaskType.HTTP)
.<HttpTaskForm>addTask(WorkflowForm.TaskType.HTTP)
.url(mockServerUrl)
.name("test-1")
.addParam("today", "${system.datetime}")
@ -125,18 +121,15 @@ public class WorkflowHttpTaskE2ETest {
.submit()
.name(workflow)
.addGlobalParam("global_param", "hello world")
.submit()
;
.submit();
Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList())
.as("Workflow list should contain newly-created workflow")
.anyMatch(
it -> it.getText().contains(workflow)
));
it -> it.getText().contains(workflow)));
workflowDefinitionPage.publish(workflow);
}
@Test
@Order(30)
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;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
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.TenantPage;
import org.apache.dolphinscheduler.e2e.pages.security.UserPage;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import java.time.Duration;
import static org.assertj.core.api.Assertions.assertThat;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
public class WorkflowJavaTaskE2ETest {
private static final String project = "test-workflow-1";
private static final String workflow = "test-workflow-1";
@ -98,8 +96,7 @@ public class WorkflowJavaTaskE2ETest {
userPage.update(user, user, email, phone, tenant)
.goToNav(ProjectPage.class)
.create(project)
;
.create(project);
}
@AfterAll
@ -122,8 +119,6 @@ public class WorkflowJavaTaskE2ETest {
.delete(tenant);
}
@Test
@Order(1)
void testCreateWorkflow() {
@ -134,7 +129,7 @@ public class WorkflowJavaTaskE2ETest {
workflowDefinitionPage
.createWorkflow()
.<JavaTaskForm> addTask(WorkflowForm.TaskType.JAVA)
.<JavaTaskForm>addTask(WorkflowForm.TaskType.JAVA)
.script(javaContent)
.name("test-1")
.addParam("today", "${system.datetime}")
@ -143,18 +138,15 @@ public class WorkflowJavaTaskE2ETest {
.submit()
.name(workflow)
.addGlobalParam("global_param", "hello world")
.submit()
;
.submit();
Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList())
.as("Workflow list should contain newly-created workflow")
.anyMatch(
it -> it.getText().contains(workflow)
));
it -> it.getText().contains(workflow)));
workflowDefinitionPage.publish(workflow);
}
@Test
@Order(30)
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;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
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.TenantPage;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import java.util.List;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import org.testcontainers.shaded.org.awaitility.Awaitility;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class WorkflowSwitchE2ETest {
private static final String project = "test-workflow-1";
private static final String workflow = "test-workflow-1";
private static final String ifBranchName = "key==1";
@ -60,31 +61,28 @@ class WorkflowSwitchE2ETest {
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(TenantPage.class)
.create(tenant)
.goToNav(ProjectPage.class)
.create(project)
;
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(TenantPage.class)
.create(tenant)
.goToNav(ProjectPage.class)
.create(project);
}
@AfterAll
public static void cleanup() {
new NavBarPage(browser)
.goToNav(ProjectPage.class)
.goTo(project)
.goToTab(WorkflowDefinitionTab.class)
.cancelPublishAll()
.deleteAll()
;
.goToNav(ProjectPage.class)
.goTo(project)
.goToTab(WorkflowDefinitionTab.class)
.cancelPublishAll()
.deleteAll();
new NavBarPage(browser)
.goToNav(ProjectPage.class)
.delete(project)
.goToNav(SecurityPage.class)
.goToTab(TenantPage.class)
.delete(tenant)
;
.goToNav(ProjectPage.class)
.delete(project)
.goToNav(SecurityPage.class)
.goToTab(TenantPage.class)
.delete(tenant);
}
@Test
@ -92,33 +90,33 @@ class WorkflowSwitchE2ETest {
void testCreateSwitchWorkflow() {
final WorkflowDefinitionTab workflowDefinitionPage =
new ProjectPage(browser)
.goTo(project)
.goToTab(WorkflowDefinitionTab.class);
new ProjectPage(browser)
.goTo(project)
.goToTab(WorkflowDefinitionTab.class);
WorkflowForm workflowForm = workflowDefinitionPage.createWorkflow();
workflowForm.<ShellTaskForm> addTask(TaskType.SHELL)
.script("echo ${today}\necho ${global_param}\n")
.name("pre-task")
.submit();
workflowForm.<ShellTaskForm>addTask(TaskType.SHELL)
.script("echo ${today}\necho ${global_param}\n")
.name("pre-task")
.submit();
SwitchTaskForm switchTaskForm = workflowForm.addTask(TaskType.SWITCH);
switchTaskForm.preTask("pre-task")
.name("switch")
.submit();
.name("switch")
.submit();
workflowForm.<ShellTaskForm>addTask(TaskType.SHELL)
.script("echo ${key}")
.preTask("switch")
.name(ifBranchName)
.submit();
.script("echo ${key}")
.preTask("switch")
.name(ifBranchName)
.submit();
workflowForm.<ShellTaskForm>addTask(TaskType.SHELL)
.script("echo ${key}")
.preTask("switch")
.name(elseBranchName)
.submit();
.script("echo ${key}")
.preTask("switch")
.name(elseBranchName)
.submit();
// format dag
workflowForm.formatDAG().confirm();
@ -130,13 +128,12 @@ class WorkflowSwitchE2ETest {
switchTaskForm.submit();
workflowForm.submit()
.name(workflow)
.addGlobalParam("key", "1")
.submit();
.name(workflow)
.addGlobalParam("key", "1")
.submit();
Awaitility.await().untilAsserted(() -> assertThat(
workflowDefinitionPage.workflowList()
).anyMatch(it -> it.getText().contains(workflow)));
workflowDefinitionPage.workflowList()).anyMatch(it -> it.getText().contains(workflow)));
workflowDefinitionPage.publish(workflow);
}
@ -178,8 +175,10 @@ class WorkflowSwitchE2ETest {
Awaitility.await().untilAsserted(() -> {
assertThat(taskInstances.size()).isEqualTo(3);
assertThat(taskInstances.stream().filter(row -> row.taskInstanceName().contains(ifBranchName)).count()).isEqualTo(1);
assertThat(taskInstances.stream().noneMatch(row -> row.taskInstanceName().contains(elseBranchName))).isTrue();
assertThat(taskInstances.stream().filter(row -> row.taskInstanceName().contains(ifBranchName)).count())
.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;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.dolphinscheduler.e2e.cases.workflow.BaseWorkflowE2ETest;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
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.resource.FileManagePage;
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.runners.MethodSorters;
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;
import org.junit.jupiter.api.TestMethodOrder;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@TestMethodOrder(MethodOrderer.MethodName.class)
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
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;
import java.time.Duration;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
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.IUser;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage;
import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab;
@ -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.TenantPage;
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.openqa.selenium.remote.RemoteWebDriver;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
@Slf4j
public abstract class BaseWorkflowE2ETest {
@ -83,8 +81,7 @@ public abstract class BaseWorkflowE2ETest {
await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList())
.as("Workflow list should contain newly-created workflow: %s", workflowName)
.anyMatch(
it -> it.getText().contains(workflowName)
));
it -> it.getText().contains(workflowName)));
}
protected void runWorkflow(String workflowName) {
@ -155,7 +152,8 @@ public abstract class BaseWorkflowE2ETest {
if (workflowInstances.size() > 1) {
throw new RuntimeException("More than one failed workflow instance found: " +
workflowInstances.stream()
.map(WorkflowInstanceTab.Row::workflowInstanceName).collect(Collectors.joining(", ")));
.map(WorkflowInstanceTab.Row::workflowInstanceName)
.collect(Collectors.joining(", ")));
}
return workflowInstances.get(0);
}, 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;
public class DefaultTenant implements ITenant {
@Override
public String getTenantCode() {
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;
import lombok.Data;
import org.apache.dolphinscheduler.e2e.models.tenant.BootstrapTenant;
import org.apache.dolphinscheduler.e2e.models.tenant.ITenant;
import lombok.Data;
@Data
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;
import org.apache.dolphinscheduler.e2e.models.tenant.ITenant;
public interface IUser {
String getUserName();
@ -31,5 +29,4 @@ public interface IUser {
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.models.users.IUser;
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.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
import lombok.SneakyThrows;
import java.time.Duration;
@Getter
public final class LoginPage extends NavBarPage {
@FindBys({
@FindBy(className = "input-user-name"),
@FindBy(tagName = "input"),
@FindBy(className = "input-user-name"),
@FindBy(tagName = "input"),
})
private WebElement inputUsername;
@FindBys( {
@FindBy(className = "input-password"),
@FindBy(tagName = "input"),
@FindBys({
@FindBy(className = "input-password"),
@FindBy(tagName = "input"),
})
private WebElement inputPassword;
@ -67,7 +64,8 @@ public final class LoginPage extends NavBarPage {
@SneakyThrows
public NavBarPage login(String username, String password) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(buttonSwitchLanguage));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(buttonSwitchLanguage));
buttonSwitchLanguage().click();
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;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import lombok.Getter;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
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.WebDriverWait;
@Getter
public final class CodeEditor {
@FindBys({
@FindBy(className = "monaco-editor"),
@FindBy(className = "view-line"),
@FindBy(className = "monaco-editor"),
@FindBy(className = "view-line"),
})
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;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import lombok.Getter;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
@Getter
public class HttpInput {
@FindBys({
@FindBy(className = "input-url-name"),
@FindBy(tagName = "input")
@ -43,8 +42,6 @@ public class HttpInput {
private WebDriver driver;
public HttpInput(WebDriver driver) {
PageFactory.initElements(driver, this);
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.security.SecurityPage;
import lombok.Getter;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
import java.time.Duration;
@Getter
public class NavBarPage {
protected final RemoteWebDriver driver;
@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) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(securityTab));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(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));
}
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());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file-manage"));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/resource/file-manage"));
return nav.cast(new ResourcePage(driver));
}
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());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/datasource"));
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
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.pages.datasource;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.security.Key;
import java.time.Duration;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@Getter
public class DataSourcePage extends NavBarPage implements NavBarPage.NavBarItem {
@FindBy(className = "btn-create-data-source")
private WebElement buttonCreateDataSource;
@FindBy(className = "data-source-items")
private List<WebElement> dataSourceItemsList;
@FindBys({
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
})
private WebElement buttonConfirm;
@FindBys({
@FindBy(className = "dialog-source-modal"),
})
private WebElement dataSourceModal;
private final CreateDataSourceForm createDataSourceForm;
public DataSourcePage(RemoteWebDriver driver) {
super(driver);
createDataSourceForm = new CreateDataSourceForm();
}
public DataSourcePage createDataSource(String dataSourceType, String dataSourceName, String dataSourceDescription, String ip, String port, String userName, String password, String database,
String jdbcParams) {
buttonCreateDataSource().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(
new By.ByClassName("dialog-source-modal")));
dataSourceModal().findElement(By.className(dataSourceType.toUpperCase()+"-box")).click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.className("dialog-create-data-source")), dataSourceType.toUpperCase()));
createDataSourceForm().inputDataSourceName().sendKeys(dataSourceName);
createDataSourceForm().inputDataSourceDescription().sendKeys(dataSourceDescription);
createDataSourceForm().inputIP().sendKeys(ip);
createDataSourceForm().inputPort().sendKeys(Keys.CONTROL + "a");
createDataSourceForm().inputPort().sendKeys(Keys.BACK_SPACE);
createDataSourceForm().inputPort().sendKeys(port);
createDataSourceForm().inputUserName().sendKeys(userName);
createDataSourceForm().inputPassword().sendKeys(password);
createDataSourceForm().inputDataBase().sendKeys(database);
if (!"".equals(jdbcParams)) {
createDataSourceForm().inputJdbcParams().sendKeys(jdbcParams);
}
createDataSourceForm().buttonSubmit().click();
return this;
}
public DataSourcePage delete(String name) {
dataSourceItemsList()
.stream()
.filter(it -> it.getText().contains(name))
.flatMap(it -> it.findElements(By.className("btn-delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in data source list"))
.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
return this;
}
@Getter
public class CreateDataSourceForm {
CreateDataSourceForm() {
PageFactory.initElements(driver, this);
}
@FindBy(className = "n-base-select-option__content")
private List<WebElement> selectDataSourceType;
@FindBys({
@FindBy(className = "btn-data-source-type-drop-down"),
@FindBy(className = "n-base-selection"),
})
private WebElement btnDataSourceTypeDropdown;
@FindBys({
@FindBy(className = "input-data-source-name"),
@FindBy(tagName = "input"),
})
private WebElement inputDataSourceName;
@FindBys({
@FindBy(className = "input-data-source-description"),
@FindBy(tagName = "textarea"),
})
private WebElement inputDataSourceDescription;
@FindBys({
@FindBy(className = "input-ip"),
@FindBy(tagName = "input"),
})
private WebElement inputIP;
@FindBys({
@FindBy(className = "input-port"),
@FindBy(tagName = "input"),
})
private WebElement inputPort;
@FindBys({
@FindBy(className = "input-username"),
@FindBy(tagName = "input"),
})
private WebElement inputUserName;
@FindBys({
@FindBy(className = "input-password"),
@FindBy(tagName = "input"),
})
private WebElement inputPassword;
@FindBys({
@FindBy(className = "input-data-base"),
@FindBy(tagName = "input"),
})
private WebElement inputDataBase;
@FindBys({
@FindBy(className = "input-jdbc-params"),
@FindBy(tagName = "textarea"),
})
private WebElement inputJdbcParams;
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
@FindBy(className = "btn-test-connection")
private WebElement btnTestConnection;
@FindBys({
@FindBy(className = "input-zeppelin_rest_endpoint"),
@FindBy(tagName = "input"),
})
private WebElement inputZeppelinRestEndpoint;
@FindBys({
@FindBy(className = "input-kubeConfig"),
@FindBy(tagName = "textarea"),
})
private WebElement inputKubeConfig;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.pages.datasource;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
@Getter
public class DataSourcePage extends NavBarPage implements NavBarPage.NavBarItem {
@FindBy(className = "btn-create-data-source")
private WebElement buttonCreateDataSource;
@FindBy(className = "data-source-items")
private List<WebElement> dataSourceItemsList;
@FindBys({
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
})
private WebElement buttonConfirm;
@FindBys({
@FindBy(className = "dialog-source-modal"),
})
private WebElement dataSourceModal;
private final CreateDataSourceForm createDataSourceForm;
public DataSourcePage(RemoteWebDriver driver) {
super(driver);
createDataSourceForm = new CreateDataSourceForm();
}
public DataSourcePage createDataSource(String dataSourceType, String dataSourceName, String dataSourceDescription,
String ip, String port, String userName, String password, String database,
String jdbcParams) {
buttonCreateDataSource().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(
new By.ByClassName("dialog-source-modal")));
dataSourceModal().findElement(By.className(dataSourceType.toUpperCase() + "-box")).click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.textToBePresentInElement(
driver.findElement(By.className("dialog-create-data-source")), dataSourceType.toUpperCase()));
createDataSourceForm().inputDataSourceName().sendKeys(dataSourceName);
createDataSourceForm().inputDataSourceDescription().sendKeys(dataSourceDescription);
createDataSourceForm().inputIP().sendKeys(ip);
createDataSourceForm().inputPort().sendKeys(Keys.CONTROL + "a");
createDataSourceForm().inputPort().sendKeys(Keys.BACK_SPACE);
createDataSourceForm().inputPort().sendKeys(port);
createDataSourceForm().inputUserName().sendKeys(userName);
createDataSourceForm().inputPassword().sendKeys(password);
createDataSourceForm().inputDataBase().sendKeys(database);
if (!"".equals(jdbcParams)) {
createDataSourceForm().inputJdbcParams().sendKeys(jdbcParams);
}
createDataSourceForm().buttonSubmit().click();
return this;
}
public DataSourcePage delete(String name) {
dataSourceItemsList()
.stream()
.filter(it -> it.getText().contains(name))
.flatMap(it -> it.findElements(By.className("btn-delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in data source list"))
.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
return this;
}
@Getter
public class CreateDataSourceForm {
CreateDataSourceForm() {
PageFactory.initElements(driver, this);
}
@FindBy(className = "n-base-select-option__content")
private List<WebElement> selectDataSourceType;
@FindBys({
@FindBy(className = "btn-data-source-type-drop-down"),
@FindBy(className = "n-base-selection"),
})
private WebElement btnDataSourceTypeDropdown;
@FindBys({
@FindBy(className = "input-data-source-name"),
@FindBy(tagName = "input"),
})
private WebElement inputDataSourceName;
@FindBys({
@FindBy(className = "input-data-source-description"),
@FindBy(tagName = "textarea"),
})
private WebElement inputDataSourceDescription;
@FindBys({
@FindBy(className = "input-ip"),
@FindBy(tagName = "input"),
})
private WebElement inputIP;
@FindBys({
@FindBy(className = "input-port"),
@FindBy(tagName = "input"),
})
private WebElement inputPort;
@FindBys({
@FindBy(className = "input-username"),
@FindBy(tagName = "input"),
})
private WebElement inputUserName;
@FindBys({
@FindBy(className = "input-password"),
@FindBy(tagName = "input"),
})
private WebElement inputPassword;
@FindBys({
@FindBy(className = "input-data-base"),
@FindBy(tagName = "input"),
})
private WebElement inputDataBase;
@FindBys({
@FindBy(className = "input-jdbc-params"),
@FindBy(tagName = "textarea"),
})
private WebElement inputJdbcParams;
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
@FindBy(className = "btn-test-connection")
private WebElement btnTestConnection;
@FindBys({
@FindBy(className = "input-zeppelin_rest_endpoint"),
@FindBy(tagName = "input"),
})
private WebElement inputZeppelinRestEndpoint;
@FindBys({
@FindBy(className = "input-kubeConfig"),
@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;
import lombok.SneakyThrows;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
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.WorkflowDefinitionTab;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab;
import lombok.Getter;
import lombok.SneakyThrows;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import lombok.Getter;
import org.openqa.selenium.support.ui.ExpectedConditions;
@Getter
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")
private WebElement menuProcessDefinition;
@ -52,12 +53,14 @@ public final class ProjectDetailPage extends NavBarPage {
public <T extends Tab> T goToTab(Class<T> tab) {
if (tab == WorkflowDefinitionTab.class) {
menuProcessDefinition().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/workflow-definition"));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/workflow-definition"));
return tab.cast(new WorkflowDefinitionTab(driver));
}
if (tab == WorkflowInstanceTab.class) {
menuProcessInstances().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/workflow/instances"));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/workflow/instances"));
return tab.cast(new WorkflowInstanceTab(driver));
}
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;
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.NavBarItem;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
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.FindBys;
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
public final class ProjectPage extends NavBarPage implements NavBarItem {
@FindBy(className = "btn-create-project")
private WebElement buttonCreateProject;
@ -77,7 +77,6 @@ public final class ProjectPage extends NavBarPage implements NavBarItem {
return this;
}
public ProjectPage delete(String project) {
projectList()
.stream()
@ -104,6 +103,7 @@ public final class ProjectPage extends NavBarPage implements NavBarItem {
@Getter
public class CreateProjectForm {
CreateProjectForm() {
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;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
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.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import java.util.List;
import java.util.stream.Collectors;
@Getter
public final class TaskInstanceTab extends NavBarPage implements ProjectDetailPage.Tab {
@ -45,14 +46,15 @@ public final class TaskInstanceTab extends NavBarPage implements ProjectDetailPa
public List<Row> instances() {
return instanceList()
.stream()
.filter(WebElement::isDisplayed)
.map(Row::new)
.collect(Collectors.toList());
.stream()
.filter(WebElement::isDisplayed)
.map(Row::new)
.collect(Collectors.toList());
}
@RequiredArgsConstructor
public static class Row {
private final WebElement row;
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.stream.Collectors;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
@ -35,10 +37,9 @@ import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import lombok.Getter;
@Getter
public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDetailPage.Tab {
@FindBy(className = "btn-create-process")
private WebElement buttonCreateProcess;
@ -61,8 +62,8 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
private WebElement buttonConfirm;
@FindBys({
@FindBy(className = "n-dialog__action"),
@FindBy(className = "n-button--default-type"),
@FindBy(className = "n-dialog__action"),
@FindBy(className = "n-button--default-type"),
})
private WebElement publishSuccessButtonCancel;
@ -91,13 +92,13 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
public WorkflowDefinitionTab publish(String workflow) {
workflowList()
.stream()
.filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("btn-publish")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("Can not find publish button in workflow definition"))
.click();
.stream()
.filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("btn-publish")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("Can not find publish button in workflow definition"))
.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
@ -108,13 +109,13 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
public WorkflowRunDialog run(String workflow) {
workflowList()
.stream()
.filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("btn-run")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("Can not find run button in workflow definition"))
.click();
.stream()
.filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("btn-run")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("Can not find run button in workflow definition"))
.click();
return new WorkflowRunDialog(this);
}
@ -136,19 +137,18 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
public WorkflowDefinitionTab delete(String workflow) {
Awaitility.await().untilAsserted(() -> assertThat(workflowList())
.as("Workflow list should contain newly-created workflow")
.anyMatch(
it -> it.getText().contains(workflow)
));
.as("Workflow list should contain newly-created workflow")
.anyMatch(
it -> it.getText().contains(workflow)));
workflowList()
.stream()
.filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("btn-delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("Can not find delete button in workflow definition"))
.click();
.stream()
.filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("btn-delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("Can not find delete button in workflow definition"))
.click();
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.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.SubWorkflowTaskForm;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SwitchTaskForm;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.JavaTaskForm;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.Getter;
import lombok.SneakyThrows;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
@ -38,17 +39,14 @@ import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
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")
@Getter
public final class WorkflowForm {
private WebDriver driver;
private final WorkflowSaveDialog saveForm;
private final WorkflowFormatDialog formatDialog;
@ -95,7 +93,8 @@ public final class WorkflowForm {
public WebElement getTask(String taskName) {
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()
.filter(t -> t.getText().contains(taskName))
@ -110,7 +109,8 @@ public final class WorkflowForm {
public WorkflowSaveDialog submit() {
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);
}

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;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.pagefactory.ByChained;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.List;
import java.util.stream.Stream;
@Getter
public final class WorkflowFormatDialog {
private final WebDriver driver;
private final WorkflowForm parent;

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.stream.Collectors;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.openqa.selenium.support.pagefactory.ByChained;
@Getter
public final class WorkflowInstanceTab extends NavBarPage implements ProjectDetailPage.Tab {
@FindBy(className = "items-workflow-instances")
private List<WebElement> instanceList;
@FindBys({
@FindBy(className = "btn-selected"),
@FindBy(className = "n-checkbox-box"),
@FindBy(className = "btn-selected"),
@FindBy(className = "n-checkbox-box"),
})
private WebElement checkBoxSelectAll;
@ -62,10 +63,10 @@ public final class WorkflowInstanceTab extends NavBarPage implements ProjectDeta
public List<Row> instances() {
return instanceList()
.stream()
.filter(WebElement::isDisplayed)
.map(Row::new)
.collect(Collectors.toList());
.stream()
.filter(WebElement::isDisplayed)
.map(Row::new)
.collect(Collectors.toList());
}
public WorkflowInstanceTab deleteAll() {
@ -84,6 +85,7 @@ public final class WorkflowInstanceTab extends NavBarPage implements ProjectDeta
@RequiredArgsConstructor
public static class Row {
private final WebElement row;
public String workflowInstanceName() {
@ -108,11 +110,11 @@ public final class WorkflowInstanceTab extends NavBarPage implements ProjectDeta
public Row rerun() {
row.findElements(new ByChained(By.className("btn-rerun"), By.className("n-button__content")))
.stream()
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("Cannot find rerun button"))
.click();
.stream()
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("Cannot find rerun button"))
.click();
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 lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
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.WebDriverWait;
@Getter
public final class WorkflowRunDialog {
private final WorkflowDefinitionTab parent;
@FindBy(className = "btn-submit")
@ -47,9 +44,12 @@ public final class WorkflowRunDialog {
}
public WorkflowDefinitionTab submit() {
By runDialogTitleXpath = By.xpath(String.format("//*[contains(text(), '%s')]", "Please set the parameters before starting"));
WebDriverWaitFactory.createWebDriverWait(parent.driver()).until(ExpectedConditions.visibilityOfElementLocated(runDialogTitleXpath));
WebDriverWaitFactory.createWebDriverWait(parent.driver()).until(ExpectedConditions.elementToBeClickable(buttonSubmit()));
By runDialogTitleXpath =
By.xpath(String.format("//*[contains(text(), '%s')]", "Please set the parameters before starting"));
WebDriverWaitFactory.createWebDriverWait(parent.driver())
.until(ExpectedConditions.visibilityOfElementLocated(runDialogTitleXpath));
WebDriverWaitFactory.createWebDriverWait(parent.driver())
.until(ExpectedConditions.elementToBeClickable(buttonSubmit()));
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;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.pagefactory.ByChained;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.List;
import java.util.stream.Stream;
@Getter
public final class WorkflowSaveDialog {
private final WebDriver driver;
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(1).sendKeys(value);
} 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+1).sendKeys(value);
globalParamsItems().findElements(By.tagName("input")).get(len + 1).sendKeys(value);
}
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.project.workflow.WorkflowForm;
import org.openqa.selenium.WebDriver;
public class HttpTaskForm extends TaskNodeForm{
public class HttpTaskForm extends TaskNodeForm {
private WebDriver driver;
private HttpInput httpInput;
public HttpTaskForm(WorkflowForm parent) {
super(parent);
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.project.workflow.WorkflowForm;
import org.openqa.selenium.WebDriver;
public class JavaTaskForm extends TaskNodeForm{
public class JavaTaskForm extends TaskNodeForm {
private CodeEditor codeEditor;
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 lombok.Getter;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
@Getter
public final class ShellTaskForm extends TaskNodeForm {
private CodeEditor codeEditor;
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.pages.project.workflow.WorkflowForm;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.List;
@Getter
public final class SubWorkflowTaskForm extends TaskNodeForm {
@FindBys({
@FindBy(className = "select-child-node"),
@FindBy(className = "n-base-selection"),
@ -47,7 +47,6 @@ public final class SubWorkflowTaskForm extends TaskNodeForm {
private WebDriver driver;
public SubWorkflowTaskForm(WorkflowForm parent) {
super(parent);
@ -55,12 +54,14 @@ public final class SubWorkflowTaskForm extends TaskNodeForm {
}
public SubWorkflowTaskForm childNode(String node) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(btnSelectChildNodeDropdown));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(btnSelectChildNodeDropdown));
btnSelectChildNodeDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(By.className(
"n-base-select-option__content")));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.visibilityOfElementLocated(By.className(
"n-base-select-option__content")));
selectChildNode()
.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;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
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.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.List;
@Getter
public final class SwitchTaskForm extends TaskNodeForm {
@ -51,14 +51,14 @@ public final class SwitchTaskForm extends TaskNodeForm {
}
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");
WebDriverWaitFactory.createWebDriverWait(parent().driver())
.until(ExpectedConditions.visibilityOfElementLocated(optionsLocator));
List<WebElement> webElements = parent().driver().findElements(optionsLocator);
List<WebElement> webElements = parent().driver().findElements(optionsLocator);
webElements.stream()
.filter(it -> it.getText().contains(elseBranchName))
.findFirst()
@ -71,19 +71,20 @@ public final class SwitchTaskForm extends TaskNodeForm {
}
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.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");
WebDriverWaitFactory.createWebDriverWait(parent().driver())
.until(ExpectedConditions.visibilityOfElementLocated(optionsLocator));
List<WebElement> webElements = parent().driver().findElements(optionsLocator);
List<WebElement> webElements = parent().driver().findElements(optionsLocator);
webElements.stream()
.filter(it -> it.getText().contains(ifBranchName))
.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;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor;
import lombok.Getter;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -29,6 +31,7 @@ import org.openqa.selenium.support.PageFactory;
@Getter
public final class SwitchTaskIfBranch {
private final WebDriver driver;
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;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
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.JavascriptExecutor;
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.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.List;
@Getter
public abstract class TaskNodeForm {
@FindBys({
@FindBy(className = "input-node-name"),
@FindBy(tagName = "input")
@ -85,7 +86,6 @@ public abstract class TaskNodeForm {
})
private WebElement selectResource;
private final WorkflowForm parent;
TaskNodeForm(WorkflowForm parent) {
@ -168,7 +168,8 @@ public abstract class TaskNodeForm {
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()
.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
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.pages.resource;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
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 org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.File;
import java.time.Duration;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
@Getter
public class FileManagePage extends NavBarPage implements ResourcePage.Tab {
@FindBy(className = "btn-create-directory")
private WebElement buttonCreateDirectory;
@FindBy(className = "btn-create-file")
private WebElement buttonCreateFile;
@FindBy(className = "btn-upload-resource")
private WebElement buttonUploadFile;
private final CreateDirectoryBox createDirectoryBox;
private final RenameBox renameBox;
private final UploadFileBox uploadFileBox;
private final EditFileBox editFileBox;
@FindBy(className = "items")
private List<WebElement> fileList;
@FindBys({
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
})
private WebElement buttonConfirm;
@FindBys({
@FindBy(className = "monaco-editor"),
@FindBy(className = "view-line"),
})
private WebElement editor;
public FileManagePage(RemoteWebDriver driver) {
super(driver);
createDirectoryBox = new CreateDirectoryBox();
renameBox = new RenameBox();
uploadFileBox = new UploadFileBox();
editFileBox = new EditFileBox();
}
public FileManagePage createDirectory(String name) {
buttonCreateDirectory().click();
createDirectoryBox().inputDirectoryName().sendKeys(name);
createDirectoryBox().buttonSubmit().click();
return this;
}
public FileManagePage cancelCreateDirectory(String name) {
buttonCreateDirectory().click();
createDirectoryBox().inputDirectoryName().sendKeys(name);
createDirectoryBox().buttonCancel().click();
return this;
}
public FileManagePage rename(String currentName, String AfterName) {
fileList()
.stream()
.filter(it -> it.getText().contains(currentName))
.flatMap(it -> it.findElements(By.className("btn-rename")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No rename button in file manage list"))
.click();
renameBox().inputName().sendKeys(Keys.CONTROL + "a");
renameBox().inputName().sendKeys(Keys.BACK_SPACE);
renameBox().inputName().sendKeys(AfterName);
renameBox().buttonSubmit().click();
return this;
}
public FileManagePage createSubDirectory(String directoryName, String subDirectoryName) {
fileList()
.stream()
.filter(it -> it.getText().contains(directoryName))
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format("No %s in file manage list", directoryName)))
.click();
buttonCreateDirectory().click();
createDirectoryBox().inputDirectoryName().sendKeys(subDirectoryName);
createDirectoryBox().buttonSubmit().click();
return this;
}
public FileManagePage delete(String name) {
fileList()
.stream()
.filter(it -> it.getText().contains(name))
.flatMap(it -> it.findElements(By.className("btn-delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in file manage list"))
.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
return this;
}
// todo: add file type
public FileManagePage createFile(String fileName, String scripts) {
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(buttonCreateFile()));
buttonCreateFile().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file/create"));
CreateFileBox createFileBox = new CreateFileBox();
createFileBox.inputFileName().sendKeys(fileName);
createFileBox.codeEditor().content(scripts);
createFileBox.buttonSubmit().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file-manage"));
return this;
}
public FileManagePage createFileUntilSuccess(String fileName, String scripts) {
createFile(fileName, scripts);
await()
.untilAsserted(() ->
assertThat(fileList())
.as("File list should contain newly-created file: " + fileName)
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(fileName)));
return this;
}
public FileManagePage editFile(String fileName, String scripts) {
fileList()
.stream()
.filter(it -> it.getText().contains(fileName))
.flatMap(it -> it.findElements(By.className("btn-edit")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in file manage list"))
.click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/edit"));
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.tagName("body")), fileName));
editFileBox().codeEditor().content(scripts);
editFileBox().buttonSubmit().click();
return this;
}
public FileManagePage uploadFile(String filePath) {
buttonUploadFile().click();
driver.setFileDetector(new LocalFileDetector());
uploadFileBox().buttonUpload().sendKeys(filePath);
uploadFileBox().buttonSubmit().click();
return this;
}
public FileManagePage downloadFile(String fileName) {
fileList()
.stream()
.filter(it -> it.getText().contains(fileName))
.flatMap(it -> it.findElements(By.className("btn-download")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No download button in file manage list"))
.click();
return this;
}
@Getter
public class CreateDirectoryBox {
CreateDirectoryBox() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-directory-name"),
@FindBy(tagName = "input"),
})
private WebElement inputDirectoryName;
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
}
@Getter
public class RenameBox {
RenameBox() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-name"),
@FindBy(tagName = "input"),
})
private WebElement inputName;
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
}
@Getter
public class CreateFileBox {
CreateFileBox() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-file-name"),
@FindBy(tagName = "input"),
})
private WebElement inputFileName;
private final CodeEditor codeEditor = new CodeEditor(driver);
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
}
@Getter
public class EditFileBox {
EditFileBox() {
PageFactory.initElements(driver, this);
}
CodeEditor codeEditor = new CodeEditor(driver);
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
}
@Getter
public class UploadFileBox {
UploadFileBox() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "btn-upload"),
@FindBy(tagName = "input"),
})
private WebElement buttonUpload;
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.pages.resource;
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.pages.common.NavBarPage;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
@Getter
public class FileManagePage extends NavBarPage implements ResourcePage.Tab {
@FindBy(className = "btn-create-directory")
private WebElement buttonCreateDirectory;
@FindBy(className = "btn-create-file")
private WebElement buttonCreateFile;
@FindBy(className = "btn-upload-resource")
private WebElement buttonUploadFile;
private final CreateDirectoryBox createDirectoryBox;
private final RenameBox renameBox;
private final UploadFileBox uploadFileBox;
private final EditFileBox editFileBox;
@FindBy(className = "items")
private List<WebElement> fileList;
@FindBys({
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
})
private WebElement buttonConfirm;
@FindBys({
@FindBy(className = "monaco-editor"),
@FindBy(className = "view-line"),
})
private WebElement editor;
public FileManagePage(RemoteWebDriver driver) {
super(driver);
createDirectoryBox = new CreateDirectoryBox();
renameBox = new RenameBox();
uploadFileBox = new UploadFileBox();
editFileBox = new EditFileBox();
}
public FileManagePage createDirectory(String name) {
buttonCreateDirectory().click();
createDirectoryBox().inputDirectoryName().sendKeys(name);
createDirectoryBox().buttonSubmit().click();
return this;
}
public FileManagePage cancelCreateDirectory(String name) {
buttonCreateDirectory().click();
createDirectoryBox().inputDirectoryName().sendKeys(name);
createDirectoryBox().buttonCancel().click();
return this;
}
public FileManagePage rename(String currentName, String AfterName) {
fileList()
.stream()
.filter(it -> it.getText().contains(currentName))
.flatMap(it -> it.findElements(By.className("btn-rename")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No rename button in file manage list"))
.click();
renameBox().inputName().sendKeys(Keys.CONTROL + "a");
renameBox().inputName().sendKeys(Keys.BACK_SPACE);
renameBox().inputName().sendKeys(AfterName);
renameBox().buttonSubmit().click();
return this;
}
public FileManagePage createSubDirectory(String directoryName, String subDirectoryName) {
fileList()
.stream()
.filter(it -> it.getText().contains(directoryName))
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format("No %s in file manage list", directoryName)))
.click();
buttonCreateDirectory().click();
createDirectoryBox().inputDirectoryName().sendKeys(subDirectoryName);
createDirectoryBox().buttonSubmit().click();
return this;
}
public FileManagePage delete(String name) {
fileList()
.stream()
.filter(it -> it.getText().contains(name))
.flatMap(it -> it.findElements(By.className("btn-delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in file manage list"))
.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
return this;
}
// todo: add file type
public FileManagePage createFile(String fileName, String scripts) {
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(buttonCreateFile()));
buttonCreateFile().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file/create"));
CreateFileBox createFileBox = new CreateFileBox();
createFileBox.inputFileName().sendKeys(fileName);
createFileBox.codeEditor().content(scripts);
createFileBox.buttonSubmit().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file-manage"));
return this;
}
public FileManagePage createFileUntilSuccess(String fileName, String scripts) {
createFile(fileName, scripts);
await()
.untilAsserted(() -> assertThat(fileList())
.as("File list should contain newly-created file: " + fileName)
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(fileName)));
return this;
}
public FileManagePage editFile(String fileName, String scripts) {
fileList()
.stream()
.filter(it -> it.getText().contains(fileName))
.flatMap(it -> it.findElements(By.className("btn-edit")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in file manage list"))
.click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/edit"));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.tagName("body")), fileName));
editFileBox().codeEditor().content(scripts);
editFileBox().buttonSubmit().click();
return this;
}
public FileManagePage uploadFile(String filePath) {
buttonUploadFile().click();
driver.setFileDetector(new LocalFileDetector());
uploadFileBox().buttonUpload().sendKeys(filePath);
uploadFileBox().buttonSubmit().click();
return this;
}
public FileManagePage downloadFile(String fileName) {
fileList()
.stream()
.filter(it -> it.getText().contains(fileName))
.flatMap(it -> it.findElements(By.className("btn-download")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No download button in file manage list"))
.click();
return this;
}
@Getter
public class CreateDirectoryBox {
CreateDirectoryBox() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-directory-name"),
@FindBy(tagName = "input"),
})
private WebElement inputDirectoryName;
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
}
@Getter
public class RenameBox {
RenameBox() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-name"),
@FindBy(tagName = "input"),
})
private WebElement inputName;
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
}
@Getter
public class CreateFileBox {
CreateFileBox() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-file-name"),
@FindBy(tagName = "input"),
})
private WebElement inputFileName;
private final CodeEditor codeEditor = new CodeEditor(driver);
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
}
@Getter
public class EditFileBox {
EditFileBox() {
PageFactory.initElements(driver, this);
}
CodeEditor codeEditor = new CodeEditor(driver);
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
}
@Getter
public class UploadFileBox {
UploadFileBox() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "btn-upload"),
@FindBy(tagName = "input"),
})
private WebElement buttonUpload;
@FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@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
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.pages.resource;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.time.Duration;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
@Getter
public class ResourcePage extends NavBarPage implements NavBarPage.NavBarItem {
@FindBy(css = ".tab-vertical > .n-menu-item:nth-child(1) > .n-menu-item-content")
private WebElement fileManageTab;
public ResourcePage(RemoteWebDriver driver) {
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"));
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(fileManageTab));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", fileManageTab());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/file-manage"));
return tab.cast(new FileManagePage(driver));
}
throw new UnsupportedOperationException("Unknown tab: " + tab.getName());
}
public interface Tab {
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.dolphinscheduler.e2e.pages.resource;
import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import lombok.Getter;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
@Getter
public class ResourcePage extends NavBarPage implements NavBarPage.NavBarItem {
@FindBy(css = ".tab-vertical > .n-menu-item:nth-child(1) > .n-menu-item-content")
private WebElement fileManageTab;
public ResourcePage(RemoteWebDriver driver) {
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"));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(fileManageTab));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", fileManageTab());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/file-manage"));
return tab.cast(new FileManagePage(driver));
}
throw new UnsupportedOperationException("Unknown tab: " + tab.getName());
}
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 lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
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.FindBys;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
@Getter
public final class ClusterPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-cluster")
private WebElement buttonCreateCluster;
@ -45,8 +44,8 @@ public final class ClusterPage extends NavBarPage implements SecurityPage.Tab {
private List<WebElement> clusterList;
@FindBys({
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
})
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"))
.click();
editClusterForm().inputClusterName().sendKeys(Keys.CONTROL + "a");
editClusterForm().inputClusterName().sendKeys(Keys.BACK_SPACE);
editClusterForm().inputClusterName().sendKeys(name);
@ -114,31 +112,32 @@ public final class ClusterPage extends NavBarPage implements SecurityPage.Tab {
@Getter
public class ClusterForm {
ClusterForm() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-cluster-name"),
@FindBy(tagName = "input"),
@FindBy(className = "input-cluster-name"),
@FindBy(tagName = "input"),
})
private WebElement inputClusterName;
@FindBys({
@FindBy(className = "input-cluster-config"),
@FindBy(tagName = "textarea"),
@FindBy(className = "input-cluster-config"),
@FindBy(tagName = "textarea"),
})
private WebElement inputClusterConfig;
@FindBys({
@FindBy(className = "input-cluster-desc"),
@FindBy(tagName = "input"),
@FindBy(className = "input-cluster-desc"),
@FindBy(tagName = "input"),
})
private WebElement inputClusterDesc;
@FindBys({
@FindBy(className = "n-base-selection-tags"),
@FindBy(className = "n-tag__content"),
@FindBy(className = "n-base-selection-tags"),
@FindBy(className = "n-tag__content"),
})
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.pages.common.NavBarPage;
import java.time.Duration;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
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.FindBys;
import org.openqa.selenium.support.PageFactory;
import lombok.Getter;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@Getter
public final class EnvironmentPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-environment")
private WebElement buttonCreateEnvironment;
@ -47,8 +46,8 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
private List<WebElement> environmentList;
@FindBys({
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
})
private WebElement buttonConfirm;
@ -68,8 +67,9 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
createEnvironmentForm().inputEnvironmentDesc().sendKeys(desc);
editEnvironmentForm().btnSelectWorkerGroupDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
editEnvironmentForm().selectWorkerGroupList()
.stream()
.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) {
environmentList()
.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())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in environment list"))
.click();
editEnvironmentForm().inputEnvironmentName().sendKeys(Keys.CONTROL + "a");
editEnvironmentForm().inputEnvironmentName().sendKeys(Keys.BACK_SPACE);
editEnvironmentForm().inputEnvironmentName().sendKeys(name);
@ -107,8 +107,9 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
if (editEnvironmentForm().selectedWorkerGroup().getAttribute("innerHTML").equals(workerGroup)) {
editEnvironmentForm().btnSelectWorkerGroupDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
editEnvironmentForm().selectWorkerGroupList()
.stream()
.filter(it -> it.getText().contains(workerGroup))
@ -140,25 +141,26 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
@Getter
public class EnvironmentForm {
EnvironmentForm() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-environment-name"),
@FindBy(tagName = "input"),
@FindBy(className = "input-environment-name"),
@FindBy(tagName = "input"),
})
private WebElement inputEnvironmentName;
@FindBys({
@FindBy(className = "input-environment-config"),
@FindBy(tagName = "textarea"),
@FindBy(className = "input-environment-config"),
@FindBy(tagName = "textarea"),
})
private WebElement inputEnvironmentConfig;
@FindBys({
@FindBy(className = "input-environment-desc"),
@FindBy(tagName = "input"),
@FindBy(className = "input-environment-desc"),
@FindBy(tagName = "input"),
})
private WebElement inputEnvironmentDesc;
@ -172,8 +174,8 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
private List<WebElement> selectWorkerGroupList;
@FindBys({
@FindBy(className = "n-base-selection-tags"),
@FindBy(className = "n-tag__content"),
@FindBy(className = "n-base-selection-tags"),
@FindBy(className = "n-tag__content"),
})
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 lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import lombok.Getter;
@Getter
public final class NamespacePage extends NavBarPage implements SecurityPage.Tab {
@FindBy(id = "btnCreateNamespace")
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) {
namespaceList()
.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())
.filter(WebElement::isDisplayed)
.findFirst()
@ -75,6 +77,7 @@ public final class NamespacePage extends NavBarPage implements SecurityPage.Tab
@Getter
public class NamespaceForm {
NamespaceForm() {
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 java.security.Key;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
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.PageFactory;
import lombok.Getter;
@Getter
public final class QueuePage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-queue")
private WebElement buttonCreateQueue;
@ -84,13 +84,14 @@ public final class QueuePage extends NavBarPage implements SecurityPage.Tab {
@Getter
public class QueueForm {
QueueForm() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-queue-name"),
@FindBy(tagName = "input"),
@FindBy(className = "input-queue-name"),
@FindBy(tagName = "input"),
})
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.NavBarItem;
import lombok.Getter;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
import java.time.Duration;
@Getter
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) {
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());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/tenant-manage"));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/tenant-manage"));
return tab.cast(new TenantPage(driver));
}
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());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/user-manage"));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/user-manage"));
return tab.cast(new UserPage(driver));
}
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());
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));
}
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());
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));
}
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());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/environment-manage"));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/environment-manage"));
return tab.cast(new EnvironmentPage(driver));
}
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());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/cluster-manage"));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/cluster-manage"));
return tab.cast(new ClusterPage(driver));
}
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());
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/token-manage"));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.urlContains("/security/token-manage"));
return tab.cast(new TokenPage(driver));
}
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());
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));
}

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;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.apache.dolphinscheduler.e2e.models.tenant.ITenant;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
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.JavascriptExecutor;
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.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
public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-tenant")
private WebElement buttonCreateTenant;
@ -132,6 +129,7 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
@Getter
public class TenantForm {
TenantForm() {
PageFactory.initElements(driver, this);
}
@ -160,6 +158,7 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
@RequiredArgsConstructor
public static class Row {
private final WebElement row;
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.security.SecurityPage.Tab;
import java.time.Duration;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
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.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Getter;
import com.google.common.base.Strings;
@Getter
public final class TokenPage extends NavBarPage implements Tab {
@FindBy(className = "btn-create-token")
private WebElement buttonCreateToken;
@ -49,8 +48,8 @@ public final class TokenPage extends NavBarPage implements Tab {
private List<WebElement> tokenList;
@FindBys({
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
})
private WebElement buttonConfirm;
@ -70,10 +69,12 @@ public final class TokenPage extends NavBarPage implements Tab {
public TokenPage create(String userName) {
buttonCreateToken().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(createTokenForm().selectUserNameDropdown()));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(createTokenForm().selectUserNameDropdown()));
createTokenForm().selectUserNameDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
createTokenForm().selectUserNameList()
.stream()
.filter(it -> it.getText().contains(userName))
@ -82,7 +83,8 @@ public final class TokenPage extends NavBarPage implements Tab {
userName)))
.click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(createTokenForm().buttonGenerateToken()));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(createTokenForm().buttonGenerateToken()));
createTokenForm().buttonGenerateToken().click();
createTokenForm().buttonSubmit().click();
@ -92,16 +94,18 @@ public final class TokenPage extends NavBarPage implements Tab {
public TokenPage update(String userName) {
tokenList().stream()
.filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName))
.flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in token list"))
.click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken()));
.filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName))
.flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in token list"))
.click();
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken()));
editTokenForm().buttonGenerateToken().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken()));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken()));
editTokenForm().buttonSubmit().click();
@ -110,23 +114,23 @@ public final class TokenPage extends NavBarPage implements Tab {
public String getToken(String userName) {
return tokenList().stream()
.filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName))
.flatMap(it -> it.findElements(By.className("token")).stream())
.filter(it -> !Strings.isNullOrEmpty(it.getAttribute("innerHTML")))
.map(it -> it.getAttribute("innerHTML"))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No token for such user: " + userName));
.filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName))
.flatMap(it -> it.findElements(By.className("token")).stream())
.filter(it -> !Strings.isNullOrEmpty(it.getAttribute("innerHTML")))
.map(it -> it.getAttribute("innerHTML"))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No token for such user: " + userName));
}
public TokenPage delete(String userName) {
tokenList()
.stream()
.filter(it -> it.getText().contains(userName))
.flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in token list"))
.click();
.stream()
.filter(it -> it.getText().contains(userName))
.flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in token list"))
.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
@ -135,13 +139,14 @@ public final class TokenPage extends NavBarPage implements Tab {
@Getter
public class TokenForm {
TokenForm() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-username"),
@FindBy(className = "n-base-selection"),
@FindBy(className = "input-username"),
@FindBy(className = "n-base-selection"),
})
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.pages.common.NavBarPage;
import java.time.Duration;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
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.FindBys;
import org.openqa.selenium.support.PageFactory;
import lombok.Getter;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@Getter
public final class UserPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-user")
private WebElement buttonCreateUser;
@ -48,15 +47,14 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
private List<WebElement> userList;
@FindBys({
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
})
private WebElement buttonConfirm;
private final UserForm createUserForm = new UserForm();
private final UserForm editUserForm = new UserForm();
public UserPage(RemoteWebDriver driver) {
super(driver);
}
@ -69,15 +67,16 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
createUserForm().btnSelectTenantDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
createUserForm().selectTenant()
.stream()
.filter(it -> it.getText().contains(tenant))
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format("No %s in tenant dropdown list", tenant)))
.click();
.stream()
.filter(it -> it.getText().contains(tenant))
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format("No %s in tenant dropdown list", tenant)))
.click();
createUserForm().inputEmail().sendKeys(email);
createUserForm().inputPhone().sendKeys(phone);
@ -101,21 +100,22 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
String editPhone,
String tenant) {
userList().stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user))
.flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in user list"))
.click();
editUserForm().inputUserName().sendKeys(Keys.CONTROL+"a");
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user))
.flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in user list"))
.click();
editUserForm().inputUserName().sendKeys(Keys.CONTROL + "a");
editUserForm().inputUserName().sendKeys(Keys.BACK_SPACE);
editUserForm().inputUserName().sendKeys(editUser);
createUserForm().btnSelectTenantDropdown().click();
WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
createUserForm().selectTenant()
.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)))
.click();
editUserForm().inputEmail().sendKeys(Keys.CONTROL+"a");
editUserForm().inputEmail().sendKeys(Keys.CONTROL + "a");
editUserForm().inputEmail().sendKeys(Keys.BACK_SPACE);
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(editPhone);
@ -139,13 +139,13 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
public UserPage delete(String user) {
userList()
.stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user))
.flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in user list"))
.click();
.stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user))
.flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in user list"))
.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
@ -154,25 +154,26 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
@Getter
public class UserForm {
UserForm() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-username"),
@FindBy(tagName = "input"),
@FindBy(className = "input-username"),
@FindBy(tagName = "input"),
})
private WebElement inputUserName;
@FindBys({
@FindBy(className = "input-password"),
@FindBy(tagName = "input"),
@FindBy(className = "input-password"),
@FindBy(tagName = "input"),
})
private WebElement inputUserPassword;
@FindBys({
@FindBy(className = "select-tenant"),
@FindBy(className = "n-base-selection"),
@FindBy(className = "select-tenant"),
@FindBy(className = "n-base-selection"),
})
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;
import lombok.Getter;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.util.List;
import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
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.PageFactory;
import java.util.List;
@Getter
public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(className = "btn-create-worker-group")
private WebElement buttonCreateWorkerGroup;
@ -42,16 +44,14 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
private List<WebElement> workerGroupList;
@FindBys({
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
@FindBy(className = "n-popconfirm__action"),
@FindBy(className = "n-button--primary-type"),
})
private WebElement buttonConfirm;
private final WorkerGroupForm createWorkerForm = new WorkerGroupForm();
private final WorkerGroupForm editWorkerForm = new WorkerGroupForm();
public WorkerGroupPage(RemoteWebDriver driver) {
super(driver);
}
@ -87,16 +87,15 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
return this;
}
public WorkerGroupPage delete(String Worker) {
workerGroupList()
.stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(Worker))
.flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in workerGroup list"))
.click();
.stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(Worker))
.flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in workerGroup list"))
.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
@ -105,19 +104,20 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
@Getter
public class WorkerGroupForm {
WorkerGroupForm() {
PageFactory.initElements(driver, this);
}
@FindBys({
@FindBy(className = "input-worker-group-name"),
@FindBy(tagName = "input"),
@FindBy(className = "input-worker-group-name"),
@FindBy(tagName = "input"),
})
private WebElement inputWorkerGroupName;
@FindBys({
@FindBy(className = "select-worker-address"),
@FindBy(className = "n-base-selection"),
@FindBy(className = "select-worker-address"),
@FindBy(className = "n-base-selection"),
})
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;
import lombok.experimental.UtilityClass;
import java.nio.file.Path;
import java.nio.file.Paths;
import lombok.experimental.UtilityClass;
@UtilityClass
public final class Constants {
/**
* 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)
@ExtendWith(DolphinSchedulerExtension.class)
public @interface DolphinScheduler {
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.Stream;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
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.net.HostAndPort;
import lombok.extern.slf4j.Slf4j;
@Slf4j
final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback {
private final boolean LOCAL_MODE = Objects.equals(System.getProperty("local"), "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.manage().timeouts()
.implicitlyWait(Duration.ofSeconds(10))
.pageLoadTimeout(Duration.ofSeconds(10));
.implicitlyWait(Duration.ofSeconds(10))
.pageLoadTimeout(Duration.ofSeconds(10));
driver.manage().window()
.maximize();
.maximize();
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();
Stream.of(clazz.getDeclaredFields())
.filter(it -> Modifier.isStatic(it.getModifiers()))
.filter(f -> WebDriver.class.isAssignableFrom(f.getType()))
.forEach(it -> setDriver(clazz, it));
.filter(it -> Modifier.isStatic(it.getModifiers()))
.filter(f -> WebDriver.class.isAssignableFrom(f.getType()))
.forEach(it -> setDriver(clazz, it));
WebDriverHolder.setWebDriver(driver);
}
@ -128,7 +129,8 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
compose = createDockerCompose(context);
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/";
}
@ -183,8 +185,8 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
public void beforeEach(ExtensionContext context) {
final Object instance = context.getRequiredTestInstance();
Stream.of(instance.getClass().getDeclaredFields())
.filter(f -> WebDriver.class.isAssignableFrom(f.getType()))
.forEach(it -> setDriver(instance, it));
.filter(f -> WebDriver.class.isAssignableFrom(f.getType()))
.forEach(it -> setDriver(instance, it));
}
private void setDriver(Object object, Field field) {
@ -200,13 +202,13 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
final Class<?> clazz = context.getRequiredTestClass();
final DolphinScheduler annotation = clazz.getAnnotation(DolphinScheduler.class);
final List<File> files = Stream.of(annotation.composeFiles())
.map(it -> DolphinScheduler.class.getClassLoader().getResource(it))
.filter(Objects::nonNull)
.map(URL::getPath)
.map(File::new)
.collect(Collectors.toList());
.map(it -> DolphinScheduler.class.getClassLoader().getResource(it))
.filter(Objects::nonNull)
.map(URL::getPath)
.map(File::new)
.collect(Collectors.toList());
ComposeContainer compose = new ComposeContainer(files)
ComposeContainer compose = new ComposeContainer(files)
.withPull(true)
.withTailChildContainers(true)
.withLocalCompose(true)
@ -216,7 +218,6 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
.withLogConsumer(serviceName, outputFrame -> LOGGER.info(outputFrame.getUtf8String()))
.waitingFor(serviceName, Wait.forHealthcheck().withStartupTimeout(Duration.ofSeconds(300)));
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.net.URLEncoder;
import org.junit.jupiter.api.extension.ExtensionContext;
import lombok.RequiredArgsConstructor;
import org.junit.jupiter.api.extension.ExtensionContext;
@RequiredArgsConstructor
final class TestDescription implements org.testcontainers.lifecycle.TestDescription {
private static final String UNKNOWN_NAME = "unknown";
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;
import java.time.Duration;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.WebDriverWait;

4
dolphinscheduler-e2e/pom.xml

@ -31,8 +31,8 @@
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<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>
<replacement>$1</replacement>
</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>
<pom>
<sortPom>

Loading…
Cancel
Save