feat(项目设置): UI环境配置校验与提示信息完善

--story=1010692 --user=张大海 【UI测试】支持与环境管理打通 https://www.tapd.cn/55049933/s/1315234
This commit is contained in:
zhangdahai112 2022-12-14 17:51:14 +08:00 committed by zhangdahai112
parent e5a366de15
commit 5e1567b6b4
9 changed files with 183 additions and 105 deletions

View File

@ -3,7 +3,7 @@
<el-col :span="16">
<el-select v-model="selfQuantity" placeholder=" " size="mini" filterable default-first-option
allow-create
class="timing_select" :disabled="selfChoose">
class="timing_select" :disabled="selfChoose" @change="chooseChange(true)">
<el-option
v-for="item in quantityOptions"
:key="item"
@ -12,7 +12,7 @@
</el-option>
</el-select>
<el-select v-model="selfUnit" placeholder=" " size="mini"
class="timing_select" :disabled="selfChoose">
class="timing_select" :disabled="selfChoose" @change="chooseChange(true)">
<el-option
v-for="item in unitOptions"
:key="item.value"
@ -58,6 +58,7 @@ export default {
type: Array,
default() {
return [
{value: "H", label: this.$t('commons.date_unit.hour')},
{value: "D", label: this.$t('commons.date_unit.day')},
{value: "M", label: this.$t('commons.date_unit.month')},
{value: "Y", label: this.$t('commons.date_unit.year')},
@ -66,8 +67,11 @@ export default {
}
},
watch: {
expr(val) {
this.parseExpr(val);
expr: {
handler(val) {
this.parseExpr(val);
},
immediate: true
},
choose(val) {
this.selfChoose = val;

View File

@ -8,9 +8,9 @@
:class="{ 'el-icon-arrow-left pointer' : !active, 'el-icon-arrow-down pointer' : active}"
@click="active=!active"></span>
</el-tooltip>
<template v-if="active">
<div v-show="active">
<slot></slot>
</template>
</div>
</div>
</div>
</template>

View File

@ -84,6 +84,7 @@ export class HttpConfig extends BaseConfig {
this.protocol = 'https';
this.port = undefined;
this.conditions = [];
this.cookie = options.cookie ? options.cookie : [new Cookie()];
this.isMock = false;
this.description = "";
this.set(options);
@ -93,6 +94,7 @@ export class HttpConfig extends BaseConfig {
initOptions(options = {}) {
options.headers = options.headers || [new KeyValue()];
options.cookie = options.cookie || [new Cookie()];
return options;
}
}
@ -111,6 +113,20 @@ export class Host extends BaseConfig {
}
}
export class Cookie extends BaseConfig {
constructor(options = {}) {
super();
this.cookie = undefined;
this.expireTime = "1D";
this.updateTime = undefined;
this.relevanceId = undefined;
this.enable = false;
this.set(options);
}
}
/* ---------- Functions ------- */

View File

@ -136,7 +136,7 @@ import MsTableOperator from "metersphere-frontend/src/components/MsTableOperator
import MsTableOperatorButton from "metersphere-frontend/src/components/MsTableOperatorButton";
import MsTablePagination from "metersphere-frontend/src/components/pagination/TablePagination";
import ApiEnvironmentConfig from "metersphere-frontend/src/components/environment/ApiEnvironmentConfig";
import {Environment, parseEnvironment} from "metersphere-frontend/src/model/EnvironmentModel";
import {Environment, parseEnvironment, HttpConfig} from "metersphere-frontend/src/model/EnvironmentModel";
import EnvironmentEdit from "./components/EnvironmentEdit";
import MsAsideItem from "metersphere-frontend/src/components/MsAsideItem";
import MsAsideContainer from "metersphere-frontend/src/components/MsAsideContainer";
@ -174,7 +174,7 @@ export default {
projectList: [],
condition: {}, //
environments: [],
currentEnvironment: new Environment(),
currentEnvironment: new Environment({httpConfig: new HttpConfig()}),
result: {},
loading: false,
dialogVisible: false,
@ -288,7 +288,7 @@ export default {
createEnv() {
this.dialogTitle = this.$t('api_test.environment.create');
this.dialogVisible = true;
this.currentEnvironment = new Environment();
this.currentEnvironment = new Environment({httpConfig: new HttpConfig()});
this.currentEnvironment.projectId = this.currentProjectId;
this.currentEnvironment.currentProjectId = this.currentProjectId;
this.ifCreate = true;

View File

@ -45,7 +45,7 @@
</el-input>
</div>
<!-- 接口测试配置 -->
<!-- 接口测试配置 -->
<form-section :title="$t('commons.api')" :init-active=true>
<p>{{ $t('api_test.request.headers') }}</p>
<el-row>
@ -71,12 +71,12 @@
</div>
</form-section>
<!-- UI 配置 -->
<form-section :title="$t('commons.ui_test')" :init-active="false">
<!-- UI 配置 -->
<form-section :title="$t('commons.ui_test')" :init-active=false>
<el-row :gutter="10" style="padding-top: 10px;">
<el-col :span="6">
<!-- 浏览器驱动 -->
<span style="margin-right: 10px;">{{$t("ui.browser")}}</span>
<span style="margin-right: 10px;">{{ $t("ui.browser") }}</span>
<el-select
size="mini"
v-model="httpConfig.browser"
@ -104,7 +104,7 @@
<el-row :gutter="10">
<el-col :span="24">
<ms-ui-scenario-cookie-table :items="httpConfig.cookie"/>
<ms-ui-scenario-cookie-table :items="httpConfig.cookie" ref="cookieTable"/>
</el-col>
</el-row>
</form-section>
@ -174,9 +174,10 @@ export default {
name: "MsEnvironmentHttpConfig",
components: {
MsUiScenarioCookieTable,
FormSection, MsApiKeyValue, MsSelectTree, MsTableOperatorButton, BatchAddParameter, MsInstructionsIcon},
FormSection, MsApiKeyValue, MsSelectTree, MsTableOperatorButton, BatchAddParameter, MsInstructionsIcon
},
props: {
httpConfig: new HttpConfig({cookie: []}),
httpConfig: new HttpConfig(),
projectId: String,
isReadOnly: {
type: Boolean,
@ -185,9 +186,6 @@ export default {
},
created() {
this.list();
if (this.httpConfig && !this.httpConfig.cookie) {
this.$set(this.httpConfig, "cookie", []);
}
},
data() {
let socketValidator = (rule, value, callback) => {
@ -220,7 +218,7 @@ export default {
port: 0,
headers: [new KeyValue()],
headlessEnabled: true,
browser : 'CHROME'
browser: 'CHROME'
},
beforeCondition: {},
browsers: [
@ -354,7 +352,7 @@ export default {
list() {
if (this.projectId) {
this.result = getApiModuleByProjectIdAndProtocol(this.projectId, "HTTP").then((response) => {
if (response.data && response.data !== null) {
if (response.data && response.data !== null) {
this.moduleOptions = response.data;
}
});
@ -507,6 +505,9 @@ export default {
this.$refs["httpConfig"].validate((valid) => {
isValidate = valid;
});
if (this.$refs.cookieTable && !this.$refs.cookieTable.validate()) {
return false;
}
return isValidate;
},
batchAdd() {

View File

@ -16,10 +16,10 @@
:data="variables"
:total="items.length"
:screen-height="'100px'"
:batch-operators="batchButtons"
:remember-order="true"
:highlightCurrentRow="true"
@refresh="onChange"
:enable-selection="false"
ref="variableTable"
>
<ms-table-column prop="cookie" label="cookie" min-width="160">
@ -28,44 +28,44 @@
v-model="scope.row.cookie"
size="mini"
:placeholder="$t('cookie')"
@change="change"
@change="change(scope.row)"
/>
</template>
</ms-table-column>
<ms-table-column
prop="userName"
:label="$t('api_test.request.sql.username')"
min-width="200"
>
<template slot-scope="scope">
<el-input
v-model="scope.row.userName"
size="mini"
maxlength="200"
:placeholder="$t('api_test.request.sql.username')"
show-word-limit
@change="change"
/>
</template>
</ms-table-column>
<!-- <ms-table-column-->
<!-- prop="userName"-->
<!-- :label="$t('api_test.request.sql.username')"-->
<!-- min-width="200"-->
<!-- >-->
<!-- <template slot-scope="scope">-->
<!-- <el-input-->
<!-- v-model="scope.row.userName"-->
<!-- size="mini"-->
<!-- maxlength="200"-->
<!-- :placeholder="$t('api_test.request.sql.username')"-->
<!-- show-word-limit-->
<!-- @change="change"-->
<!-- />-->
<!-- </template>-->
<!-- </ms-table-column>-->
<ms-table-column
prop="password"
:label="$t('api_test.request.tcp.password')"
min-width="140"
>
<template slot-scope="scope">
<el-input
v-model="scope.row.password"
size="mini"
maxlength="200"
show-password
:placeholder="$t('api_test.request.tcp.password')"
@change="change"
/>
</template>
</ms-table-column>
<!-- <ms-table-column-->
<!-- prop="password"-->
<!-- :label="$t('api_test.request.tcp.password')"-->
<!-- min-width="140"-->
<!-- >-->
<!-- <template slot-scope="scope">-->
<!-- <el-input-->
<!-- v-model="scope.row.password"-->
<!-- size="mini"-->
<!-- maxlength="200"-->
<!-- show-password-->
<!-- :placeholder="$t('api_test.request.tcp.password')"-->
<!-- @change="change"-->
<!-- />-->
<!-- </template>-->
<!-- </ms-table-column>-->
<ms-table-column
prop="description"
@ -74,7 +74,7 @@
:editContent="'aaa'"
>
<template slot-scope="scope">
<mini-timing-item :expr="scope.row.expireTime"></mini-timing-item>
<mini-timing-item :expr.sync="scope.row.expireTime" @chooseChange="change(scope.row)"></mini-timing-item>
</template>
</ms-table-column>
@ -95,7 +95,8 @@
<el-switch v-model="scope.row.enable" size="mini"></el-switch>
<el-tooltip
effect="dark"
:content="$t('关联登录场景/指令')"
:content="$t('environment.relevance_ui')"
v-if="!existCookieConfig"
placement="top-start"
>
<el-button
@ -103,26 +104,26 @@
circle
size="mini"
@click="openRelevance"
v-if="!existCookieConfig"
style="margin-left: 10px"
/>
</el-tooltip>
<el-dropdown @command="handleCommand" v-if="existCookieConfig">
<el-button
icon="el-icon-paperclip"
circle
size="mini"
style="margin-left: 10px"
/>
<el-dropdown @command="handleCommand" v-if="existCookieConfig">
<el-button
icon="el-icon-paperclip"
circle
size="mini"
style="margin-left: 10px"
/>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="view">{{ $t("environment.view_ui_relevane") }}</el-dropdown-item>
<el-dropdown-item command="cancelRelevance">{{ $t("environment.cancel_ui_relevane") }}
</el-dropdown-item>
<el-dropdown-item command="relevance">{{ $t("environment.re_ui_relevane") }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="view">查看关联</el-dropdown-item>
<el-dropdown-item command="cancelRelevance">取消关联</el-dropdown-item>
<el-dropdown-item command="relevance">重新关联</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-tooltip>
</template>
</ms-table-column>
</ms-table>
@ -158,6 +159,7 @@ import VariableImport from "metersphere-frontend/src/components/environment/Vari
import _ from "lodash";
import MiniTimingItem from "metersphere-frontend/src/components/environment/commons/MiniTimingItem";
import UiScenarioEditRelevance from "@/business/menu/environment/components/ui-related/UiScenarioEditRelevance";
import {getCurrentProjectID, getCurrentWorkspaceId} from "metersphere-frontend/src/utils/token";
export default {
name: "MsUiScenarioCookieTable",
@ -218,8 +220,8 @@ export default {
},
watch: {
items: {
handler(v) {
this.variables = v;
handler(val) {
this.variables = val;
this.sortParameters();
},
immediate: true,
@ -235,7 +237,7 @@ export default {
},
immediate: true,
deep: true,
}
},
},
methods: {
remove: function (index) {
@ -271,6 +273,7 @@ export default {
this.$t("load_test.param_is_duplicate")
);
}
this.variables[0].updateTime = new Date().getTime();
this.$emit("change", this.variables);
},
changeType(data) {
@ -314,23 +317,22 @@ export default {
},
sortParameters() {
let index = 1;
this.variables.forEach((item) => {
item.num = index;
if (!item.type || item.type === "text") {
item.type = "CONSTANT";
}
if (!item.id) {
item.id = getUUID();
}
if (item.remark) {
this.$set(item, "description", item.remark);
item.remark = undefined;
}
if (!item.scope) {
this.$set(item, "scope", "api");
}
index++;
});
if (this.variables) {
this.variables.forEach((item) => {
item.num = index;
if (!item.type || item.type === "text") {
item.type = "CONSTANT";
}
if (!item.id) {
item.id = getUUID();
}
if (item.remark) {
this.$set(item, "description", item.remark);
item.remark = undefined;
}
index++;
});
}
},
handleDeleteBatch() {
operationConfirm(
@ -509,17 +511,36 @@ export default {
handleCommand(c) {
switch (c) {
case "view":
this.redirectPage(this.variables[0].relevanceId);
break;
case "cancelRelevance":
this.variables[0].relevanceId = null;
this.$success(this.$t("organization.integration.successful_operation"));
break;
case "relevance":
this.openRelevance();
this.openRelevance("scenario", "scenario",);
break;
default:
break;
}
},
redirectPage(resourceId) {
let uuid = getUUID().substring(1, 5);
let projectId = getCurrentProjectID();
let workspaceId = getCurrentWorkspaceId();
let prefix = '/#';
if (
this.$route &&
this.$route.path.startsWith('/#')
) {
prefix = '';
}
let path = `/ui/automation/?redirectID=${uuid}&dataType=scenario&projectId=${projectId}&workspaceId=${workspaceId}&resourceId=${resourceId}`;
let data = this.$router.resolve({
path: path,
});
window.open(data.href, '_blank');
},
openRelevance() {
this.$refs.relevanceUiDialog.open();
},
@ -527,19 +548,31 @@ export default {
this.variables[0].relevanceId = id.keys().next().value.id;
this.$refs.relevanceUiDialog.close();
this.$success(this.$t('commons.save_success'));
},
validate() {
if (!this.variables[0].enable) {
return true;
}
let cookieConfig = this.variables[0];
if (!cookieConfig) {
this.$warning(this.$t("配置错误"));
return false;
}
if (!cookieConfig.expireTime || cookieConfig.expireTime === "") {
this.$warning(this.$t("environment.need_expire_time"));
return false;
}
if (!cookieConfig.relevanceId) {
this.$warning(this.$t("environment.need_relevance_ui_scenario"));
return false;
}
return true;
}
},
created() {
if (this.items.length === 0) {
this.items.push(new KeyValue({enable: true, expireTime: '1Y'}));
} else {
// api
_.forEach(this.items, item => {
if (!item.scope) {
this.$set(item, "scope", "api");
}
})
this.variables = this.items;
if (!this.items || this.items.length === 0) {
this.items = [];
this.items.push(new KeyValue({id: getUUID(), enable: true, expireTime: '1M'}));
}
},
};

View File

@ -35,6 +35,15 @@ const message = {
},
project_version: {
version_time: 'Version cycle',
},
environment: {
export_variable_tip : "Export interface test variables",
need_expire_time : "Please enter an expiration time",
need_relevance_ui_scenario : "Please associate the login scenario",
view_ui_relevane : "View Relevane",
cancel_ui_relevane : "Relevant",
re_ui_relevane : "Relevane",
relevance_ui : "Relevance login scene/command",
}
}

View File

@ -37,7 +37,13 @@ const message = {
version_time: '版本周期',
},
environment: {
export_variable_tip : "导出接口测试变量"
export_variable_tip : "导出接口测试变量",
need_expire_time : "请输入过期时间",
need_relevance_ui_scenario : "请关联登录场景",
view_ui_relevane : "查看关联",
cancel_ui_relevane : "取消关联",
re_ui_relevane : "重新关联",
relevance_ui : "关联登录场景/指令",
}
}

View File

@ -35,6 +35,15 @@ const message = {
},
project_version: {
version_time: '版本週期',
},
environment: {
export_variable_tip : "導出接口測試變量",
need_expire_time : "請輸入過期時間",
need_relevance_ui_scenario : "請關聯登錄場景",
view_ui_relevane : "查看關聯",
cancel_ui_relevane : "取消關聯",
re_ui_relevane : "重新關聯",
relevance_ui : "關聯登錄場景/指令",
}
}