Browse Source

[e2e] Add new test of security environment (#8048)

* [e2e] Add new test of security environment

ref: #7281

* Fix frontend bug

* Fix order of UT

* Fix delete and edit bottom class

* Try to fix

* Try to fix
3.0.0/version-upgrade
Jiajie Zhong 3 years ago committed by GitHub
parent
commit
a061cf136c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/workflows/e2e.yml
  2. 126
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/EnvironmentE2ETest.java
  3. 131
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java
  4. 7
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java
  5. 6
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/environment/_source/createEnvironment.vue
  6. 9
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/environment/_source/list.vue
  7. 2
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/environment/index.vue
  8. 3
      dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js

2
.github/workflows/e2e.yml

@ -79,6 +79,8 @@ jobs:
class: org.apache.dolphinscheduler.e2e.cases.ProjectE2ETest class: org.apache.dolphinscheduler.e2e.cases.ProjectE2ETest
- name: Queue - name: Queue
class: org.apache.dolphinscheduler.e2e.cases.QueueE2ETest class: org.apache.dolphinscheduler.e2e.cases.QueueE2ETest
- name: Environment
class: org.apache.dolphinscheduler.e2e.cases.EnvironmentE2ETest
- name: Workflow - name: Workflow
class: org.apache.dolphinscheduler.e2e.cases.WorkflowE2ETest class: org.apache.dolphinscheduler.e2e.cases.WorkflowE2ETest
- name: FileManage - name: FileManage

126
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/EnvironmentE2ETest.java

@ -0,0 +1,126 @@
/*
* 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.common.NavBarPage;
import org.apache.dolphinscheduler.e2e.pages.security.EnvironmentPage;
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage;
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;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
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 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 RemoteWebDriver browser;
@BeforeAll
public static void setup() {
new LoginPage(browser)
.login("admin", "dolphinscheduler123")
.goToNav(SecurityPage.class)
.goToTab(EnvironmentPage.class)
;
}
@Test
@Order(10)
void testCreateEnvironment() {
final EnvironmentPage page = new EnvironmentPage(browser);
page.create(environmentName, environmentConfig, environmentDesc, environmentWorkerGroup);
await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(page.environmentList())
.as("Environment list should contain newly-created environment")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(environmentName));
});
}
@Test
@Order(20)
void testCreateDuplicateEnvironment() {
final EnvironmentPage page = new EnvironmentPage(browser);
page.create(environmentName, environmentConfig, environmentDesc, environmentWorkerGroup);
await().untilAsserted(() ->
assertThat(browser.findElement(By.tagName("body")).getText())
.contains("already exists")
);
page.createEnvironmentForm().buttonCancel().click();
}
@Test
@Order(30)
void testEditEnvironment() {
final EnvironmentPage page = new EnvironmentPage(browser);
page.update(environmentName, editEnvironmentName, editEnvironmentConfig, editEnvironmentDesc, editEnvironmentWorkerGroup);
await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(page.environmentList())
.as("Environment list should contain newly-modified environment")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(editEnvironmentName));
});
}
@Test
@Order(40)
void testDeleteEnvironment() {
final EnvironmentPage page = new EnvironmentPage(browser);
page.delete(editEnvironmentName);
await().untilAsserted(() -> {
browser.navigate().refresh();
assertThat(
page.environmentList()
).noneMatch(
it -> it.getText().contains(environmentName) || it.getText().contains(editEnvironmentName)
);
});
}
}

131
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.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.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 EnvironmentPage extends NavBarPage implements SecurityPage.Tab {
@FindBy(id = "btnCreateEnvironment")
private WebElement buttonCreateEnvironment;
@FindBy(className = "items")
private List<WebElement> environmentList;
@FindBys({
@FindBy(className = "el-popconfirm"),
@FindBy(className = "el-button--primary"),
})
private List<WebElement> buttonConfirm;
private final EnvironmentForm createEnvironmentForm;
private final EnvironmentForm editEnvironmentForm;
public EnvironmentPage(RemoteWebDriver driver) {
super(driver);
createEnvironmentForm = new EnvironmentForm();
editEnvironmentForm = new EnvironmentForm();
}
public EnvironmentPage create(String name, String config, String desc, String workerGroup) {
buttonCreateEnvironment().click();
createEnvironmentForm().inputEnvironmentName().sendKeys(name);
createEnvironmentForm().inputEnvironmentConfig().sendKeys(config);
createEnvironmentForm().inputEnvironmentDesc().sendKeys(desc);
createEnvironmentForm().inputWorkerGroup().sendKeys(workerGroup);
createEnvironmentForm().buttonSubmit().click();
return this;
}
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))
.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(name);
editEnvironmentForm().inputEnvironmentConfig().sendKeys(config);
editEnvironmentForm().inputEnvironmentDesc().sendKeys(desc);
editEnvironmentForm().inputWorkerGroup().sendKeys(workerGroup);
editEnvironmentForm().buttonSubmit().click();
return this;
}
public EnvironmentPage delete(String name) {
environmentList()
.stream()
.filter(it -> it.getText().contains(name))
.flatMap(it -> it.findElements(By.className("delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.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();
return this;
}
@Getter
public class EnvironmentForm {
EnvironmentForm() {
PageFactory.initElements(driver, this);
}
@FindBy(id = "inputEnvironmentName")
private WebElement inputEnvironmentName;
@FindBy(id = "inputEnvironmentConfig")
private WebElement inputEnvironmentConfig;
@FindBy(id = "inputEnvironmentDesc")
private WebElement inputEnvironmentDesc;
@FindBy(id = "inputEnvironmentWorkerGroup")
private WebElement inputWorkerGroup;
@FindBy(id = "btnSubmit")
private WebElement buttonSubmit;
@FindBy(id = "btnCancel")
private WebElement buttonCancel;
}
}

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

@ -45,6 +45,9 @@ public class SecurityPage extends NavBarPage implements NavBarItem {
@FindBy(className = "tab-queue-manage") @FindBy(className = "tab-queue-manage")
private WebElement menuQueueManage; private WebElement menuQueueManage;
@FindBy(className = "tab-environment-manage")
private WebElement menuEnvironmentManage;
public SecurityPage(RemoteWebDriver driver) { public SecurityPage(RemoteWebDriver driver) {
super(driver); super(driver);
} }
@ -72,6 +75,10 @@ public class SecurityPage extends NavBarPage implements NavBarItem {
menuQueueManage().click(); menuQueueManage().click();
return tab.cast(new QueuePage(driver)); return tab.cast(new QueuePage(driver));
} }
if (tab == EnvironmentPage.class) {
menuEnvironmentManage().click();
return tab.cast(new EnvironmentPage(driver));
}
throw new UnsupportedOperationException("Unknown tab: " + tab.getName()); throw new UnsupportedOperationException("Unknown tab: " + tab.getName());
} }

6
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/environment/_source/createEnvironment.vue

@ -15,13 +15,14 @@
* limitations under the License. * limitations under the License.
*/ */
<template> <template>
<m-popover ref="popover" :ok-text="item && item.name ? $t('Edit') : $t('Submit')" @ok="_ok" @close="close"> <m-popover okId="btnSubmit" cancelId="btnCancel" ref="popover" :ok-text="item && item.name ? $t('Edit') : $t('Submit')" @ok="_ok" @close="close">
<template slot="content"> <template slot="content">
<div class="create-environment-model"> <div class="create-environment-model">
<m-list-box-f> <m-list-box-f>
<template slot="name"><strong>*</strong>{{$t('Environment Name')}}</template> <template slot="name"><strong>*</strong>{{$t('Environment Name')}}</template>
<template slot="content"> <template slot="content">
<el-input <el-input
id="inputEnvironmentName"
type="input" type="input"
v-model="name" v-model="name"
maxlength="60" maxlength="60"
@ -34,6 +35,7 @@
<template slot="name"><strong>*</strong>{{$t('Environment Config')}}</template> <template slot="name"><strong>*</strong>{{$t('Environment Config')}}</template>
<template slot="content"> <template slot="content">
<el-input <el-input
id="inputEnvironmentConfig"
type="textarea" type="textarea"
:autosize="{ minRows: 10, maxRows: 20 }" :autosize="{ minRows: 10, maxRows: 20 }"
v-model="config" v-model="config"
@ -45,6 +47,7 @@
<template slot="name"><strong>*</strong>{{$t('Environment Desc')}}</template> <template slot="name"><strong>*</strong>{{$t('Environment Desc')}}</template>
<template slot="content"> <template slot="content">
<el-input <el-input
id="inputEnvironmentDesc"
type="input" type="input"
v-model="description" v-model="description"
maxlength="60" maxlength="60"
@ -57,6 +60,7 @@
<template slot="name">{{$t('Environment Worker Group')}}</template> <template slot="name">{{$t('Environment Worker Group')}}</template>
<template slot="content"> <template slot="content">
<el-select <el-select
id="inputEnvironmentWorkerGroup"
v-model="workerGroups" v-model="workerGroups"
size="mini" size="mini"
multiple multiple

9
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/environment/_source/list.vue

@ -17,9 +17,9 @@
<template> <template>
<div class="list-model"> <div class="list-model">
<div class="table-box"> <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 type="index" :label="$t('#')" width="50"></el-table-column>
<el-table-column prop="name" :label="$t('Environment Name')" width="150"></el-table-column> <el-table-column prop="name" :label="$t('Environment Name')" width="150" class-name="environmentName"></el-table-column>
<el-table-column prop="config" :label="$t('Environment Config')"></el-table-column> <el-table-column prop="config" :label="$t('Environment Config')"></el-table-column>
<el-table-column prop="description" :label="$t('Environment Desc')" min-width="50"></el-table-column> <el-table-column prop="description" :label="$t('Environment Desc')" min-width="50"></el-table-column>
<el-table-column :label="$t('Environment Worker Group')" min-width="50"> <el-table-column :label="$t('Environment Worker Group')" min-width="50">
@ -40,10 +40,9 @@
<el-table-column :label="$t('Operation')" width="100"> <el-table-column :label="$t('Operation')" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip :content="$t('Edit')" placement="top"> <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>
<el-tooltip :content="$t('Delete')" placement="top"> <el-tooltip :content="$t('Delete')" placement="top">
<el-button type="danger" size="mini" icon="el-icon-delete" circle></el-button>
<el-popconfirm <el-popconfirm
:confirmButtonText="$t('Confirm')" :confirmButtonText="$t('Confirm')"
:cancelButtonText="$t('Cancel')" :cancelButtonText="$t('Cancel')"
@ -52,7 +51,7 @@
:title="$t('Delete?')" :title="$t('Delete?')"
@onConfirm="_delete(scope.row,scope.row.id)" @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-popconfirm>
</el-tooltip> </el-tooltip>
</template> </template>

2
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/environment/index.vue

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

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

@ -154,7 +154,8 @@ const menu = {
isOpen: true, isOpen: true,
enabled: true, enabled: true,
icon: 'el-icon-setting', icon: 'el-icon-setting',
children: [] children: [],
classNames: 'tab-environment-manage'
}, },
{ {
name: `${i18n.$t('Token manage')}`, name: `${i18n.$t('Token manage')}`,

Loading…
Cancel
Save