This is an automated email from the ASF dual-hosted git repository.

benjobs pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampark.git


The following commit(s) were added to refs/heads/dev by this push:
     new df8ca3aa1 [ISSUE-3811][Feature] Introduce role management e2e test 
(#3824)
df8ca3aa1 is described below

commit df8ca3aa1d02a4d1f8464c1f73650519c0327c4e
Author: Zhengke Zhou <[email protected]>
AuthorDate: Fri Jul 5 13:23:19 2024 +0800

    [ISSUE-3811][Feature] Introduce role management e2e test (#3824)
    
    * Introduce role management e2e test
    
    * fix code format
    
    ---------
    
    Co-authored-by: benjobs <[email protected]>
---
 .github/workflows/e2e.yml                          |   2 +
 .../streampark/e2e/cases/RoleManagementTest.java   | 122 ++++++++++++++++
 .../e2e/pages/system/RoleManagementPage.java       | 159 +++++++++++++++++++++
 .../streampark/e2e/pages/system/SystemPage.java    |   7 +
 4 files changed, 290 insertions(+)

diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 316291b8a..a70adbbee 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -105,6 +105,8 @@ jobs:
     strategy:
       matrix:
         case:
+          - name: RoleManagementTest
+            class: org.apache.streampark.e2e.cases.RoleManagementTest
           - name: UserManagementTest
             class: org.apache.streampark.e2e.cases.UserManagementTest
           - name: TeamManagementTest
diff --git 
a/streampark-e2e/streampark-e2e-case/src/test/java/org/apache/streampark/e2e/cases/RoleManagementTest.java
 
b/streampark-e2e/streampark-e2e-case/src/test/java/org/apache/streampark/e2e/cases/RoleManagementTest.java
new file mode 100644
index 000000000..9f354c3bb
--- /dev/null
+++ 
b/streampark-e2e/streampark-e2e-case/src/test/java/org/apache/streampark/e2e/cases/RoleManagementTest.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.streampark.e2e.cases;
+
+import org.apache.streampark.e2e.core.StreamPark;
+import org.apache.streampark.e2e.pages.LoginPage;
+import org.apache.streampark.e2e.pages.system.RoleManagementPage;
+import org.apache.streampark.e2e.pages.system.SystemPage;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.remote.RemoteWebDriver;
+import org.testcontainers.shaded.org.awaitility.Awaitility;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@StreamPark(composeFiles = "docker/basic/docker-compose.yaml")
+public class RoleManagementTest {
+
+    private static RemoteWebDriver browser;
+
+    private static final String userName = "admin";
+
+    private static final String password = "streampark";
+
+    private static final String teamName = "default";
+
+    private static final String newRoleName = "new_role";
+
+    private static final String newDescription = "new_description";
+
+    private static final String existMenuName = "Apache Flink";
+
+    @BeforeAll
+    public static void setup() {
+        new LoginPage(browser)
+                .login(userName, password, teamName)
+                .goToNav(SystemPage.class)
+                .goToTab(RoleManagementPage.class);
+    }
+
+    @Test
+    @Order(10)
+    void testCreateUser() {
+        final RoleManagementPage roleManagementPage = new 
RoleManagementPage(browser);
+        roleManagementPage.createRole(newRoleName, newDescription, 
existMenuName);
+
+        Awaitility.await()
+                .untilAsserted(
+                        () -> assertThat(roleManagementPage.roleList())
+                                .as("Role list should contain newly-created 
role")
+                                .extracting(WebElement::getText)
+                                .anyMatch(it -> it.contains(newRoleName)));
+    }
+
+    @Test
+    @Order(20)
+    void testCreateDuplicateRole() {
+        final RoleManagementPage roleManagementPage = new 
RoleManagementPage(browser);
+        roleManagementPage.createRole(newRoleName, newDescription, 
existMenuName);
+
+        Awaitility.await()
+                .untilAsserted(
+                        () -> assertThat(roleManagementPage.errorMessageList())
+                                .as("Role Name Duplicated Error message should 
be displayed")
+                                .extracting(WebElement::getText)
+                                .anyMatch(it -> it.contains("Sorry, the role 
name already exists")));
+
+        roleManagementPage.createRoleForm().buttonCancel().click();
+    }
+    @Test
+    @Order(30)
+    void testEditRole() {
+        final RoleManagementPage roleManagementPage = new 
RoleManagementPage(browser);
+
+        String newEditDescription = newDescription + "_edit";
+        String newEditMenuName = "System";
+        roleManagementPage.editRole(newRoleName, newEditDescription, 
newEditMenuName);
+
+        // TODO: there is no description filed value actual exist
+        // Awaitility.await()
+        // .untilAsserted(
+        // () ->
+        // assertThat(roleManagementPage.roleList())
+        // .as("Role list should contain newly-created role")
+        // .extracting(WebElement::getText)
+        // .anyMatch(it -> it.contains(newEditDescription)));
+    }
+
+    @Test
+    @Order(40)
+    void testDeleteRole() {
+        final RoleManagementPage roleManagementPage = new 
RoleManagementPage(browser);
+
+        roleManagementPage.deleteRole(newRoleName);
+
+        Awaitility.await()
+                .untilAsserted(
+                        () -> assertThat(roleManagementPage.roleList())
+                                .extracting(WebElement::getText)
+                                .noneMatch(it -> it.contains(newRoleName)));
+    }
+}
diff --git 
a/streampark-e2e/streampark-e2e-case/src/test/java/org/apache/streampark/e2e/pages/system/RoleManagementPage.java
 
b/streampark-e2e/streampark-e2e-case/src/test/java/org/apache/streampark/e2e/pages/system/RoleManagementPage.java
new file mode 100644
index 000000000..7e1141068
--- /dev/null
+++ 
b/streampark-e2e/streampark-e2e-case/src/test/java/org/apache/streampark/e2e/pages/system/RoleManagementPage.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.streampark.e2e.pages.system;
+
+import org.apache.streampark.e2e.pages.common.NavBarPage;
+
+import lombok.Getter;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.remote.RemoteWebDriver;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.FindBys;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Objects;
+
+@Getter
+public class RoleManagementPage extends NavBarPage implements SystemPage.Tab {
+
+    @FindBy(xpath = "//span[contains(., 'Role 
List')]/..//button[contains(@class, 'ant-btn-primary')]/span[contains(text(), 
'Add New')]")
+    private WebElement buttonCreateRole;
+
+    @FindBy(xpath = "//tbody[contains(@class, 'ant-table-tbody')]")
+    private List<WebElement> roleList;
+
+    @FindBy(className = "ant-form-item-explain-error")
+    private List<WebElement> errorMessageList;
+
+    @FindBy(xpath = "//button[contains(@class, 'ant-btn')]/span[contains(., 
'OK')]")
+    private WebElement deleteConfirmButton;
+
+    private final CreateRoleForm createRoleForm = new CreateRoleForm();
+
+    public RoleManagementPage(RemoteWebDriver driver) {
+        super(driver);
+    }
+
+    public RoleManagementPage createRole(String roleName, String description, 
String menuName) {
+        waitForPageLoading();
+
+        new WebDriverWait(driver, Duration.ofSeconds(10))
+                
.until(ExpectedConditions.elementToBeClickable(buttonCreateRole));
+        buttonCreateRole.click();
+
+        createRoleForm.inputRoleName().sendKeys(roleName);
+        createRoleForm.inputDescription().sendKeys(description);
+        editRoleMenu(menuName);
+
+        createRoleForm.buttonSubmit().click();
+        return this;
+    }
+
+    public RoleManagementPage editRole(String roleName, String description, 
String menuName) {
+        waitForPageLoading();
+        new WebDriverWait(driver, Duration.ofSeconds(2));
+
+        roleList().stream()
+                .filter(it -> it.getText().contains(roleName))
+                .flatMap(
+                        it -> 
it.findElements(By.xpath("//button[contains(@tooltip,'Edit Role')]")).stream())
+                .filter(WebElement::isDisplayed)
+                .findFirst()
+                .orElseThrow(() -> new RuntimeException("No edit button in 
role list"))
+                .click();
+
+        createRoleForm.inputDescription().sendKeys(description);
+        editRoleMenu(menuName);
+
+        createRoleForm.buttonSubmit().click();
+
+        return this;
+    }
+
+    public RoleManagementPage deleteRole(String roleName) {
+        waitForPageLoading();
+        roleList().stream()
+                .filter(it -> it.getText().contains(roleName))
+                .flatMap(
+                        it -> 
it.findElements(By.xpath("//button[contains(@tooltip,'Delete 
Role')]")).stream())
+                .filter(WebElement::isDisplayed)
+                .findFirst()
+                .orElseThrow(() -> new RuntimeException("No delete button in 
role list"))
+                .click();
+
+        new WebDriverWait(driver, Duration.ofSeconds(10))
+                
.until(ExpectedConditions.elementToBeClickable(deleteConfirmButton));
+
+        deleteConfirmButton.click();
+
+        return this;
+    }
+
+    private void waitForPageLoading() {
+        new WebDriverWait(driver, Duration.ofSeconds(10))
+                .until(ExpectedConditions.urlContains("/system/role"));
+    }
+
+    private void editRoleMenu(String menuName) {
+        createRoleForm.inputMenus.stream()
+                .filter(e -> Objects.equals(
+                        e.findElement(By.xpath(
+                                ".//span[contains(@class, 
'streampark-tree__title') and contains(@class, 'pl-2')]"))
+                                .getText(),
+                        menuName))
+                .findFirst()
+                .orElseThrow(
+                        () -> new RuntimeException(
+                                String.format("No %s in menus checkbox tree", 
menuName)))
+                .findElement(By.className("ant-tree-checkbox-inner"))
+                .click();
+    }
+
+    @Getter
+    public class CreateRoleForm {
+
+        CreateRoleForm() {
+            PageFactory.initElements(driver, this);
+        }
+
+        @FindBy(xpath = 
"//div[@class='scrollbar__view']//*[@id='form_item_roleName']")
+        private WebElement inputRoleName;
+
+        @FindBy(id = "form_item_remark")
+        private WebElement inputDescription;
+
+        @FindBys({
+                @FindBy(className = "ant-tree-list"),
+                @FindBy(className = "ant-tree-treenode")
+        })
+        private List<WebElement> inputMenus;
+
+        @FindBy(xpath = "//button[contains(@class, 
'ant-btn')]//span[contains(., 'Submit')]")
+        private WebElement buttonSubmit;
+
+        @FindBy(xpath = "//button[contains(@class, 
'ant-btn')]//span[contains(., 'Cancel')]")
+        private WebElement buttonCancel;
+    }
+}
diff --git 
a/streampark-e2e/streampark-e2e-case/src/test/java/org/apache/streampark/e2e/pages/system/SystemPage.java
 
b/streampark-e2e/streampark-e2e-case/src/test/java/org/apache/streampark/e2e/pages/system/SystemPage.java
index 2396142b4..b008063a4 100644
--- 
a/streampark-e2e/streampark-e2e-case/src/test/java/org/apache/streampark/e2e/pages/system/SystemPage.java
+++ 
b/streampark-e2e/streampark-e2e-case/src/test/java/org/apache/streampark/e2e/pages/system/SystemPage.java
@@ -68,6 +68,13 @@ public final class SystemPage extends NavBarPage implements 
NavBarItem {
             return tab.cast(new TeamManagementPage(driver));
         }
 
+        if (tab == RoleManagementPage.class) {
+            new WebDriverWait(driver, Duration.ofSeconds(10))
+                    
.until(ExpectedConditions.elementToBeClickable(menuRoleManagement));
+            menuRoleManagement.click();
+            return tab.cast(new RoleManagementPage(driver));
+        }
+
         throw new UnsupportedOperationException("Unknown tab: " + 
tab.getName());
     }
 

Reply via email to