Browse Source

Add E2E case for user manage (#7652)

3.0.0/version-upgrade
kezhenxu94 2 years ago committed by GitHub
parent
commit
269a62418f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/workflows/e2e.yml
  2. 10
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TenantE2ETest.java
  3. 139
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java
  4. 8
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java
  5. 8
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java
  6. 148
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java
  7. 4
      dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java
  8. 6
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue
  9. 8
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue
  10. 2
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/index.vue
  11. 3
      dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js

2
.github/workflows/e2e.yml

@ -42,6 +42,8 @@ jobs:
case:
- name: Tenant
class: org.apache.dolphinscheduler.e2e.cases.TenantE2ETest
- name: User
class: org.apache.dolphinscheduler.e2e.cases.UserE2ETest
- name: Project
class: org.apache.dolphinscheduler.e2e.cases.ProjectE2ETest
- name: Workflow

10
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TenantE2ETest.java

@ -32,6 +32,7 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
@ -52,7 +53,13 @@ class TenantE2ETest {
@Test
@Order(10)
void testCreateTenant() {
new TenantPage(browser).create(tenant);
final TenantPage page = new TenantPage(browser);
page.create(tenant);
await().untilAsserted(() -> assertThat(page.tenantList())
.as("Tenant list should contain newly-created tenant")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant)));
}
@Test
@ -78,6 +85,7 @@ class TenantE2ETest {
await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(
page.tenantList()
).noneMatch(

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

@ -0,0 +1,139 @@
/*
* 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 static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage;
import org.apache.dolphinscheduler.e2e.pages.security.TenantPage;
import org.apache.dolphinscheduler.e2e.pages.security.UserPage;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
@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 = "test_user@gmail.com";
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 = "edit_test_user@gmail.com";
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 SecurityPage(browser)
.goToTab(TenantPage.class)
.delete(tenant)
;
}
@Test
@Order(1)
void testCreateUser() {
final UserPage page = new UserPage(browser);
page.create(user, password, email, phone);
await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(page.userList())
.as("User list should contain newly-created user")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(user));
});
}
@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.update(user, editUser, editPassword, editEmail, editPhone);
await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(page.userList())
.as("User list should contain newly-modified User")
.extracting(WebElement::getText)
.anyMatch(it -> it.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)
);
});
}
}

8
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 = "tab-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());
}

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

@ -19,9 +19,6 @@
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;
@ -67,11 +64,6 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab {
createTenantForm().inputDescription().sendKeys(description);
createTenantForm().buttonSubmit().click();
await().untilAsserted(() -> assertThat(tenantList())
.as("Tenant list should contain newly-created tenant")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(tenant)));
return this;
}

148
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 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(className = "items")
private List<WebElement> userList;
@FindBys({
@FindBy(className = "el-popconfirm"),
@FindBy(className = "el-button--primary"),
})
private List<WebElement> buttonConfirm;
private final UserForm createUserForm = new UserForm();
private final 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();
return this;
}
public UserPage update(String user, String editUser, String editPassword, String editEmail, String editPhone) {
userList()
.stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user))
.flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in user list"))
.click();
editUserForm().inputUserName().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();
return this;
}
public UserPage delete(String user) {
userList()
.stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user))
.flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in user list"))
.click();
buttonConfirm()
.stream()
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No confirm button when deleting"))
.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;
}
}

4
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(60));
Awaitility.setDefaultPollInterval(Duration.ofSeconds(10));
Network network = null;
HostAndPort address = null;

6
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"

8
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue

@ -17,9 +17,9 @@
<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="items">
<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 prop="userName" :label="$t('User Name')" class-name="name"></el-table-column>
<el-table-column :label="$t('User Type')" width="80">
<template slot-scope="scope">
{{scope.row.userType === 'GENERAL_USER' ? `${$t('Ordinary users')}` : `${$t('Administrator')}`}}
@ -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 type="primary" size="mini" icon="el-icon-edit-outline" @click="_edit(scope.row)" circle class="edit"></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 type="danger" size="mini" icon="el-icon-delete" circle slot="reference" class="delete"></el-button>
</el-popconfirm>
</el-tooltip>
</template>

2
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"

3
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: 'tab-user-manage'
},
{
name: `${i18n.$t('Warning group manage')}`,

Loading…
Cancel
Save