Browse Source

[E2E]add worker group manage e2e case (#7879)

* add worker group manage e2e case

* add worker group manage e2e case

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

Co-authored-by: janeHe13 <438044805@qq.com>
Co-authored-by: Jiajie Zhong <zhongjiajie955@gmail.com>
3.0.0/version-upgrade
janeHe13 2 years ago committed by GitHub
parent
commit
0b38d0e826
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/workflows/e2e.yml
  2. 131
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java
  3. 8
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java
  4. 129
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/WorkerGroupPage.java
  5. 5
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/_source/createWorker.vue
  6. 8
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/_source/list.vue
  7. 2
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/index.vue
  8. 3
      dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js

2
.github/workflows/e2e.yml

@ -38,6 +38,8 @@ jobs:
class: org.apache.dolphinscheduler.e2e.cases.TenantE2ETest
- name: User
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: Workflow

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

@ -0,0 +1,131 @@
/*
* 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.security.SecurityPage;
import org.apache.dolphinscheduler.e2e.pages.security.TenantPage;
import org.apache.dolphinscheduler.e2e.pages.security.WorkerGroupPage;
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;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class WorkerGroupE2ETest {
private static final String tenant = System.getProperty("user.name");
private static final String workerGroupName = "test_worker_group";
private static final String editWorkerGroupName = "edit_worker_group";
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(WorkerGroupPage.class);
}
@AfterAll
public static void cleanup() {
new SecurityPage(browser)
.goToTab(TenantPage.class)
.delete(tenant)
;
}
@Test
@Order(1)
void testCreateWorkerGroup() throws InterruptedException {
final WorkerGroupPage page = new WorkerGroupPage(browser);
page.create(workerGroupName);
await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(page.workerGroupList())
.as("workerGroup list should contain newly-created workerGroup")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(workerGroupName));
});
}
@Test
@Order(20)
void testCreateDuplicateWorkerGroup() throws InterruptedException {
final WorkerGroupPage page = new WorkerGroupPage(browser);
page.create(workerGroupName);
await().untilAsserted(() ->
assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists")
);
page.createWorkerForm().buttonCancel().click();
}
@Test
@Order(30)
void testEditWorkerGroup() {
final WorkerGroupPage page = new WorkerGroupPage(browser);
page.update(workerGroupName, editWorkerGroupName);
await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(page.workerGroupList())
.as("workerGroup list should contain newly-modified workerGroup")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(editWorkerGroupName));
});
}
@Test
@Order(40)
void testDeleteWorkerGroup() {
final WorkerGroupPage page = new WorkerGroupPage(browser);
page.delete(editWorkerGroupName);
await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(
page.workerGroupList()
).noneMatch(
it -> it.getText().contains(workerGroupName) || it.getText().contains(editWorkerGroupName)
);
});
}
}

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

@ -36,6 +36,9 @@ public class SecurityPage extends NavBarPage implements NavBarItem {
@FindBy(className = "tab-user-manage")
private WebElement menUserManage;
@FindBy(className = "tab-worker-group-manage")
private WebElement menWorkerGroupManage;
public SecurityPage(RemoteWebDriver driver) {
super(driver);
@ -50,7 +53,10 @@ public class SecurityPage extends NavBarPage implements NavBarItem {
menUserManage().click();
return tab.cast(new UserPage(driver));
}
if (tab == WorkerGroupPage.class) {
menWorkerGroupManage().click();
return tab.cast(new WorkerGroupPage(driver));
}
throw new UnsupportedOperationException("Unknown tab: " + tab.getName());
}

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

@ -0,0 +1,129 @@
/*
* 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 lombok.Getter;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
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 java.util.List;
@Getter
public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(id = "btnCreateWorkerGroup")
private WebElement buttonCreateWorkerGroup;
@FindBy(className = "items")
private List<WebElement> workerGroupList;
@FindBys({
@FindBy(className = "el-popconfirm"),
@FindBy(className = "el-button--primary"),
})
private List<WebElement> buttonConfirm;
private final WorkerGroupForm createWorkerForm = new WorkerGroupForm();
private final WorkerGroupForm editWorkerForm = new WorkerGroupForm();
public WorkerGroupPage(RemoteWebDriver driver) {
super(driver);
}
public WorkerGroupPage create(String workerGroupName) {
buttonCreateWorkerGroup().click();
createWorkerForm().inputWorkerGroupName().sendKeys(workerGroupName);
createWorkerForm().selectWorkerAddress().click();
createWorkerForm().workerAddressList().click();
createWorkerForm().buttonSubmit().click();
return this;
}
public WorkerGroupPage update(String workerGroupName, String editWorkerGroupName) {
workerGroupList()
.stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(workerGroupName))
.flatMap(it -> it.findElements(By.className("edit")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in workerGroup list"))
.click();
editWorkerForm().inputWorkerGroupName().clear();
editWorkerForm().inputWorkerGroupName().sendKeys(editWorkerGroupName);
editWorkerForm().buttonSubmit().click();
return this;
}
public WorkerGroupPage delete(String Worker) {
workerGroupList()
.stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(Worker))
.flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.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();
return this;
}
@Getter
public class WorkerGroupForm {
WorkerGroupForm() {
PageFactory.initElements(driver, this);
}
@FindBy(id = "inputWorkerGroupName")
private WebElement inputWorkerGroupName;
@FindBy(id = "selectWorkerAddress")
private WebElement selectWorkerAddress;
@FindBy(className = "vue-treeselect__menu")
private WebElement workerAddressList;
@FindBy(id = "btnSubmit")
private WebElement buttonSubmit;
@FindBy(id = "btnCancel")
private WebElement buttonCancel;
}
}

5
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/_source/createWorker.vue

@ -16,6 +16,8 @@
*/
<template>
<m-popover
okId="btnSubmit"
cancelId="btnCancel"
ref="popover"
:ok-text="item ? $t('Edit') : $t('Submit')"
@ok="_ok"
@ -27,6 +29,7 @@
<template slot="name"><strong>*</strong>{{$t('Group Name')}}</template>
<template slot="content">
<el-input
id="inputWorkerGroupName"
type="input"
v-model="name"
maxlength="60"
@ -38,7 +41,7 @@
<m-list-box-f>
<template slot="name"><strong>*</strong>{{$t('Worker Addresses')}}</template>
<template slot="content">
<treeselect :options="this.workerAddressList" v-model="addrList" :multiple="true" :placeholder="$t('Please select the worker addresses')"></treeselect>
<treeselect id="selectWorkerAddress" :options="this.workerAddressList" v-model="addrList" :multiple="true" :placeholder="$t('Please select the worker addresses')"></treeselect>
</template>
</m-list-box-f>
</div>

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

@ -17,9 +17,9 @@
<template>
<div class="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="name" :label="$t('Group')"></el-table-column>
<el-table-column prop="name" :label="$t('Group')" class-name="name"></el-table-column>
<el-table-column :label="$t('Addresses')" min-width="300">
<template slot-scope="scope">
<span style="display: inline-block; margin-right: 10px">{{scope.row.addrList}}</span>
@ -38,7 +38,7 @@
<el-table-column :label="$t('Operation')" width="100">
<template slot-scope="scope">
<el-tooltip :content="$t('Edit')" placement="top" v-if="!scope.row.systemDefault">
<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" v-if="!scope.row.systemDefault">
<el-popconfirm
@ -49,7 +49,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/workerGroups/index.vue

@ -19,7 +19,7 @@
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group" v-if="isADMIN">
<el-button size="mini" @click="_create('')">{{$t('Create worker group')}}</el-button>
<el-button id="btnCreateWorkerGroup" size="mini" @click="_create('')">{{$t('Create worker group')}}</el-button>
<el-dialog
:title="item ? $t('Edit worker group') : $t('Create worker group')"
v-if="createWorkerGroupDialog"

3
dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js

@ -134,7 +134,8 @@ const menu = {
isOpen: true,
enabled: true,
icon: 'el-icon-s-custom',
children: []
children: [],
classNames: 'tab-worker-group-manage'
},
{
name: `${i18n.$t('Queue manage')}`,

Loading…
Cancel
Save