Browse Source

[E2E] Restore security center e2e test cases in ui-next (#8815)

3.0.0/version-upgrade
xiangzihao 3 years ago committed by GitHub
parent
commit
20dd0c12ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 45
      .github/workflows/e2e.yml
  2. 8
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/EnvironmentE2ETest.java
  3. 28
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java
  4. 44
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FunctionManageE2ETest.java
  5. 4
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/QueueE2ETest.java
  6. 8
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TokenE2ETest.java
  7. 28
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UdfManageE2ETest.java
  8. 53
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java
  9. 2
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java
  10. 24
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java
  11. 36
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java
  12. 93
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java
  13. 27
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/QueuePage.java
  14. 43
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java
  15. 39
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java
  16. 65
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java
  17. 109
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java
  18. 40
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/WorkerGroupPage.java
  19. 6
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/basic/docker-compose.yaml
  20. 1
      dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java
  21. 1
      dolphinscheduler-ui-next/src/layouts/content/components/sidebar/index.tsx
  22. 1
      dolphinscheduler-ui-next/src/layouts/content/index.tsx
  23. 3
      pom.xml

45
.github/workflows/e2e.yml

@ -64,7 +64,6 @@ jobs:
retention-days: 1 retention-days: 1
e2e: e2e:
name: ${{ matrix.case.name }} name: ${{ matrix.case.name }}
if: false
needs: build needs: build
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
@ -76,34 +75,34 @@ jobs:
class: org.apache.dolphinscheduler.e2e.cases.UserE2ETest class: org.apache.dolphinscheduler.e2e.cases.UserE2ETest
- name: WorkerGroup - name: WorkerGroup
class: org.apache.dolphinscheduler.e2e.cases.WorkerGroupE2ETest class: org.apache.dolphinscheduler.e2e.cases.WorkerGroupE2ETest
- name: Project # - name: Project
class: org.apache.dolphinscheduler.e2e.cases.ProjectE2ETest # class: org.apache.dolphinscheduler.e2e.cases.ProjectE2ETest
- name: Queue - name: Queue
class: org.apache.dolphinscheduler.e2e.cases.QueueE2ETest class: org.apache.dolphinscheduler.e2e.cases.QueueE2ETest
- name: Environment - name: Environment
class: org.apache.dolphinscheduler.e2e.cases.EnvironmentE2ETest class: org.apache.dolphinscheduler.e2e.cases.EnvironmentE2ETest
- name: Token - name: Token
class: org.apache.dolphinscheduler.e2e.cases.TokenE2ETest class: org.apache.dolphinscheduler.e2e.cases.TokenE2ETest
- name: Workflow # - name: Workflow
class: org.apache.dolphinscheduler.e2e.cases.WorkflowE2ETest # class: org.apache.dolphinscheduler.e2e.cases.WorkflowE2ETest
- name: WorkflowForSwitch # - name: WorkflowForSwitch
class: org.apache.dolphinscheduler.e2e.cases.WorkflowSwitchE2ETest # class: org.apache.dolphinscheduler.e2e.cases.WorkflowSwitchE2ETest
- name: FileManage # - name: FileManage
class: org.apache.dolphinscheduler.e2e.cases.FileManageE2ETest # class: org.apache.dolphinscheduler.e2e.cases.FileManageE2ETest
- name: UdfManage # - name: UdfManage
class: org.apache.dolphinscheduler.e2e.cases.UdfManageE2ETest # class: org.apache.dolphinscheduler.e2e.cases.UdfManageE2ETest
- name: FunctionManage # - name: FunctionManage
class: org.apache.dolphinscheduler.e2e.cases.FunctionManageE2ETest # class: org.apache.dolphinscheduler.e2e.cases.FunctionManageE2ETest
- name: MysqlDataSource # - name: MysqlDataSource
class: org.apache.dolphinscheduler.e2e.cases.MysqlDataSourceE2ETest # class: org.apache.dolphinscheduler.e2e.cases.MysqlDataSourceE2ETest
- name: ClickhouseDataSource # - name: ClickhouseDataSource
class: org.apache.dolphinscheduler.e2e.cases.ClickhouseDataSourceE2ETest # class: org.apache.dolphinscheduler.e2e.cases.ClickhouseDataSourceE2ETest
- name: PostgresDataSource # - name: PostgresDataSource
class: org.apache.dolphinscheduler.e2e.cases.PostgresDataSourceE2ETest # class: org.apache.dolphinscheduler.e2e.cases.PostgresDataSourceE2ETest
- name: SqlServerDataSource # - name: SqlServerDataSource
class: org.apache.dolphinscheduler.e2e.cases.SqlServerDataSourceE2ETest # class: org.apache.dolphinscheduler.e2e.cases.SqlServerDataSourceE2ETest
- name: HiveDataSource # - name: HiveDataSource
class: org.apache.dolphinscheduler.e2e.cases.HiveDataSourceE2ETest # class: org.apache.dolphinscheduler.e2e.cases.HiveDataSourceE2ETest
env: env:
RECORDING_PATH: /tmp/recording-${{ matrix.case.name }} RECORDING_PATH: /tmp/recording-${{ matrix.case.name }}
steps: steps:

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

@ -44,12 +44,12 @@ class EnvironmentE2ETest {
private static final String environmentName = "test_environment_name"; private static final String environmentName = "test_environment_name";
private static final String environmentConfig = "test_environment_config"; private static final String environmentConfig = "test_environment_config";
private static final String environmentDesc = "test_environment_desc"; private static final String environmentDesc = "test_environment_desc";
private static final String environmentWorkerGroup = "[\"default\"]"; private static final String environmentWorkerGroup = "default";
private static final String editEnvironmentName = "edit_environment_name"; private static final String editEnvironmentName = "edit_environment_name";
private static final String editEnvironmentConfig = "edit_environment_config"; private static final String editEnvironmentConfig = "edit_environment_config";
private static final String editEnvironmentDesc = "edit_environment_desc"; private static final String editEnvironmentDesc = "edit_environment_desc";
private static final String editEnvironmentWorkerGroup = "[\"default\"]"; private static final String editEnvironmentWorkerGroup = "default";
private static RemoteWebDriver browser; private static RemoteWebDriver browser;
@ -118,7 +118,9 @@ class EnvironmentE2ETest {
assertThat( assertThat(
page.environmentList() page.environmentList()
).noneMatch( )
.as("Environment list should not contain deleted environment")
.noneMatch(
it -> it.getText().contains(environmentName) || it.getText().contains(editEnvironmentName) it -> it.getText().contains(environmentName) || it.getText().contains(editEnvironmentName)
); );
}); });

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

@ -84,20 +84,20 @@ public class FileManageE2ETest {
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
TenantPage tenantPage = new LoginPage(browser) // TenantPage tenantPage = new LoginPage(browser)
.login(user, password) // .login(user, password)
.create(tenant); // .create(tenant);
//
await().untilAsserted(() -> assertThat(tenantPage.tenantList()) // await().untilAsserted(() -> assertThat(tenantPage.tenantList())
.as("Tenant list should contain newly-created tenant") // .as("Tenant list should contain newly-created tenant")
.extracting(WebElement::getText) // .extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant))); // .anyMatch(it -> it.contains(tenant)));
//
tenantPage.goToNav(SecurityPage.class) // tenantPage.goToNav(SecurityPage.class)
.goToTab(UserPage.class) // .goToTab(UserPage.class)
.update(user, user, password, email, phone) // .update(user, user, password, email, phone)
.goToNav(ResourcePage.class) // .goToNav(ResourcePage.class)
.goToTab(FileManagePage.class); // .goToTab(FileManagePage.class);
} }
@AfterAll @AfterAll

44
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FunctionManageE2ETest.java

@ -83,28 +83,28 @@ public class FunctionManageE2ETest {
@BeforeAll @BeforeAll
@SneakyThrows @SneakyThrows
public static void setup() { public static void setup() {
TenantPage tenantPage = new LoginPage(browser) // TenantPage tenantPage = new LoginPage(browser)
.login(user, password) // .login(user, password)
.create(tenant); // .create(tenant);
//
await().untilAsserted(() -> assertThat(tenantPage.tenantList()) // await().untilAsserted(() -> assertThat(tenantPage.tenantList())
.as("Tenant list should contain newly-created tenant") // .as("Tenant list should contain newly-created tenant")
.extracting(WebElement::getText) // .extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant))); // .anyMatch(it -> it.contains(tenant)));
//
downloadFile("https://repo1.maven.org/maven2/org/apache/hive/hive-jdbc/3.1.2/hive-jdbc-3.1.2.jar", testUploadUdfFilePath.toFile().getAbsolutePath()); // downloadFile("https://repo1.maven.org/maven2/org/apache/hive/hive-jdbc/3.1.2/hive-jdbc-3.1.2.jar", testUploadUdfFilePath.toFile().getAbsolutePath());
//
UdfManagePage udfManagePage = tenantPage.goToNav(SecurityPage.class) // UdfManagePage udfManagePage = tenantPage.goToNav(SecurityPage.class)
.goToTab(UserPage.class) // .goToTab(UserPage.class)
.update(user, user, password, email, phone) // .update(user, user, password, email, phone)
.goToNav(ResourcePage.class) // .goToNav(ResourcePage.class)
.goToTab(UdfManagePage.class) // .goToTab(UdfManagePage.class)
.uploadFile(testUploadUdfFilePath.toFile().getAbsolutePath()); // .uploadFile(testUploadUdfFilePath.toFile().getAbsolutePath());
//
new WebDriverWait(browser, 10).until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog"))); // new WebDriverWait(browser, 10).until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog")));
//
udfManagePage.goToNav(ResourcePage.class) // udfManagePage.goToNav(ResourcePage.class)
.goToTab(FunctionManagePage.class); // .goToTab(FunctionManagePage.class);
} }
@AfterAll @AfterAll

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

@ -86,7 +86,8 @@ class QueueE2ETest {
@Test @Test
@Order(30) @Order(30)
void testEditQueue() { void testEditQueue() {
final QueuePage page = new QueuePage(browser); QueuePage page = new QueuePage(browser);
page.update(queueName, editQueueName, editQueueValue); page.update(queueName, editQueueName, editQueueValue);
await().untilAsserted(() -> { await().untilAsserted(() -> {
@ -97,4 +98,5 @@ class QueueE2ETest {
.anyMatch(it -> it.contains(editQueueName)); .anyMatch(it -> it.contains(editQueueName));
}); });
} }
} }

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

@ -52,8 +52,8 @@ public class TokenE2ETest {
@Test @Test
@Order(10) @Order(10)
void testCreateToken() { void testCreateToken() {
final TokenPage page = new TokenPage(browser); TokenPage page = new TokenPage(browser);
page.create(); page.create(userName);
await().untilAsserted(() -> { await().untilAsserted(() -> {
browser.navigate().refresh(); browser.navigate().refresh();
@ -68,7 +68,7 @@ public class TokenE2ETest {
@Test @Test
@Order(30) @Order(30)
void testEditToken() { void testEditToken() {
final TokenPage page = new TokenPage(browser); TokenPage page = new TokenPage(browser);
String oldToken = page.getToken(userName); String oldToken = page.getToken(userName);
page.update(userName); page.update(userName);
@ -85,7 +85,7 @@ public class TokenE2ETest {
@Test @Test
@Order(40) @Order(40)
void testDeleteToken() { void testDeleteToken() {
final TokenPage page = new TokenPage(browser); TokenPage page = new TokenPage(browser);
page.delete(userName); page.delete(userName);
await().untilAsserted(() -> { await().untilAsserted(() -> {

28
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UdfManageE2ETest.java

@ -80,20 +80,20 @@ public class UdfManageE2ETest {
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
TenantPage tenantPage = new LoginPage(browser) // TenantPage tenantPage = new LoginPage(browser)
.login(user, password) // .login(user, password)
.create(tenant); // .create(tenant);
//
await().untilAsserted(() -> assertThat(tenantPage.tenantList()) // await().untilAsserted(() -> assertThat(tenantPage.tenantList())
.as("Tenant list should contain newly-created tenant") // .as("Tenant list should contain newly-created tenant")
.extracting(WebElement::getText) // .extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant))); // .anyMatch(it -> it.contains(tenant)));
//
tenantPage.goToNav(SecurityPage.class) // tenantPage.goToNav(SecurityPage.class)
.goToTab(UserPage.class) // .goToTab(UserPage.class)
.update(user, user, password, email, phone) // .update(user, user, password, email, phone)
.goToNav(ResourcePage.class) // .goToNav(ResourcePage.class)
.goToTab(UdfManagePage.class); // .goToTab(UdfManagePage.class);
} }
@AfterAll @AfterAll

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

@ -42,14 +42,14 @@ import org.openqa.selenium.remote.RemoteWebDriver;
class UserE2ETest { class UserE2ETest {
private static final String tenant = System.getProperty("user.name"); private static final String tenant = System.getProperty("user.name");
private static final String user = "test_user"; private static final String user = "test_user";
private static final String password = "test_user123"; private static final String password = "testUser123";
private static final String email = "test_user@gmail.com"; private static final String email = "testUser@gmail.com";
private static final String phone = "15800000000"; private static final String phone = "15812389765";
private static final String editUser = "edit_test_user"; private static final String editUser = "edit_test_user";
private static final String editPassword = "edit_test_user123"; private static final String editPassword = "editTestUser123";
private static final String editEmail = "edit_test_user@gmail.com"; private static final String editEmail = "editTestUser@gmail.com";
private static final String editPhone = "15800000001"; private static final String editPhone = "15812389780";
private static RemoteWebDriver browser; private static RemoteWebDriver browser;
@ -83,7 +83,7 @@ class UserE2ETest {
void testCreateUser() { void testCreateUser() {
final UserPage page = new UserPage(browser); final UserPage page = new UserPage(browser);
page.create(user, password, email, phone); page.create(user, password, email, phone, tenant);
await().untilAsserted(() -> { await().untilAsserted(() -> {
browser.navigate().refresh(); browser.navigate().refresh();
@ -100,7 +100,7 @@ class UserE2ETest {
void testCreateDuplicateUser() { void testCreateDuplicateUser() {
final UserPage page = new UserPage(browser); final UserPage page = new UserPage(browser);
page.create(user, password, email, phone); page.create(user, password, email, phone, tenant);
await().untilAsserted(() -> await().untilAsserted(() ->
assertThat(browser.findElement(By.tagName("body")).getText()) assertThat(browser.findElement(By.tagName("body")).getText())
@ -113,7 +113,8 @@ class UserE2ETest {
@Test @Test
@Order(30) @Order(30)
void testEditUser() { void testEditUser() {
final UserPage page = new UserPage(browser); UserPage page = new UserPage(browser);
page.update(user, editUser, editPassword, editEmail, editPhone); page.update(user, editUser, editPassword, editEmail, editPhone);
await().untilAsserted(() -> { await().untilAsserted(() -> {
@ -126,21 +127,21 @@ class UserE2ETest {
} }
@Test // @Test
@Order(40) // @Order(40)
void testDeleteUser() { // void testDeleteUser() {
final UserPage page = new UserPage(browser); // final UserPage page = new UserPage(browser);
//
page.delete(editUser); // page.delete(editUser);
//
await().untilAsserted(() -> { // await().untilAsserted(() -> {
browser.navigate().refresh(); // browser.navigate().refresh();
//
assertThat( // assertThat(
page.userList() // page.userList()
).noneMatch( // ).noneMatch(
it -> it.getText().contains(user) || it.getText().contains(editUser) // it -> it.getText().contains(user) || it.getText().contains(editUser)
); // );
}); // });
} // }
} }

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

@ -58,7 +58,7 @@ class WorkerGroupE2ETest {
final WorkerGroupPage page = new WorkerGroupPage(browser); final WorkerGroupPage page = new WorkerGroupPage(browser);
new WebDriverWait(page.driver(), 10) new WebDriverWait(page.driver(), 10)
.until(ExpectedConditions.urlContains("/#/security/worker-groups")); .until(ExpectedConditions.urlContains("/security/worker-group-manage"));
page.create(workerGroupName); page.create(workerGroupName);

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

@ -25,6 +25,7 @@ import org.apache.dolphinscheduler.e2e.pages.security.TenantPage;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.WebDriverWait;
@ -33,28 +34,39 @@ import lombok.SneakyThrows;
@Getter @Getter
public final class LoginPage extends NavBarPage { public final class LoginPage extends NavBarPage {
@FindBy(id = "inputUsername") @FindBys({
@FindBy(className = "input-user-name"),
@FindBy(tagName = "input"),
})
private WebElement inputUsername; private WebElement inputUsername;
@FindBy(id = "inputPassword") @FindBys( {
@FindBy(className = "input-password"),
@FindBy(tagName = "input"),
})
private WebElement inputPassword; private WebElement inputPassword;
@FindBy(id = "btnLogin") @FindBy(className = "btn-login")
private WebElement buttonLogin; private WebElement buttonLogin;
@FindBy(className = "n-switch__button")
private WebElement buttonSwitchLanguage;
public LoginPage(RemoteWebDriver driver) { public LoginPage(RemoteWebDriver driver) {
super(driver); super(driver);
} }
@SneakyThrows @SneakyThrows
public TenantPage login(String username, String password) { public NavBarPage login(String username, String password) {
buttonSwitchLanguage().click();
inputUsername().sendKeys(username); inputUsername().sendKeys(username);
inputPassword().sendKeys(password); inputPassword().sendKeys(password);
buttonLogin().click(); buttonLogin().click();
new WebDriverWait(driver, 10) new WebDriverWait(driver, 10)
.until(ExpectedConditions.urlContains("/#/security")); .until(ExpectedConditions.urlContains("/home"));
return new TenantPage(driver); return new NavBarPage(driver);
} }
} }

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

@ -28,6 +28,7 @@ import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.WebDriverWait;
@ -38,18 +39,21 @@ import lombok.Getter;
public class NavBarPage { public class NavBarPage {
protected final RemoteWebDriver driver; protected final RemoteWebDriver driver;
@FindBy(id = "tabProject") @FindBy(css = ".tab-horizontal .n-menu-item:nth-child(2) > .n-menu-item-content")
private WebElement projectTab; private WebElement projectTab;
@FindBy(id = "tabSecurity") @FindBy(css = ".tab-horizontal .n-menu-item:nth-child(3) > .n-menu-item-content")
private WebElement securityTab;
@FindBy(id = "tabResource")
private WebElement resourceTab; private WebElement resourceTab;
@FindBy(id = "tabDataSource") @FindBy(css = ".tab-horizontal .n-menu-item:nth-child(4) > .n-menu-item-content")
private WebElement dataQualityTab;
@FindBy(css = ".tab-horizontal .n-menu-item:nth-child(5) > .n-menu-item-content")
private WebElement dataSourceTab; private WebElement dataSourceTab;
@FindBy(css = ".tab-horizontal .n-menu-item:nth-child(7) > .n-menu-item-content")
private WebElement securityTab;
public NavBarPage(RemoteWebDriver driver) { public NavBarPage(RemoteWebDriver driver) {
this.driver = driver; this.driver = driver;
@ -58,30 +62,26 @@ public class NavBarPage {
public <T extends NavBarItem> T goToNav(Class<T> nav) { public <T extends NavBarItem> T goToNav(Class<T> nav) {
if (nav == ProjectPage.class) { if (nav == ProjectPage.class) {
WebElement projectTabElement = new WebDriverWait(driver, 60) new WebDriverWait(driver, 60).until(ExpectedConditions.elementToBeClickable(projectTab));
.until(ExpectedConditions.elementToBeClickable(projectTab)); projectTab.click();
((JavascriptExecutor)driver).executeScript("arguments[0].click();", projectTabElement);
return nav.cast(new ProjectPage(driver)); return nav.cast(new ProjectPage(driver));
} }
if (nav == SecurityPage.class) { if (nav == SecurityPage.class) {
WebElement securityTabElement = new WebDriverWait(driver, 60) new WebDriverWait(driver, 60).until(ExpectedConditions.elementToBeClickable(securityTab));
.until(ExpectedConditions.elementToBeClickable(securityTab)); securityTab.click();
((JavascriptExecutor)driver).executeScript("arguments[0].click();", securityTabElement);
return nav.cast(new SecurityPage(driver)); return nav.cast(new SecurityPage(driver));
} }
if (nav == ResourcePage.class) { if (nav == ResourcePage.class) {
WebElement resourceTabElement = new WebDriverWait(driver, 60) new WebDriverWait(driver, 60).until(ExpectedConditions.elementToBeClickable(resourceTab));
.until(ExpectedConditions.elementToBeClickable(resourceTab)); resourceTab.click();
((JavascriptExecutor)driver).executeScript("arguments[0].click();", resourceTabElement);
return nav.cast(new ResourcePage(driver)); return nav.cast(new ResourcePage(driver));
} }
if (nav == DataSourcePage.class) { if (nav == DataSourcePage.class) {
WebElement dataSourceTabElement = new WebDriverWait(driver, 60) new WebDriverWait(driver, 60).until(ExpectedConditions.elementToBeClickable(dataSourceTab));
.until(ExpectedConditions.elementToBeClickable(dataSourceTab)); dataSourceTab.click();
((JavascriptExecutor)driver).executeScript("arguments[0].click();", dataSourceTabElement);
return nav.cast(new DataSourcePage(driver)); return nav.cast(new DataSourcePage(driver));
} }

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

@ -24,6 +24,8 @@ import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.util.List; import java.util.List;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
@ -31,20 +33,22 @@ import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter; import lombok.Getter;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@Getter @Getter
public final class EnvironmentPage extends NavBarPage implements SecurityPage.Tab { public final class EnvironmentPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(id = "btnCreateEnvironment") @FindBy(className = "btn-create-environment")
private WebElement buttonCreateEnvironment; private WebElement buttonCreateEnvironment;
@FindBy(className = "items") @FindBy(className = "items")
private List<WebElement> environmentList; private List<WebElement> environmentList;
@FindBys({ @FindBys({
@FindBy(className = "el-popconfirm"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "el-button--primary"), @FindBy(className = "n-button--primary-type"),
}) })
private List<WebElement> buttonConfirm; private WebElement buttonConfirm;
private final EnvironmentForm createEnvironmentForm; private final EnvironmentForm createEnvironmentForm;
private final EnvironmentForm editEnvironmentForm; private final EnvironmentForm editEnvironmentForm;
@ -60,7 +64,18 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
createEnvironmentForm().inputEnvironmentName().sendKeys(name); createEnvironmentForm().inputEnvironmentName().sendKeys(name);
createEnvironmentForm().inputEnvironmentConfig().sendKeys(config); createEnvironmentForm().inputEnvironmentConfig().sendKeys(config);
createEnvironmentForm().inputEnvironmentDesc().sendKeys(desc); createEnvironmentForm().inputEnvironmentDesc().sendKeys(desc);
createEnvironmentForm().inputWorkerGroup().sendKeys(workerGroup);
editEnvironmentForm().btnSelectWorkerGroupDropdown().click();
new WebDriverWait(driver, 5).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
editEnvironmentForm().selectWorkerGroupList()
.stream()
.filter(it -> it.getText().contains(workerGroup))
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format("No %s in worker group dropdown list",
workerGroup)))
.click();
createEnvironmentForm().buttonSubmit().click(); createEnvironmentForm().buttonSubmit().click();
return this; return this;
} }
@ -68,17 +83,39 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
public EnvironmentPage update(String oldName, String name, String config, String desc, String workerGroup) { public EnvironmentPage update(String oldName, String name, String config, String desc, String workerGroup) {
environmentList() environmentList()
.stream() .stream()
.filter(it -> it.findElement(By.className("environmentName")).getAttribute("innerHTML").contains(oldName)) .filter(it -> it.findElement(By.className("environment-name")).getAttribute("innerHTML").contains(oldName))
.flatMap(it -> it.findElements(By.className("edit")).stream()) .flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in environment list")) .orElseThrow(() -> new RuntimeException("No edit button in environment list"))
.click(); .click();
editEnvironmentForm().inputEnvironmentName().sendKeys(Keys.CONTROL + "a");
editEnvironmentForm().inputEnvironmentName().sendKeys(Keys.BACK_SPACE);
editEnvironmentForm().inputEnvironmentName().sendKeys(name); editEnvironmentForm().inputEnvironmentName().sendKeys(name);
editEnvironmentForm().inputEnvironmentConfig().sendKeys(Keys.CONTROL + "a");
editEnvironmentForm().inputEnvironmentConfig().sendKeys(Keys.BACK_SPACE);
editEnvironmentForm().inputEnvironmentConfig().sendKeys(config); editEnvironmentForm().inputEnvironmentConfig().sendKeys(config);
editEnvironmentForm().inputEnvironmentDesc().sendKeys(Keys.CONTROL + "a");
editEnvironmentForm().inputEnvironmentDesc().sendKeys(Keys.BACK_SPACE);
editEnvironmentForm().inputEnvironmentDesc().sendKeys(desc); editEnvironmentForm().inputEnvironmentDesc().sendKeys(desc);
editEnvironmentForm().inputWorkerGroup().sendKeys(workerGroup);
if (editEnvironmentForm().selectedWorkerGroup().getAttribute("innerHTML").equals(workerGroup)) {
editEnvironmentForm().btnSelectWorkerGroupDropdown().click();
new WebDriverWait(driver, 5).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
editEnvironmentForm().selectWorkerGroupList()
.stream()
.filter(it -> it.getText().contains(workerGroup))
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format("No %s in worker group dropdown list",
workerGroup)))
.click();
}
editEnvironmentForm().buttonSubmit().click(); editEnvironmentForm().buttonSubmit().click();
return this; return this;
@ -94,12 +131,7 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
.orElseThrow(() -> new RuntimeException("No delete button in environment list")) .orElseThrow(() -> new RuntimeException("No delete button in environment list"))
.click(); .click();
buttonConfirm() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.stream()
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No confirm button when deleting"))
.click();
return this; return this;
} }
@ -110,22 +142,43 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputEnvironmentName") @FindBys({
@FindBy(className = "input-environment-name"),
@FindBy(tagName = "input"),
})
private WebElement inputEnvironmentName; private WebElement inputEnvironmentName;
@FindBy(id = "inputEnvironmentConfig") @FindBys({
@FindBy(className = "input-environment-config"),
@FindBy(tagName = "textarea"),
})
private WebElement inputEnvironmentConfig; private WebElement inputEnvironmentConfig;
@FindBy(id = "inputEnvironmentDesc") @FindBys({
@FindBy(className = "input-environment-desc"),
@FindBy(tagName = "input"),
})
private WebElement inputEnvironmentDesc; private WebElement inputEnvironmentDesc;
@FindBy(id = "inputEnvironmentWorkerGroup") @FindBys({
private WebElement inputWorkerGroup; @FindBy(className = "input-environment-worker-group"),
@FindBy(className = "n-base-selection"),
})
private WebElement btnSelectWorkerGroupDropdown;
@FindBy(className = "n-base-select-option__content")
private List<WebElement> selectWorkerGroupList;
@FindBys({
@FindBy(className = "n-base-selection-tags"),
@FindBy(className = "n-tag__content"),
})
private WebElement selectedWorkerGroup;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
} }

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

@ -21,19 +21,22 @@ package org.apache.dolphinscheduler.e2e.pages.security;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.security.Key;
import java.util.List; import java.util.List;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter; import lombok.Getter;
@Getter @Getter
public final class QueuePage extends NavBarPage implements SecurityPage.Tab { public final class QueuePage extends NavBarPage implements SecurityPage.Tab {
@FindBy(id = "btnCreateQueue") @FindBy(className = "btn-create-queue")
private WebElement buttonCreateQueue; private WebElement buttonCreateQueue;
@FindBy(className = "items") @FindBy(className = "items")
@ -59,15 +62,21 @@ public final class QueuePage extends NavBarPage implements SecurityPage.Tab {
public QueuePage update(String queueName, String editQueueName, String editQueueValue) { public QueuePage update(String queueName, String editQueueName, String editQueueValue) {
queueList() queueList()
.stream() .stream()
.filter(it -> it.findElement(By.className("queueName")).getAttribute("innerHTML").contains(queueName)) .filter(it -> it.findElement(By.className("queue-name")).getAttribute("innerHTML").contains(queueName))
.flatMap(it -> it.findElements(By.className("edit")).stream()) .flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in queue list")) .orElseThrow(() -> new RuntimeException("No edit button in queue list"))
.click(); .click();
editQueueForm().inputQueueName().sendKeys(Keys.CONTROL + "a");
editQueueForm().inputQueueName().sendKeys(Keys.BACK_SPACE);
editQueueForm().inputQueueName().sendKeys(editQueueName); editQueueForm().inputQueueName().sendKeys(editQueueName);
editQueueForm().inputQueueValue().sendKeys(Keys.CONTROL + "a");
editQueueForm().inputQueueValue().sendKeys(Keys.BACK_SPACE);
editQueueForm().inputQueueValue().sendKeys(editQueueValue); editQueueForm().inputQueueValue().sendKeys(editQueueValue);
editQueueForm().buttonSubmit().click(); editQueueForm().buttonSubmit().click();
return this; return this;
@ -79,16 +88,22 @@ public final class QueuePage extends NavBarPage implements SecurityPage.Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputQueueName") @FindBys({
@FindBy(className = "input-queue-name"),
@FindBy(tagName = "input"),
})
private WebElement inputQueueName; private WebElement inputQueueName;
@FindBy(id = "inputQueueValue") @FindBys({
@FindBy(className = "input-queue-value"),
@FindBy(tagName = "input"),
})
private WebElement inputQueueValue; private WebElement inputQueueValue;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
} }

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

@ -27,6 +27,7 @@ import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.WebDriverWait;
@ -34,67 +35,71 @@ import lombok.Getter;
@Getter @Getter
public class SecurityPage extends NavBarPage implements NavBarItem { public class SecurityPage extends NavBarPage implements NavBarItem {
@FindBy(className = "tab-tenant-manage")
@FindBy(css = ".tab-vertical > .n-menu-item:nth-child(1) > .n-menu-item-content")
private WebElement menuTenantManage; private WebElement menuTenantManage;
@FindBy(className = "tab-user-manage") @FindBy(css = ".tab-vertical > .n-menu-item:nth-child(2) > .n-menu-item-content")
private WebElement menUserManage; private WebElement menUserManage;
@FindBy(className = "tab-worker-group-manage") @FindBy(css = ".tab-vertical > .n-menu-item:nth-child(5) > .n-menu-item-content")
private WebElement menWorkerGroupManage; private WebElement menWorkerGroupManage;
@FindBy(className = "tab-queue-manage") @FindBy(css = ".tab-vertical > .n-menu-item:nth-child(6) > .n-menu-item-content")
private WebElement menuQueueManage; private WebElement menuQueueManage;
@FindBy(className = "tab-environment-manage") @FindBy(css = ".tab-vertical > .n-menu-item:nth-child(7) > .n-menu-item-content")
private WebElement menuEnvironmentManage; private WebElement menuEnvironmentManage;
@FindBy(className = "tab-token-manage") @FindBy(css = ".tab-vertical > .n-menu-item:nth-child(8) > .n-menu-item-content")
private WebElement menuTokenManage;
@FindBy(className = "tab-namespace-manage")
private WebElement menuNamespaceManage; private WebElement menuNamespaceManage;
@FindBy(css = ".tab-vertical > .n-menu-item:nth-child(9) > .n-menu-item-content")
private WebElement menuTokenManage;
public SecurityPage(RemoteWebDriver driver) { public SecurityPage(RemoteWebDriver driver) {
super(driver); super(driver);
} }
public <T extends SecurityPage.Tab> T goToTab(Class<T> tab) { public <T extends SecurityPage.Tab> T goToTab(Class<T> tab) {
if (tab == TenantPage.class) { if (tab == TenantPage.class) {
WebElement menuTenantManageElement = new WebDriverWait(driver, 60) new WebDriverWait(driver, 60).until(ExpectedConditions.elementToBeClickable(menuTenantManage));
.until(ExpectedConditions.elementToBeClickable(menuTenantManage)); menuTenantManage.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuTenantManageElement);
return tab.cast(new TenantPage(driver)); return tab.cast(new TenantPage(driver));
} }
if (tab == UserPage.class) { if (tab == UserPage.class) {
WebElement menUserManageElement = new WebDriverWait(driver, 60) new WebDriverWait(driver, 60).until(ExpectedConditions.elementToBeClickable(menUserManage));
.until(ExpectedConditions.elementToBeClickable(menUserManage)); menUserManage.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", menUserManageElement);
new WebDriverWait(driver, 25).until(ExpectedConditions.urlContains("/#/security/users"));
return tab.cast(new UserPage(driver)); return tab.cast(new UserPage(driver));
} }
if (tab == WorkerGroupPage.class) { if (tab == WorkerGroupPage.class) {
WebElement menWorkerGroupManageElement = new WebDriverWait(driver, 60) new WebDriverWait(driver, 60).until(ExpectedConditions.elementToBeClickable(menWorkerGroupManage));
.until(ExpectedConditions.elementToBeClickable(menWorkerGroupManage)); menWorkerGroupManage.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", menWorkerGroupManageElement);
return tab.cast(new WorkerGroupPage(driver)); return tab.cast(new WorkerGroupPage(driver));
} }
if (tab == QueuePage.class) { if (tab == QueuePage.class) {
menuQueueManage().click(); menuQueueManage().click();
return tab.cast(new QueuePage(driver)); return tab.cast(new QueuePage(driver));
} }
if (tab == EnvironmentPage.class) { if (tab == EnvironmentPage.class) {
menuEnvironmentManage().click(); menuEnvironmentManage().click();
return tab.cast(new EnvironmentPage(driver)); return tab.cast(new EnvironmentPage(driver));
} }
if (tab == TokenPage.class) { if (tab == TokenPage.class) {
menuTokenManage().click(); menuTokenManage().click();
return tab.cast(new TokenPage(driver)); return tab.cast(new TokenPage(driver));
} }
if (tab == NamespacePage.class) { if (tab == NamespacePage.class) {
menuNamespaceManage().click(); menuNamespaceManage().click();
return tab.cast(new NamespacePage(driver)); return tab.cast(new NamespacePage(driver));
} }
throw new UnsupportedOperationException("Unknown tab: " + tab.getName()); throw new UnsupportedOperationException("Unknown tab: " + tab.getName());
} }

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

@ -24,6 +24,8 @@ import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.util.List; import java.util.List;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
@ -34,19 +36,19 @@ import lombok.Getter;
@Getter @Getter
public final class TenantPage extends NavBarPage implements SecurityPage.Tab { public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(id = "btnCreateTenant") @FindBy(className = "btn-create-tenant")
private WebElement buttonCreateTenant; private WebElement buttonCreateTenant;
@FindBy(className = "items") @FindBy(className = "items")
private List<WebElement> tenantList; private List<WebElement> tenantList;
@FindBys({ @FindBys({
@FindBy(className = "el-popconfirm"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "el-button--primary"), @FindBy(className = "n-button--primary-type"),
}) })
private WebElement buttonConfirm; private WebElement buttonConfirm;
@FindBy(className = "tenantCode") @FindBy(className = "tenant-code")
private WebElement tenantCode; private WebElement tenantCode;
private final TenantForm tenantForm; private final TenantForm tenantForm;
@ -74,18 +76,17 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
public TenantPage update(String tenant, String description) { public TenantPage update(String tenant, String description) {
tenantList().stream() tenantList().stream()
.filter(it -> it.findElement(By.className("tenantCode")).getAttribute("innerHTML").contains(tenant)) .filter(it -> it.findElement(By.className("tenant-code")).getAttribute("innerHTML").contains(tenant))
.flatMap(it -> it.findElements(By.className("edit")).stream()) .flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in tenant list")) .orElseThrow(() -> new RuntimeException("No edit button in tenant list"))
.click(); .click();
TenantForm editTenantForm = new TenantForm(); editTenantForm().inputDescription().sendKeys(Keys.CONTROL + "a");
editTenantForm().inputDescription().sendKeys(Keys.BACK_SPACE);
editTenantForm.inputDescription().clear(); editTenantForm().inputDescription().sendKeys(description);
editTenantForm.inputDescription().sendKeys(description); editTenantForm().buttonSubmit().click();
editTenantForm.buttonSubmit().click();
return this; return this;
} }
@ -100,7 +101,7 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
.orElseThrow(() -> new RuntimeException("No delete button in user list")) .orElseThrow(() -> new RuntimeException("No delete button in user list"))
.click(); .click();
buttonConfirm().click(); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
return this; return this;
} }
@ -111,19 +112,25 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputTenantCode") @FindBys({
@FindBy(className = "input-tenant-code"),
@FindBy(tagName = "input"),
})
private WebElement inputTenantCode; private WebElement inputTenantCode;
@FindBy(id = "selectQueue") @FindBy(className = "select-queue")
private WebElement selectQueue; private WebElement selectQueue;
@FindBy(id = "inputDescription") @FindBys({
@FindBy(className = "input-description"),
@FindBy(tagName = "textarea"),
})
private WebElement inputDescription; private WebElement inputDescription;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
} }

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

@ -25,6 +25,7 @@ import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage.Tab;
import java.util.List; import java.util.List;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
@ -39,19 +40,19 @@ import com.google.common.base.Strings;
@Getter @Getter
public final class TokenPage extends NavBarPage implements Tab { public final class TokenPage extends NavBarPage implements Tab {
@FindBy(id = "btnCreateToken") @FindBy(className = "btn-create-token")
private WebElement buttonCreateToken; private WebElement buttonCreateToken;
@FindBy(className = "items") @FindBy(className = "items")
private List<WebElement> tokenList; private List<WebElement> tokenList;
@FindBys({ @FindBys({
@FindBy(className = "el-popconfirm"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "el-button--primary"), @FindBy(className = "n-button--primary-type"),
}) })
private List<WebElement> buttonConfirm; private WebElement buttonConfirm;
@FindBy(className = "userName") @FindBy(className = "username")
private List<WebElement> userName; private List<WebElement> userName;
@FindBy(className = "token") @FindBy(className = "token")
@ -64,34 +65,50 @@ public final class TokenPage extends NavBarPage implements Tab {
super(driver); super(driver);
} }
public TokenPage create() { public TokenPage create(String userName) {
buttonCreateToken().click(); buttonCreateToken().click();
new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(createTokenForm().selectUserNameDropdown()));
createTokenForm().selectUserNameDropdown().click();
new WebDriverWait(driver, 5).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
createTokenForm().selectUserNameList()
.stream()
.filter(it -> it.getText().contains(userName))
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format("No %s in token dropdown list",
userName)))
.click();
createTokenForm().buttonGenerateToken().click(); createTokenForm().buttonGenerateToken().click();
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(createTokenForm.buttonGenerateToken)); new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(createTokenForm().buttonGenerateToken()));
createTokenForm().buttonSubmit().click(); createTokenForm().buttonSubmit().click();
return this; return this;
} }
public TokenPage update(String userName) { public TokenPage update(String userName) {
tokenList().stream() tokenList().stream()
.filter(it -> it.findElement(By.className("userName")).getAttribute("innerHTML").contains(userName)) .filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName))
.flatMap(it -> it.findElements(By.className("edit")).stream()) .flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in token list")) .orElseThrow(() -> new RuntimeException("No edit button in token list"))
.click(); .click();
TokenForm editTokenForm = new TokenForm(); new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken()));
editTokenForm().buttonGenerateToken().click();
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken()));
editTokenForm().buttonSubmit().click();
editTokenForm.buttonGenerateToken().click();
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(createTokenForm.buttonGenerateToken));
editTokenForm.buttonSubmit().click();
return this; return this;
} }
public String getToken(String userName) { public String getToken(String userName) {
return tokenList().stream() return tokenList().stream()
.filter(it -> it.findElement(By.className("userName")).getAttribute("innerHTML").contains(userName)) .filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName))
.flatMap(it -> it.findElements(By.className("token")).stream()) .flatMap(it -> it.findElements(By.className("token")).stream())
.filter(it -> !Strings.isNullOrEmpty(it.getAttribute("innerHTML"))) .filter(it -> !Strings.isNullOrEmpty(it.getAttribute("innerHTML")))
.map(it -> it.getAttribute("innerHTML")) .map(it -> it.getAttribute("innerHTML"))
@ -109,12 +126,7 @@ public final class TokenPage extends NavBarPage implements Tab {
.orElseThrow(() -> new RuntimeException("No delete button in token list")) .orElseThrow(() -> new RuntimeException("No delete button in token list"))
.click(); .click();
buttonConfirm() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.stream()
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No confirm button when deleting"))
.click();
return this; return this;
} }
@ -125,13 +137,22 @@ public final class TokenPage extends NavBarPage implements Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "btnGenerateToken") @FindBys({
@FindBy(className = "input-username"),
@FindBy(className = "n-base-selection"),
})
private WebElement selectUserNameDropdown;
@FindBy(className = "n-base-select-option__content")
private List<WebElement> selectUserNameList;
@FindBy(className = "btn-generate-token")
private WebElement buttonGenerateToken; private WebElement buttonGenerateToken;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }

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

@ -24,6 +24,8 @@ import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.util.List; import java.util.List;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
@ -31,20 +33,22 @@ import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter; import lombok.Getter;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@Getter @Getter
public final class UserPage extends NavBarPage implements SecurityPage.Tab { public final class UserPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(id = "btnCreateUser") @FindBy(className = "btn-create-user")
private WebElement buttonCreateUser; private WebElement buttonCreateUser;
@FindBy(className = "items") @FindBy(className = "items")
private List<WebElement> userList; private List<WebElement> userList;
@FindBys({ @FindBys({
@FindBy(className = "el-popconfirm"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "el-button--primary"), @FindBy(className = "n-button--primary-type"),
}) })
private List<WebElement> buttonConfirm; private WebElement buttonConfirm;
private final UserForm createUserForm = new UserForm(); private final UserForm createUserForm = new UserForm();
private final UserForm editUserForm = new UserForm(); private final UserForm editUserForm = new UserForm();
@ -54,11 +58,24 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
super(driver); super(driver);
} }
public UserPage create(String user, String password, String email, String phone) { public UserPage create(String user, String password, String email, String phone, String tenant) {
buttonCreateUser().click(); buttonCreateUser().click();
createUserForm().inputUserName().sendKeys(user); createUserForm().inputUserName().sendKeys(user);
createUserForm().inputUserPassword().sendKeys(password); createUserForm().inputUserPassword().sendKeys(password);
createUserForm().btnSelectTenantDropdown().click();
new WebDriverWait(driver, 5).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();
createUserForm().inputEmail().sendKeys(email); createUserForm().inputEmail().sendKeys(email);
createUserForm().inputPhone().sendKeys(phone); createUserForm().inputPhone().sendKeys(phone);
createUserForm().buttonSubmit().click(); createUserForm().buttonSubmit().click();
@ -67,8 +84,7 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
} }
public UserPage update(String user, String editUser, String editPassword, String editEmail, String editPhone) { public UserPage update(String user, String editUser, String editPassword, String editEmail, String editPhone) {
List<WebElement> userList = driver.findElementsByClassName("items"); userList().stream()
userList.stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user)) .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user))
.flatMap(it -> it.findElements(By.className("edit")).stream()) .flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
@ -76,17 +92,21 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
.orElseThrow(() -> new RuntimeException("No edit button in user list")) .orElseThrow(() -> new RuntimeException("No edit button in user list"))
.click(); .click();
UserForm editUserForm = new UserForm(); editUserForm().inputUserName().sendKeys(Keys.CONTROL+"a");
editUserForm().inputUserName().sendKeys(Keys.BACK_SPACE);
editUserForm().inputUserName().sendKeys(editUser);
editUserForm.inputUserName().clear(); editUserForm().inputUserPassword().sendKeys(editPassword);
editUserForm.inputUserName().sendKeys(editUser);
editUserForm.inputUserPassword().clear(); editUserForm().inputEmail().sendKeys(Keys.CONTROL+"a");
editUserForm.inputUserPassword().sendKeys(editPassword); editUserForm().inputEmail().sendKeys(Keys.BACK_SPACE);
editUserForm.inputEmail().clear(); editUserForm().inputEmail().sendKeys(editEmail);
editUserForm.inputEmail().sendKeys(editEmail);
editUserForm.inputPhone().clear(); editUserForm().inputPhone().sendKeys(Keys.CONTROL+"a");
editUserForm.inputPhone().sendKeys(editPhone); editUserForm().inputPhone().sendKeys(Keys.BACK_SPACE);
editUserForm.buttonSubmit().click(); editUserForm().inputPhone().sendKeys(editPhone);
editUserForm().buttonSubmit().click();
return this; return this;
} }
@ -101,12 +121,7 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
.orElseThrow(() -> new RuntimeException("No delete button in user list")) .orElseThrow(() -> new RuntimeException("No delete button in user list"))
.click(); .click();
buttonConfirm() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.stream()
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No confirm button when deleting"))
.click();
return this; return this;
} }
@ -117,34 +132,58 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputUserName") @FindBys({
@FindBy(className = "input-username"),
@FindBy(tagName = "input"),
})
private WebElement inputUserName; private WebElement inputUserName;
@FindBy(id = "inputUserPassword") @FindBys({
@FindBy(className = "input-password"),
@FindBy(tagName = "input"),
})
private WebElement inputUserPassword; private WebElement inputUserPassword;
@FindBy(id = "selectTenant") @FindBys({
private WebElement selectTenant; @FindBy(className = "select-tenant"),
@FindBy(className = "n-base-selection"),
})
private WebElement btnSelectTenantDropdown;
@FindBy(className = "n-base-select-option__content")
private List<WebElement> selectTenant;
@FindBy(id = "selectQueue") @FindBys({
private WebElement selectQueue; @FindBy(className = "select-queue"),
@FindBy(className = "n-base-selection"),
})
private WebElement btnSelectQueueDropdown;
@FindBy(id = "inputEmail") @FindBy(className = "n-base-select-option__content")
private List<WebElement> selectQueue;
@FindBys({
@FindBy(className = "input-email"),
@FindBy(tagName = "input"),
})
private WebElement inputEmail; private WebElement inputEmail;
@FindBy(id = "inputPhone") @FindBys({
@FindBy(className = "input-phone"),
@FindBy(tagName = "input"),
})
private WebElement inputPhone; private WebElement inputPhone;
@FindBy(id = "radioStateEnable") @FindBy(className = "radio-state-enable")
private WebElement radioStateEnable; private WebElement radioStateEnable;
@FindBy(id = "radioStateDisable") @FindBy(className = "radio-state-disable")
private WebElement radioStateDisable; private WebElement radioStateDisable;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
} }

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

@ -22,6 +22,8 @@ package org.apache.dolphinscheduler.e2e.pages.security;
import lombok.Getter; import lombok.Getter;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
@ -33,17 +35,17 @@ import java.util.List;
@Getter @Getter
public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Tab { public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(id = "btnCreateWorkerGroup") @FindBy(className = "btn-create-worker-group")
private WebElement buttonCreateWorkerGroup; private WebElement buttonCreateWorkerGroup;
@FindBy(className = "items") @FindBy(className = "items")
private List<WebElement> workerGroupList; private List<WebElement> workerGroupList;
@FindBys({ @FindBys({
@FindBy(className = "el-popconfirm"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "el-button--primary"), @FindBy(className = "n-button--primary-type"),
}) })
private List<WebElement> buttonConfirm; private WebElement buttonConfirm;
private final WorkerGroupForm createWorkerForm = new WorkerGroupForm(); private final WorkerGroupForm createWorkerForm = new WorkerGroupForm();
private final WorkerGroupForm editWorkerForm = new WorkerGroupForm(); private final WorkerGroupForm editWorkerForm = new WorkerGroupForm();
@ -58,7 +60,7 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
buttonCreateWorkerGroup().click(); buttonCreateWorkerGroup().click();
createWorkerForm().inputWorkerGroupName().sendKeys(workerGroupName); createWorkerForm().inputWorkerGroupName().sendKeys(workerGroupName);
createWorkerForm().selectWorkerAddress().click(); createWorkerForm().btnSelectWorkerAddress().click();
createWorkerForm().workerAddressList().click(); createWorkerForm().workerAddressList().click();
createWorkerForm().buttonSubmit().click(); createWorkerForm().buttonSubmit().click();
@ -76,7 +78,8 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
.orElseThrow(() -> new RuntimeException("No edit button in workerGroup list")) .orElseThrow(() -> new RuntimeException("No edit button in workerGroup list"))
.click(); .click();
editWorkerForm().inputWorkerGroupName().clear(); editWorkerForm().inputWorkerGroupName().sendKeys(Keys.CONTROL + "a");
editWorkerForm().inputWorkerGroupName().sendKeys(Keys.BACK_SPACE);
editWorkerForm().inputWorkerGroupName().sendKeys(editWorkerGroupName); editWorkerForm().inputWorkerGroupName().sendKeys(editWorkerGroupName);
editWorkerForm().buttonSubmit().click(); editWorkerForm().buttonSubmit().click();
@ -95,12 +98,7 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
.orElseThrow(() -> new RuntimeException("No delete button in workerGroup list")) .orElseThrow(() -> new RuntimeException("No delete button in workerGroup list"))
.click(); .click();
buttonConfirm() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.stream()
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No confirm button when deleting"))
.click();
return this; return this;
} }
@ -111,19 +109,25 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputWorkerGroupName") @FindBys({
@FindBy(className = "input-worker-group-name"),
@FindBy(tagName = "input"),
})
private WebElement inputWorkerGroupName; private WebElement inputWorkerGroupName;
@FindBy(id = "selectWorkerAddress") @FindBys({
private WebElement selectWorkerAddress; @FindBy(className = "select-worker-address"),
@FindBy(className = "n-base-selection"),
})
private WebElement btnSelectWorkerAddress;
@FindBy(className = "vue-treeselect__menu") @FindBy(className = "n-base-select-option__content")
private WebElement workerAddressList; private WebElement workerAddressList;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
} }

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

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

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

@ -53,7 +53,6 @@ import org.testcontainers.containers.ContainerState;
import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.DockerComposeContainer;
import org.testcontainers.containers.Network; import org.testcontainers.containers.Network;
import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.shaded.org.apache.commons.lang.SystemUtils;
import org.testcontainers.shaded.org.awaitility.Awaitility; import org.testcontainers.shaded.org.awaitility.Awaitility;
import com.google.common.base.Strings; import com.google.common.base.Strings;

1
dolphinscheduler-ui-next/src/layouts/content/components/sidebar/index.tsx

@ -60,6 +60,7 @@ const Sidebar = defineComponent({
onExpand={() => (this.collapsedRef = false)} onExpand={() => (this.collapsedRef = false)}
> >
<NMenu <NMenu
class="tab-vertical"
value={this.sideKey} value={this.sideKey}
options={this.sideMenuOptions} options={this.sideMenuOptions}
defaultExpandedKeys={this.defaultExpandedKeys} defaultExpandedKeys={this.defaultExpandedKeys}

1
dolphinscheduler-ui-next/src/layouts/content/index.tsx

@ -103,6 +103,7 @@ const Content = defineComponent({
<NLayout style='height: 100%'> <NLayout style='height: 100%'>
<NLayoutHeader style='height: 65px'> <NLayoutHeader style='height: 65px'>
<NavBar <NavBar
class="tab-horizontal"
onHandleMenuClick={this.getSideMenuOptions} onHandleMenuClick={this.getSideMenuOptions}
headerMenuOptions={this.headerMenuOptions} headerMenuOptions={this.headerMenuOptions}
localesOptions={this.localesOptions} localesOptions={this.localesOptions}

3
pom.xml

@ -1034,9 +1034,6 @@
</goals> </goals>
<configuration> <configuration>
<skip>${docker.build.skip}</skip> <skip>${docker.build.skip}</skip>
<environmentVariables>
<DOCKER_BUILDKIT>1</DOCKER_BUILDKIT>
</environmentVariables>
<executable>docker</executable> <executable>docker</executable>
<workingDirectory>${project.basedir}</workingDirectory> <workingDirectory>${project.basedir}</workingDirectory>
<arguments> <arguments>

Loading…
Cancel
Save