Browse Source

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

xiangzihao 3 years ago
parent
commit
20dd0c12ce
23 changed files with 434 additions and 274 deletions
  1. 22 23
      .github/workflows/e2e.yml
  2. 5 3
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/EnvironmentE2ETest.java
  3. 14 14
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java
  4. 22 22
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FunctionManageE2ETest.java
  5. 3 1
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/QueueE2ETest.java
  6. 4 4
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TokenE2ETest.java
  7. 14 14
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UdfManageE2ETest.java
  8. 27 26
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java
  9. 1 1
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java
  10. 18 6
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java
  11. 18 18
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java
  12. 73 20
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java
  13. 21 6
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/QueuePage.java
  14. 24 19
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java
  15. 23 16
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java
  16. 43 22
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java
  17. 74 35
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java
  18. 22 18
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/WorkerGroupPage.java
  19. 4 2
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/basic/docker-compose.yaml
  20. 0 1
      dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java
  21. 1 0
      dolphinscheduler-ui-next/src/layouts/content/components/sidebar/index.tsx
  22. 1 0
      dolphinscheduler-ui-next/src/layouts/content/index.tsx
  23. 0 3
      pom.xml

+ 22 - 23
.github/workflows/e2e.yml

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

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

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

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

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

@@ -83,28 +83,28 @@ public class FunctionManageE2ETest {
     @BeforeAll
     @SneakyThrows
     public static void setup() {
-        TenantPage tenantPage = new LoginPage(browser)
-            .login(user, password)
-            .create(tenant);
-
-        await().untilAsserted(() -> assertThat(tenantPage.tenantList())
-            .as("Tenant list should contain newly-created tenant")
-            .extracting(WebElement::getText)
-            .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());
-
-        UdfManagePage udfManagePage = tenantPage.goToNav(SecurityPage.class)
-            .goToTab(UserPage.class)
-            .update(user, user, password, email, phone)
-            .goToNav(ResourcePage.class)
-            .goToTab(UdfManagePage.class)
-            .uploadFile(testUploadUdfFilePath.toFile().getAbsolutePath());
-
-        new WebDriverWait(browser, 10).until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog")));
-
-        udfManagePage.goToNav(ResourcePage.class)
-            .goToTab(FunctionManagePage.class);
+//        TenantPage tenantPage = new LoginPage(browser)
+//            .login(user, password)
+//            .create(tenant);
+//
+//        await().untilAsserted(() -> assertThat(tenantPage.tenantList())
+//            .as("Tenant list should contain newly-created tenant")
+//            .extracting(WebElement::getText)
+//            .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());
+//
+//        UdfManagePage udfManagePage = tenantPage.goToNav(SecurityPage.class)
+//            .goToTab(UserPage.class)
+//            .update(user, user, password, email, phone)
+//            .goToNav(ResourcePage.class)
+//            .goToTab(UdfManagePage.class)
+//            .uploadFile(testUploadUdfFilePath.toFile().getAbsolutePath());
+//
+//        new WebDriverWait(browser, 10).until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog")));
+//
+//        udfManagePage.goToNav(ResourcePage.class)
+//            .goToTab(FunctionManagePage.class);
     }
 
     @AfterAll

+ 3 - 1
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/QueueE2ETest.java

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

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

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

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

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

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

+ 1 - 1
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);
 
         new WebDriverWait(page.driver(), 10)
-            .until(ExpectedConditions.urlContains("/#/security/worker-groups"));
+            .until(ExpectedConditions.urlContains("/security/worker-group-manage"));
 
         page.create(workerGroupName);
 

+ 18 - 6
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.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;
 
@@ -33,28 +34,39 @@ import lombok.SneakyThrows;
 
 @Getter
 public final class LoginPage extends NavBarPage {
-    @FindBy(id = "inputUsername")
+    @FindBys({
+        @FindBy(className = "input-user-name"),
+        @FindBy(tagName = "input"),
+    })
     private WebElement inputUsername;
 
-    @FindBy(id = "inputPassword")
+    @FindBys( {
+        @FindBy(className = "input-password"),
+        @FindBy(tagName = "input"),
+    })
     private WebElement inputPassword;
 
-    @FindBy(id = "btnLogin")
+    @FindBy(className = "btn-login")
     private WebElement buttonLogin;
 
+    @FindBy(className = "n-switch__button")
+    private WebElement buttonSwitchLanguage;
+
     public LoginPage(RemoteWebDriver driver) {
         super(driver);
     }
 
     @SneakyThrows
-    public TenantPage login(String username, String password) {
+    public NavBarPage login(String username, String password) {
+        buttonSwitchLanguage().click();
+
         inputUsername().sendKeys(username);
         inputPassword().sendKeys(password);
         buttonLogin().click();
 
         new WebDriverWait(driver, 10)
-            .until(ExpectedConditions.urlContains("/#/security"));
+            .until(ExpectedConditions.urlContains("/home"));
 
-        return new TenantPage(driver);
+        return new NavBarPage(driver);
     }
 }

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

+ 73 - 20
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 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;
@@ -31,20 +33,22 @@ 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(id = "btnCreateEnvironment")
+    @FindBy(className = "btn-create-environment")
     private WebElement buttonCreateEnvironment;
 
     @FindBy(className = "items")
     private List<WebElement> environmentList;
 
     @FindBys({
-            @FindBy(className = "el-popconfirm"),
-            @FindBy(className = "el-button--primary"),
+        @FindBy(className = "n-popconfirm__action"),
+        @FindBy(className = "n-button--primary-type"),
     })
-    private List<WebElement> buttonConfirm;
+    private WebElement buttonConfirm;
 
     private final EnvironmentForm createEnvironmentForm;
     private final EnvironmentForm editEnvironmentForm;
@@ -60,7 +64,18 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
         createEnvironmentForm().inputEnvironmentName().sendKeys(name);
         createEnvironmentForm().inputEnvironmentConfig().sendKeys(config);
         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();
         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) {
         environmentList()
                 .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())
                 .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);
+
+        editEnvironmentForm().inputEnvironmentConfig().sendKeys(Keys.CONTROL + "a");
+        editEnvironmentForm().inputEnvironmentConfig().sendKeys(Keys.BACK_SPACE);
         editEnvironmentForm().inputEnvironmentConfig().sendKeys(config);
+
+        editEnvironmentForm().inputEnvironmentDesc().sendKeys(Keys.CONTROL + "a");
+        editEnvironmentForm().inputEnvironmentDesc().sendKeys(Keys.BACK_SPACE);
         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();
 
         return this;
@@ -94,12 +131,7 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
                 .orElseThrow(() -> new RuntimeException("No delete button in environment list"))
                 .click();
 
-        buttonConfirm()
-                .stream()
-                .filter(WebElement::isDisplayed)
-                .findFirst()
-                .orElseThrow(() -> new RuntimeException("No confirm button when deleting"))
-                .click();
+        ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
 
         return this;
     }
@@ -110,22 +142,43 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta
             PageFactory.initElements(driver, this);
         }
 
-        @FindBy(id = "inputEnvironmentName")
+        @FindBys({
+            @FindBy(className = "input-environment-name"),
+            @FindBy(tagName = "input"),
+        })
         private WebElement inputEnvironmentName;
 
-        @FindBy(id = "inputEnvironmentConfig")
+        @FindBys({
+            @FindBy(className = "input-environment-config"),
+            @FindBy(tagName = "textarea"),
+        })
         private WebElement inputEnvironmentConfig;
 
-        @FindBy(id = "inputEnvironmentDesc")
+        @FindBys({
+            @FindBy(className = "input-environment-desc"),
+            @FindBy(tagName = "input"),
+        })
         private WebElement inputEnvironmentDesc;
 
-        @FindBy(id = "inputEnvironmentWorkerGroup")
-        private WebElement inputWorkerGroup;
+        @FindBys({
+                @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;
 
-        @FindBy(id = "btnCancel")
+        @FindBy(className = "btn-cancel")
         private WebElement buttonCancel;
     }
 }

+ 21 - 6
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 java.security.Key;
 import java.util.List;
 
 import org.openqa.selenium.By;
+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 lombok.Getter;
 
 @Getter
 public final class QueuePage extends NavBarPage implements SecurityPage.Tab {
-    @FindBy(id = "btnCreateQueue")
+    @FindBy(className = "btn-create-queue")
     private WebElement buttonCreateQueue;
 
     @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) {
         queueList()
                 .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())
                 .filter(WebElement::isDisplayed)
                 .findFirst()
                 .orElseThrow(() -> new RuntimeException("No edit button in queue list"))
                 .click();
 
+        editQueueForm().inputQueueName().sendKeys(Keys.CONTROL + "a");
+        editQueueForm().inputQueueName().sendKeys(Keys.BACK_SPACE);
         editQueueForm().inputQueueName().sendKeys(editQueueName);
+
+        editQueueForm().inputQueueValue().sendKeys(Keys.CONTROL + "a");
+        editQueueForm().inputQueueValue().sendKeys(Keys.BACK_SPACE);
         editQueueForm().inputQueueValue().sendKeys(editQueueValue);
+
         editQueueForm().buttonSubmit().click();
 
         return this;
@@ -79,16 +88,22 @@ public final class QueuePage extends NavBarPage implements SecurityPage.Tab {
             PageFactory.initElements(driver, this);
         }
 
-        @FindBy(id = "inputQueueName")
+        @FindBys({
+            @FindBy(className = "input-queue-name"),
+            @FindBy(tagName = "input"),
+        })
         private WebElement inputQueueName;
 
-        @FindBy(id = "inputQueueValue")
+        @FindBys({
+                @FindBy(className = "input-queue-value"),
+                @FindBy(tagName = "input"),
+        })
         private WebElement inputQueueValue;
 
-        @FindBy(id = "btnSubmit")
+        @FindBy(className = "btn-submit")
         private WebElement buttonSubmit;
 
-        @FindBy(id = "btnCancel")
+        @FindBy(className = "btn-cancel")
         private WebElement buttonCancel;
     }
 }

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

+ 23 - 16
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 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;
@@ -34,19 +36,19 @@ import lombok.Getter;
 
 @Getter
 public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
-    @FindBy(id = "btnCreateTenant")
+    @FindBy(className = "btn-create-tenant")
     private WebElement buttonCreateTenant;
 
     @FindBy(className = "items")
     private List<WebElement> tenantList;
 
     @FindBys({
-        @FindBy(className = "el-popconfirm"),
-        @FindBy(className = "el-button--primary"),
+        @FindBy(className = "n-popconfirm__action"),
+        @FindBy(className = "n-button--primary-type"),
     })
     private WebElement buttonConfirm;
 
-    @FindBy(className = "tenantCode")
+    @FindBy(className = "tenant-code")
     private WebElement tenantCode;
 
     private final TenantForm tenantForm;
@@ -74,18 +76,17 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
 
     public TenantPage update(String tenant, String description) {
         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())
             .filter(WebElement::isDisplayed)
             .findFirst()
             .orElseThrow(() -> new RuntimeException("No edit button in tenant list"))
             .click();
 
-        TenantForm editTenantForm = new TenantForm();
-
-        editTenantForm.inputDescription().clear();
-        editTenantForm.inputDescription().sendKeys(description);
-        editTenantForm.buttonSubmit().click();
+        editTenantForm().inputDescription().sendKeys(Keys.CONTROL + "a");
+        editTenantForm().inputDescription().sendKeys(Keys.BACK_SPACE);
+        editTenantForm().inputDescription().sendKeys(description);
+        editTenantForm().buttonSubmit().click();
 
         return this;
     }
@@ -100,7 +101,7 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
             .orElseThrow(() -> new RuntimeException("No delete button in user list"))
             .click();
 
-        buttonConfirm().click();
+        ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
 
         return this;
     }
@@ -111,19 +112,25 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
             PageFactory.initElements(driver, this);
         }
 
-        @FindBy(id = "inputTenantCode")
+        @FindBys({
+                @FindBy(className = "input-tenant-code"),
+                @FindBy(tagName = "input"),
+        })
         private WebElement inputTenantCode;
 
-        @FindBy(id = "selectQueue")
+        @FindBy(className = "select-queue")
         private WebElement selectQueue;
 
-        @FindBy(id = "inputDescription")
+        @FindBys({
+                @FindBy(className = "input-description"),
+                @FindBy(tagName = "textarea"),
+        })
         private WebElement inputDescription;
 
-        @FindBy(id = "btnSubmit")
+        @FindBy(className = "btn-submit")
         private WebElement buttonSubmit;
 
-        @FindBy(id = "btnCancel")
+        @FindBy(className = "btn-cancel")
         private WebElement buttonCancel;
     }
 }

+ 43 - 22
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 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;
@@ -39,19 +40,19 @@ import com.google.common.base.Strings;
 
 @Getter
 public final class TokenPage extends NavBarPage implements Tab {
-    @FindBy(id = "btnCreateToken")
+    @FindBy(className = "btn-create-token")
     private WebElement buttonCreateToken;
 
     @FindBy(className = "items")
     private List<WebElement> tokenList;
 
     @FindBys({
-        @FindBy(className = "el-popconfirm"),
-        @FindBy(className = "el-button--primary"),
+        @FindBy(className = "n-popconfirm__action"),
+        @FindBy(className = "n-button--primary-type"),
     })
-    private List<WebElement> buttonConfirm;
+    private WebElement buttonConfirm;
 
-    @FindBy(className = "userName")
+    @FindBy(className = "username")
     private List<WebElement> userName;
 
     @FindBy(className = "token")
@@ -64,34 +65,50 @@ public final class TokenPage extends NavBarPage implements Tab {
         super(driver);
     }
 
-    public TokenPage create() {
+    public TokenPage create(String userName) {
         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();
-        new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(createTokenForm.buttonGenerateToken));
+        new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(createTokenForm().buttonGenerateToken()));
+
         createTokenForm().buttonSubmit().click();
+
         return this;
     }
 
     public TokenPage update(String userName) {
         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())
             .filter(WebElement::isDisplayed)
             .findFirst()
             .orElseThrow(() -> new RuntimeException("No edit button in token list"))
             .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;
     }
 
     public String getToken(String userName) {
         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())
                           .filter(it -> !Strings.isNullOrEmpty(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"))
             .click();
 
-        buttonConfirm()
-            .stream()
-            .filter(WebElement::isDisplayed)
-            .findFirst()
-            .orElseThrow(() -> new RuntimeException("No confirm button when deleting"))
-            .click();
+        ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
 
         return this;
     }
@@ -125,13 +137,22 @@ public final class TokenPage extends NavBarPage implements Tab {
             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;
 
-        @FindBy(id = "btnSubmit")
+        @FindBy(className = "btn-submit")
         private WebElement buttonSubmit;
 
-        @FindBy(id = "btnCancel")
+        @FindBy(className = "btn-cancel")
         private WebElement buttonCancel;
 
     }

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

+ 22 - 18
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 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.WebElement;
 import org.openqa.selenium.remote.RemoteWebDriver;
 import org.openqa.selenium.support.FindBy;
@@ -33,17 +35,17 @@ import java.util.List;
 
 @Getter
 public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Tab {
-    @FindBy(id = "btnCreateWorkerGroup")
+    @FindBy(className = "btn-create-worker-group")
     private WebElement buttonCreateWorkerGroup;
 
     @FindBy(className = "items")
     private List<WebElement> workerGroupList;
 
     @FindBys({
-        @FindBy(className = "el-popconfirm"),
-        @FindBy(className = "el-button--primary"),
+        @FindBy(className = "n-popconfirm__action"),
+        @FindBy(className = "n-button--primary-type"),
     })
-    private List<WebElement> buttonConfirm;
+    private WebElement buttonConfirm;
 
     private final WorkerGroupForm createWorkerForm = new WorkerGroupForm();
     private final WorkerGroupForm editWorkerForm = new WorkerGroupForm();
@@ -58,7 +60,7 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
         buttonCreateWorkerGroup().click();
 
         createWorkerForm().inputWorkerGroupName().sendKeys(workerGroupName);
-        createWorkerForm().selectWorkerAddress().click();
+        createWorkerForm().btnSelectWorkerAddress().click();
         createWorkerForm().workerAddressList().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"))
                 .click();
 
-        editWorkerForm().inputWorkerGroupName().clear();
+        editWorkerForm().inputWorkerGroupName().sendKeys(Keys.CONTROL + "a");
+        editWorkerForm().inputWorkerGroupName().sendKeys(Keys.BACK_SPACE);
         editWorkerForm().inputWorkerGroupName().sendKeys(editWorkerGroupName);
 
         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"))
             .click();
 
-        buttonConfirm()
-            .stream()
-            .filter(WebElement::isDisplayed)
-            .findFirst()
-            .orElseThrow(() -> new RuntimeException("No confirm button when deleting"))
-            .click();
+        ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
 
         return this;
     }
@@ -111,19 +109,25 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta
             PageFactory.initElements(driver, this);
         }
 
-        @FindBy(id = "inputWorkerGroupName")
+        @FindBys({
+            @FindBy(className = "input-worker-group-name"),
+            @FindBy(tagName = "input"),
+        })
         private WebElement inputWorkerGroupName;
 
-        @FindBy(id = "selectWorkerAddress")
-        private WebElement selectWorkerAddress;
+        @FindBys({
+            @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;
 
-        @FindBy(id = "btnSubmit")
+        @FindBy(className = "btn-submit")
         private WebElement buttonSubmit;
 
-        @FindBy(id = "btnCancel")
+        @FindBy(className = "btn-cancel")
         private WebElement buttonCancel;
     }
 }

+ 4 - 2
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/basic/docker-compose.yaml

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

+ 0 - 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.Network;
 import org.testcontainers.containers.wait.strategy.Wait;
-import org.testcontainers.shaded.org.apache.commons.lang.SystemUtils;
 import org.testcontainers.shaded.org.awaitility.Awaitility;
 
 import com.google.common.base.Strings;

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

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

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

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

+ 0 - 3
pom.xml

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