This is an automated email from the ASF dual-hosted git repository. kezhenxu94 pushed a commit to branch user_e2e in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
commit 4014e804b37f69f7d98712c767c8fd0142fbcf14 Author: chenxingchun <[email protected]> AuthorDate: Tue Dec 21 16:41:59 2021 +0800 add user manage of e2e case --- .../dolphinscheduler/e2e/cases/UserE2ETest.java | 120 +++++++++++++++++ .../e2e/pages/security/SecurityPage.java | 8 ++ .../e2e/pages/security/UserPage.java | 148 +++++++++++++++++++++ .../e2e/core/DolphinSchedulerExtension.java | 8 +- .../security/pages/users/_source/createUser.vue | 6 + .../pages/security/pages/users/_source/list.vue | 6 +- .../conf/home/pages/security/pages/users/index.vue | 2 +- .../components/secondaryMenu/_source/menu.js | 3 +- 8 files changed, 292 insertions(+), 9 deletions(-) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java new file mode 100644 index 0000000..63853d9 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java @@ -0,0 +1,120 @@ +/* + * Licensed to 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. Apache Software Foundation (ASF) licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.dolphinscheduler.e2e.cases; + + +import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.pages.LoginPage; +import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; +import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; +import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; +import org.apache.dolphinscheduler.e2e.pages.security.UserPage; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.remote.RemoteWebDriver; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") +class UserE2ETest { + private static final String tenant = System.getProperty("user.name"); + private static final String user = "test_user"; + private static final String password = "test_user123"; + private static final String email = "[email protected]"; + private static final String phone = "15800000000"; + + private static final String editUser = "edit_test_user"; + private static final String editPassword = "edit_test_user123"; + private static final String editEmail = "[email protected]"; + private static final String editPhone = "15800000001"; + + + private static RemoteWebDriver browser; + + @BeforeAll + public static void setup() { + new LoginPage(browser) + .login("admin","dolphinscheduler123") + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class) + .create(tenant) + .goToNav(SecurityPage.class) + .goToTab(UserPage.class); + } + + @AfterAll + public static void cleanup() { + new NavBarPage(browser) + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class) + .delete(tenant); + } + + @Test + @Order(10) + void testCreateUser() { + final UserPage page = new UserPage(browser); + + page.create(user, password, email, phone); + } + + @Test + @Order(20) + void testCreateDuplicateUser() { + final UserPage page = new UserPage(browser); + + page.create(user, password, email, phone); + + await().untilAsserted(() -> + assertThat(browser.findElement(By.tagName("body")).getText()) + .contains("already exists") + ); + + page.createUserForm().buttonCancel().click(); + } + + @Test + @Order(30) + void testEditUser() { + final UserPage page = new UserPage(browser); + page.editUser(user, editUser, editPassword, editEmail, editPhone); + } + + + @Test + @Order(40) + void testDeleteUser() { + final UserPage page = new UserPage(browser); + page.delete(user); + + await().untilAsserted(() -> { + browser.navigate().refresh(); + assertThat( + page.UserList() + ).noneMatch( + it -> it.getText().contains(user) + ); + }); + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java index 36f960c..389bd2b 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java @@ -33,6 +33,10 @@ public class SecurityPage extends NavBarPage implements NavBarItem { @FindBy(className = "tab-tenant-manage") private WebElement menuTenantManage; + @FindBy(className = "user-manage") + private WebElement menUserManage; + + public SecurityPage(RemoteWebDriver driver) { super(driver); } @@ -42,6 +46,10 @@ public class SecurityPage extends NavBarPage implements NavBarItem { menuTenantManage().click(); return tab.cast(new TenantPage(driver)); } + if (tab == UserPage.class) { + menUserManage().click(); + return tab.cast(new UserPage(driver)); + } throw new UnsupportedOperationException("Unknown tab: " + tab.getName()); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java new file mode 100644 index 0000000..861a91a --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java @@ -0,0 +1,148 @@ +/* + * Licensed to 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. Apache Software Foundation (ASF) licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.dolphinscheduler.e2e.pages.security; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; + +import java.util.List; + +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 lombok.Getter; + +@Getter +public final class UserPage extends NavBarPage implements SecurityPage.Tab { + @FindBy(id = "btnCreateUser") + private WebElement buttonCreateUser; + + @FindBy(id = "btnEditUser") + private WebElement buttonEditUser; + + @FindBy(className = "rows-user") + private List<WebElement> UserList; + + @FindBys({ + @FindBy(className = "el-popconfirm"), + @FindBy(className = "el-button--primary"), + }) + private WebElement buttonConfirm; + + private UserForm createUserForm = new UserForm(); + private UserForm editUserForm = new UserForm(); + + + public UserPage(RemoteWebDriver driver) { + super(driver); + } + + public UserPage create(String user, String password, String email, String phone) { + buttonCreateUser().click(); + + createUserForm().inputUserName().sendKeys(user); + createUserForm().inputUserPassword().sendKeys(password); + createUserForm().inputEmail().sendKeys(email); + createUserForm().inputPhone().sendKeys(phone); + createUserForm().buttonSubmit().click(); + + await().untilAsserted(() -> assertThat(UserList()) + .as("User list should contain newly-created User") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(user))); + + return this; + } + + public UserPage editUser(String user, String editUser, String editPassword, String editEmail, String editPhone) { + UserList() + .stream() + .filter(it -> it.getText().contains(user)) + .findFirst() + .ifPresent(it -> it.findElement(By.className("editUser")).click()); + editUserForm().inputUserName().sendKeys(editUser); + editUserForm().inputUserPassword().sendKeys(editPassword); + editUserForm().inputEmail().sendKeys(editEmail); + editUserForm().inputPhone().sendKeys(editPhone); + editUserForm().buttonSubmit().click(); + + await().untilAsserted(() -> assertThat(UserList()) + .as("User list should contain newly-created User") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(editUser))); + + return this; + } + + public UserPage delete(String user) { + UserList() + .stream() + .filter(it -> it.getText().contains(user)) + .findFirst() + .ifPresent(it -> it.findElement(By.className("deleteUser")).click()); + + buttonConfirm().click(); + + return this; + } + + @Getter + public class UserForm { + UserForm() { + PageFactory.initElements(driver, this); + } + + @FindBy(id = "inputUserName") + private WebElement inputUserName; + + @FindBy(id = "inputUserPassword") + private WebElement inputUserPassword; + + @FindBy(id = "selectTenant") + private WebElement selectTenant; + + @FindBy(id = "selectQueue") + private WebElement selectQueue; + + @FindBy(id = "inputEmail") + private WebElement inputEmail; + + @FindBy(id = "inputPhone") + private WebElement inputPhone; + + @FindBy(id = "radioStateEnable") + private WebElement radioStateEnable; + + @FindBy(id = "radioStateDisable") + private WebElement radioStateDisable; + + @FindBy(id = "btnSubmit") + private WebElement buttonSubmit; + + @FindBy(id = "btnCancel") + private WebElement buttonCancel; + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java index d6b1886..8a28c60 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java @@ -73,8 +73,8 @@ final class DolphinSchedulerExtension @Override @SuppressWarnings("UnstableApiUsage") public void beforeAll(ExtensionContext context) throws IOException { - Awaitility.setDefaultTimeout(Duration.ofSeconds(10)); - Awaitility.setDefaultPollInterval(Duration.ofSeconds(1)); + Awaitility.setDefaultTimeout(Duration.ofSeconds(30)); + Awaitility.setDefaultPollInterval(Duration.ofSeconds(30)); Network network = null; HostAndPort address = null; @@ -127,8 +127,8 @@ final class DolphinSchedulerExtension driver = browser.getWebDriver(); driver.manage().timeouts() - .implicitlyWait(5, TimeUnit.SECONDS) - .pageLoadTimeout(5, TimeUnit.SECONDS); + .implicitlyWait(30, TimeUnit.SECONDS) + .pageLoadTimeout(30, TimeUnit.SECONDS); driver.manage().window() .maximize(); if (address == null) { diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue index 88f69fe..8f3adc0 100644 --- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue +++ b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue @@ -16,6 +16,8 @@ */ <template> <m-popover + okId="btnSubmit" + cancelId="btnCancel" ref="popover" :ok-text="item ? $t('Edit') : $t('Submit')" @ok="_ok" @@ -26,6 +28,7 @@ <template slot="name"><strong>*</strong>{{$t('User Name')}}</template> <template slot="content"> <el-input + id="inputUserName" type="input" v-model="userName" maxlength="60" @@ -38,6 +41,7 @@ <template slot="name"><strong>*</strong>{{$t('Password')}}</template> <template slot="content"> <el-input + id="inputUserPassword" type="password" v-model="userPassword" size="small" @@ -79,6 +83,7 @@ <template slot="name"><strong>*</strong>{{$t('Email')}}</template> <template slot="content"> <el-input + id="inputEmail" type="input" v-model="email" size="small" @@ -90,6 +95,7 @@ <template slot="name">{{$t('Phone')}}</template> <template slot="content"> <el-input + id="inputPhone" type="input" v-model="phone" size="small" diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue index 615cf97..8ce5149 100644 --- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue +++ b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue @@ -17,7 +17,7 @@ <template> <div class="list-model user-list-model"> <div class="table-box"> - <el-table :data="list" size="mini" style="width: 100%"> + <el-table :data="list" size="mini" style="width: 100%" row-class-name="rows-user"> <el-table-column type="index" :label="$t('#')" width="50"></el-table-column> <el-table-column prop="userName" :label="$t('User Name')"></el-table-column> <el-table-column :label="$t('User Type')" width="80"> @@ -62,7 +62,7 @@ </el-dropdown> </el-tooltip> <el-tooltip :content="$t('Edit')" placement="top"> - <el-button type="primary" size="mini" icon="el-icon-edit-outline" @click="_edit(scope.row)" circle></el-button> + <el-button classname="btnEditUser" type="primary" size="mini" icon="el-icon-edit-outline" @click="_edit(scope.row)" circle></el-button> </el-tooltip> <el-tooltip :content="$t('Delete')" placement="top"> <el-popconfirm @@ -73,7 +73,7 @@ :title="$t('Delete?')" @onConfirm="_delete(scope.row,scope.row.id)" > - <el-button type="danger" size="mini" icon="el-icon-delete" circle slot="reference"></el-button> + <el-button className="btnDeleteUser" type="danger" size="mini" icon="el-icon-delete" circle slot="reference" class="delete"></el-button> </el-popconfirm> </el-tooltip> </template> diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/index.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/index.vue index 58bcb86..44f8adc 100644 --- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/index.vue +++ b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/index.vue @@ -19,7 +19,7 @@ <template slot="conditions"> <m-conditions @on-conditions="_onConditions"> <template slot="button-group" v-if="userList.length"> - <el-button size="mini" @click="_create('')">{{$t('Create User')}}</el-button> + <el-button id="btnCreateUser" size="mini" @click="_create('')">{{$t('Create User')}}</el-button> <el-dialog :title="item ? $t('Edit User') : $t('Create User')" v-if="createUserDialog" diff --git a/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js b/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js index 3eb7c9f..927f93e 100644 --- a/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js +++ b/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js @@ -107,7 +107,8 @@ const menu = { isOpen: true, enabled: true, icon: 'el-icon-user-solid', - children: [] + children: [], + classNames: 'user-manage' }, { name: `${i18n.$t('Warning group manage')}`,
