fix(测试计划): 调整执行测试计划中运行配置页面布局

--bug=1015041 --user=刘瑶 【测试计划】执行测试计划页面样式优化 https://www.tapd.cn/55049933/s/1211843
This commit is contained in:
nathan.liu 2022-07-26 14:32:08 +08:00 committed by nathanliu2022
parent fa7e599b77
commit 3c86b14de3
8 changed files with 359 additions and 272 deletions

View File

@ -9,7 +9,7 @@
<span style="margin-left: 8px;">{{$t('workspace.env_group.name')}}</span> <span style="margin-left: 8px;">{{$t('workspace.env_group.name')}}</span>
<i class="el-icon-view icon-view-btn" @click="viewGroup"></i> <i class="el-icon-view icon-view-btn" @click="viewGroup"></i>
</div> </div>
<el-button type="primary" @click="handleConfirm" size="small" class="env-confirm">{{$t('workspace.env_group.confirm')}}</el-button> <el-button type="primary" @click="handleConfirm" size="small" :style="btnStyle" class="env-confirm">{{$t('workspace.env_group.confirm')}}</el-button>
<el-dialog :visible="visble" append-to-body :title="$t('workspace.env_group.name')" @close="visble = false" style="height: 800px;"> <el-dialog :visible="visble" append-to-body :title="$t('workspace.env_group.name')" @close="visble = false" style="height: 800px;">
<template> <template>
<environment-group style="overflow-y: auto;" <environment-group style="overflow-y: auto;"
@ -42,6 +42,12 @@ export default {
} }
}, },
projectIds: Set, projectIds: Set,
btnStyle: {
type: Object,
default() {
return {width: "360px"}
}
}
}, },
watch: { watch: {
groupId(val) { groupId(val) {

View File

@ -2,7 +2,7 @@
<el-popover <el-popover
v-model="visible" v-model="visible"
:placement="placement" :placement="placement"
width="400" :width="width"
:disabled="isReadOnly" :disabled="isReadOnly"
@show="showPopover" @show="showPopover"
trigger="click"> trigger="click">
@ -18,10 +18,11 @@
@close="visible = false" @close="visible = false"
@setProjectEnvMap="setProjectEnvMap" @setProjectEnvMap="setProjectEnvMap"
v-show="!radio || radio === ENV_TYPE.JSON" v-show="!radio || radio === ENV_TYPE.JSON"
:btnStyle="btnStyle"
ref="envSelect"/> ref="envSelect"/>
<env-group ref="envGroup" v-show="radio === ENV_TYPE.GROUP && !hasOptionGroup" @close="visible = false" <env-group ref="envGroup" v-show="radio === ENV_TYPE.GROUP && !hasOptionGroup" @close="visible = false"
:project-ids="projectIds" :project-ids="projectIds"
@setEnvGroup="setEnvGroup" :group-id="groupId"></env-group> @setEnvGroup="setEnvGroup" :group-id="groupId" :btnStyle="btnStyle"></env-group>
<!-- 对环境组选项进行分类 可用不可用 --> <!-- 对环境组选项进行分类 可用不可用 -->
<env-group-with-option ref="envOptionGroup" v-show="radio === ENV_TYPE.GROUP && hasOptionGroup" <env-group-with-option ref="envOptionGroup" v-show="radio === ENV_TYPE.GROUP && hasOptionGroup"
@close="visible = false" @close="visible = false"
@ -44,6 +45,10 @@ export default {
name: "EnvPopover", name: "EnvPopover",
components: {EnvGroup, EnvSelect, EnvGroupWithOption}, components: {EnvGroup, EnvSelect, EnvGroupWithOption},
props: { props: {
width:{
type: String,
default: "400"
},
envMap: Map, envMap: Map,
projectIds: Set, projectIds: Set,
projectList: Array, projectList: Array,
@ -95,6 +100,12 @@ export default {
default() { default() {
return false; return false;
} }
},
btnStyle: {
type: Object,
default() {
return {width: "360px"}
}
} }
}, },
data() { data() {

View File

@ -23,7 +23,7 @@
</span> </span>
</div> </div>
<el-button type="primary" @click="handleConfirm" size="small" class="env-confirm">{{$t('workspace.env_group.confirm')}}</el-button> <el-button type="primary" @click="handleConfirm" size="small" :style="btnStyle" class="env-confirm">{{$t('workspace.env_group.confirm')}}</el-button>
<!-- 环境配置 --> <!-- 环境配置 -->
<api-environment-config ref="environmentConfig" @close="environmentConfigClose"/> <api-environment-config ref="environmentConfig" @close="environmentConfigClose"/>
@ -52,6 +52,12 @@ export default {
default() { default() {
return {loading: false} return {loading: false}
} }
},
btnStyle: {
type: Object,
default() {
return {width: "360px"}
}
} }
}, },
data() { data() {

View File

@ -6,326 +6,387 @@
@close="close" @close="close"
:visible.sync="runModeVisible" :visible.sync="runModeVisible"
> >
<div style="margin-bottom: 10px;"> <div class="env-container">
<span class="ms-mode-span">{{ $t("commons.environment") }}</span> <div class="run-env-row wrap">
<env-popover :project-ids="projectIds" <div class="title">{{ $t("commons.environment") }}</div>
:placement="'bottom-start'" <div class="content">
:project-list="projectList" <env-popover
:project-env-map="projectEnvListMap" :project-ids="projectIds"
:environment-type.sync="runConfig.environmentType" :placement="'bottom-start'"
:group-id="runConfig.environmentGroupId" :project-list="projectList"
@setEnvGroup="setEnvGroup" :project-env-map="projectEnvListMap"
@setProjectEnvMap="setProjectEnvMap" :environment-type.sync="runConfig.environmentType"
@showPopover="showPopover" :group-id="runConfig.environmentGroupId"
ref="envPopover" class="env-popover"/> @setEnvGroup="setEnvGroup"
</div> @setProjectEnvMap="setProjectEnvMap"
@showPopover="showPopover"
<div style="margin-bottom: 10px;" v-if="haveUICase"> width="300"
<span class="ms-mode-span">{{ $t("浏览器") }}</span> ref="envPopover"
<el-select :btnStyle="btnStyle"
size="mini" class="env-popover"
v-model="runConfig.browser" />
style="margin-right: 30px; width: 100px" </div>
> </div>
<el-option <div class="browser-row wrap">
v-for="b in browsers" <div class="title">{{ $t("ui.browser") }}</div>
:key="b.value" <div class="content">
:value="b.value" <el-select
:label="b.label" size="mini"
></el-option> v-model="runConfig.browser"
</el-select> style="margin-right: 30px; width: 100%"
</div> >
<el-option
<div> v-for="b in browsers"
<span class="ms-mode-span">{{ $t("run_mode.title") }}</span> :key="b.value"
<el-radio-group v-model="runConfig.mode" @change="changeMode"> :value="b.value"
<el-radio label="serial">{{ $t("run_mode.serial") }}</el-radio> :label="b.label"
<el-radio label="parallel">{{ $t("run_mode.parallel") }}</el-radio> ></el-option>
</el-radio-group> </el-select>
</div> </div>
<div class="ms-mode-div" v-if="runConfig.mode === 'serial'"> </div>
<el-row> <div class="mode-row wrap">
<el-col :span="6"> <div class="title">{{ $t("run_mode.title") }}</div>
<span class="ms-mode-pan">{{ $t("run_mode.other_config") }}</span> <div class="content">
</el-col> <el-radio-group
<el-col :span="18"> v-model="runConfig.mode"
<div v-if="testType === 'API'"> @change="changeMode"
<el-checkbox v-model="runConfig.runWithinResourcePool" style="padding-right: 10px;"> style="width: 100%"
{{ $t('run_mode.run_with_resource_pool') }} >
<el-radio label="serial">{{ $t("run_mode.serial") }}</el-radio>
<el-radio label="parallel">{{ $t("run_mode.parallel") }}</el-radio>
</el-radio-group>
</div>
</div>
<div class="other-row wrap">
<div class="title other-title">{{ $t("run_mode.other_config") }}</div>
<div class="other-content">
<!-- 串行 -->
<div
class="mode-row"
v-if="runConfig.mode === 'serial' && testType === 'API'"
>
<el-checkbox
v-model="runConfig.runWithinResourcePool"
style="padding-right: 10px"
>
{{ $t("run_mode.run_with_resource_pool") }}
</el-checkbox> </el-checkbox>
<el-select :disabled="!runConfig.runWithinResourcePool" v-model="runConfig.resourcePoolId" size="mini"> <el-select
:disabled="!runConfig.runWithinResourcePool"
v-model="runConfig.resourcePoolId"
size="mini"
style="width: 135px; margin-left: 10px"
>
<el-option <el-option
v-for="item in resourcePools" v-for="item in resourcePools"
:key="item.id" :key="item.id"
:label="item.name" :label="item.name"
:value="item.id"> :value="item.id"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
</el-col> <!-- 并行 -->
</el-row> <div
</div> class="mode-row"
<div class="ms-mode-div" v-if="runConfig.mode === 'parallel'"> v-if="runConfig.mode === 'parallel' && testType === 'API'"
<el-row> >
<el-col :span="6"> <el-checkbox
<span class="ms-mode-span">{{ $t("run_mode.other_config") }}</span> v-model="runConfig.runWithinResourcePool"
</el-col> style="padding-right: 10px"
<el-col :span="18"> >
<div v-if="testType === 'API'"> {{ $t("run_mode.run_with_resource_pool") }}
<el-checkbox v-model="runConfig.runWithinResourcePool" style="padding-right: 10px;">
{{ $t('run_mode.run_with_resource_pool') }}
</el-checkbox> </el-checkbox>
<el-select :disabled="!runConfig.runWithinResourcePool" v-model="runConfig.resourcePoolId" size="mini"> <el-select
:disabled="!runConfig.runWithinResourcePool"
v-model="runConfig.resourcePoolId"
size="mini"
style="width: 135px; margin-left: 10px"
>
<el-option <el-option
v-for="item in resourcePools" v-for="item in resourcePools"
:key="item.id" :key="item.id"
:label="item.name" :label="item.name"
:disabled="!item.api" :disabled="!item.api"
:value="item.id"> :value="item.id"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
</el-col>
</el-row>
</div>
<!-- 失败重试 -->
<div class="ms-failure-div" v-if="isHasLicense">
<el-row>
<el-col :span="6">
<span class="ms-mode-span">&nbsp;</span>
</el-col>
<el-col :span="18">
<el-checkbox v-model="runConfig.retryEnable" class="ms-failure-div-right">
{{ $t('run_mode.retry_on_failure') }}
</el-checkbox>
<span v-if="runConfig.retryEnable">
<el-tooltip placement="top">
<div slot="content">{{ $t('run_mode.retry_message') }}</div>
<i class="el-icon-question" style="cursor: pointer"/>
</el-tooltip>
<span>
{{ $t('run_mode.retry') }}
<el-input-number :value="runConfig.retryNum" v-model="runConfig.retryNum" :min="1" :max="10000000"
size="mini"/>
&nbsp;
{{ $t('run_mode.retry_frequency') }}
</span>
</span>
</el-col>
</el-row>
</div>
<div class="ms-failure-div" v-if="runConfig.mode === 'serial'">
<el-row>
<el-col :span="18" :offset="6">
<div>
<el-checkbox v-model="runConfig.onSampleError">{{ $t("api_test.fail_to_stop") }}</el-checkbox>
</div>
</el-col>
</el-row>
</div>
<div> <!-- 失败重试 -->
<el-row> <div class="mode-row" v-if="isHasLicense">
<el-col :span="18" :offset="6"> <el-checkbox
<div style="margin-top: 10px" v-if="haveUICase"> v-model="runConfig.retryEnable"
class="ms-failure-div-right"
>
{{ $t("run_mode.retry_on_failure") }}
</el-checkbox>
<span v-if="runConfig.retryEnable">
<el-tooltip placement="top" style="margin: 0 4px 0 2px">
<div slot="content">{{ $t("run_mode.retry_message") }}</div>
<i class="el-icon-question" style="cursor: pointer" />
</el-tooltip>
<span style="margin-left: 10px">
{{ $t("run_mode.retry") }}
<el-input-number
:value="runConfig.retryNum"
v-model="runConfig.retryNum"
:min="1"
:max="10000000"
size="mini"
style="width: 103px"
/>
&nbsp;
{{ $t("run_mode.retry_frequency") }}
</span>
</span>
</div>
<div class="mode-row" v-if="runConfig.mode === 'serial'">
<el-checkbox v-model="runConfig.onSampleError">{{
$t("api_test.fail_to_stop")
}}</el-checkbox>
</div>
<div class="mode-row" v-if="haveUICase">
<el-checkbox v-model="runConfig.headlessEnabled"> <el-checkbox v-model="runConfig.headlessEnabled">
{{ $t("性能模式") }} {{ $t("ui.performance_mode") }}
</el-checkbox> </el-checkbox>
</div> </div>
</el-col> </div>
</el-row> </div>
</div> </div>
<template v-slot:footer> <template v-slot:footer>
<div class="dialog-footer" v-if="showSave"> <div class="dialog-footer" v-if="showSave">
<el-button @click="close">{{ $t('commons.cancel') }}</el-button> <el-button @click="close">{{ $t("commons.cancel") }}</el-button>
<el-dropdown @command="handleCommand" style="margin-left: 5px"> <el-dropdown @command="handleCommand" style="margin-left: 5px">
<el-button type="primary"> <el-button type="primary">
{{ $t('load_test.save_and_run') }}<i class="el-icon-arrow-down el-icon--right"></i> {{ $t("load_test.save_and_run")
}}<i class="el-icon-arrow-down el-icon--right"></i>
</el-button> </el-button>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item command="run">{{ $t('load_test.save_and_run') }}</el-dropdown-item> <el-dropdown-item command="run">{{
<el-dropdown-item command="save">{{$t('commons.save')}}</el-dropdown-item> $t("load_test.save_and_run")
}}</el-dropdown-item>
<el-dropdown-item command="save">{{
$t("commons.save")
}}</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
</div> </div>
<ms-dialog-footer v-else @cancel="close" @confirm="handleRunBatch"/> <ms-dialog-footer v-else @cancel="close" @confirm="handleRunBatch" />
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script> <script>
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter"; import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
import EnvPopover from "@/business/components/api/automation/scenario/EnvPopover"; import EnvPopover from "@/business/components/api/automation/scenario/EnvPopover";
import {strMapToObj} from "@/common/js/utils"; import { strMapToObj } from "@/common/js/utils";
import {ENV_TYPE} from "@/common/js/constants"; import { ENV_TYPE } from "@/common/js/constants";
import {hasLicense} from "@/common/js/utils"; import { hasLicense } from "@/common/js/utils";
export default { export default {
name: "MsPlanRunModeWithEnv", name: "MsPlanRunModeWithEnv",
components: {EnvPopover, MsDialogFooter}, components: { EnvPopover, MsDialogFooter },
data() { data() {
return { return {
runModeVisible: false, btnStyle: {
testType: null, width: "260px",
resourcePools: [], },
runConfig: { runModeVisible: false,
mode: "serial", testType: null,
reportType: "iddReport", resourcePools: [],
onSampleError: false, runConfig: {
runWithinResourcePool: false, mode: "serial",
resourcePoolId: null, reportType: "iddReport",
envMap: new Map(), onSampleError: false,
environmentGroupId: "", runWithinResourcePool: false,
environmentType: ENV_TYPE.JSON, resourcePoolId: null,
retryEnable: false, envMap: new Map(),
retryNum: 1, environmentGroupId: "",
browser: "CHROME" environmentType: ENV_TYPE.JSON,
retryEnable: false,
retryNum: 1,
browser: "CHROME",
},
isHasLicense: hasLicense(),
projectEnvListMap: {},
projectList: [],
projectIds: new Set(),
options: [
{
value: "confirmAndRun",
label: this.$t("load_test.save_and_run"),
}, },
isHasLicense: hasLicense(), {
projectEnvListMap: {}, value: "save",
projectList: [], label: this.$t("commons.save"),
projectIds: new Set(), },
options: [{ ],
value: 'confirmAndRun', value: "confirmAndRun",
label: this.$t('load_test.save_and_run') browsers: [
}, { {
value: 'save', label: this.$t("chrome"),
label: this.$t('commons.save') value: "CHROME",
}], },
value: 'confirmAndRun', {
browsers: [ label: this.$t("firefox"),
{ value: "FIREFOX",
label: this.$t("chrome"), },
value: "CHROME", ],
}, };
{ },
label: this.$t("firefox"), props: {
value: "FIREFOX", planCaseIds: {
} type: Array,
], },
type: String,
planId: String,
showSave: {
type: Boolean,
default: false,
},
//ui ui
haveUICase: {
type: Boolean,
default: false,
},
},
methods: {
open(testType) {
this.runModeVisible = true;
this.testType = testType;
this.getResourcePools();
this.getWsProjects();
},
changeMode() {
this.runConfig.onSampleError = false;
this.runConfig.runWithinResourcePool = false;
this.runConfig.resourcePoolId = null;
},
close() {
this.runConfig = {
mode: "serial",
reportType: "iddReport",
onSampleError: false,
runWithinResourcePool: false,
resourcePoolId: null,
envMap: new Map(),
environmentGroupId: "",
environmentType: ENV_TYPE.JSON,
browser: "CHROME",
}; };
this.runModeVisible = false;
this.$emit("close");
}, },
props: { handleRunBatch() {
planCaseIds: { this.$emit("handleRunBatch", this.runConfig);
type: Array, this.close();
},
type: String,
planId: String,
showSave: {
type: Boolean,
default: false
},
//ui ui
haveUICase: {
type: Boolean,
default: false
}
}, },
methods: { getResourcePools() {
open(testType) { this.result = this.$get(
this.runModeVisible = true; "/testresourcepool/list/quota/valid",
this.testType = testType; (response) => {
this.getResourcePools();
this.getWsProjects();
},
changeMode() {
this.runConfig.onSampleError = false;
this.runConfig.runWithinResourcePool = false;
this.runConfig.resourcePoolId = null;
},
close() {
this.runConfig = {
mode: "serial",
reportType: "iddReport",
onSampleError: false,
runWithinResourcePool: false,
resourcePoolId: null,
envMap: new Map(),
environmentGroupId: "",
environmentType: ENV_TYPE.JSON,
browser: "CHROME"
};
this.runModeVisible = false;
this.$emit('close');
},
handleRunBatch() {
this.$emit("handleRunBatch", this.runConfig);
this.close();
},
getResourcePools() {
this.result = this.$get('/testresourcepool/list/quota/valid', response => {
this.resourcePools = response.data; this.resourcePools = response.data;
});
},
setProjectEnvMap(projectEnvMap) {
this.runConfig.envMap = strMapToObj(projectEnvMap);
},
setEnvGroup(id) {
this.runConfig.environmentGroupId = id;
},
getWsProjects() {
this.$get("/project/getOwnerProjects", res => {
this.projectList = res.data;
})
},
showPopover() {
this.projectIds.clear();
let param = undefined;
let url = "";
if (this.type === 'apiCase') {
url = '/test/plan/api/case/env';
param = this.planCaseIds;
} else if (this.type === 'apiScenario') {
url = '/test/plan/api/scenario/env';
param = this.planCaseIds;
} else if (this.type === 'plan') {
url = '/test/plan/case/env';
param = {id: this.planId};
} }
this.$post(url, param, res => { );
let data = res.data; },
if (data) { setProjectEnvMap(projectEnvMap) {
this.projectEnvListMap = data; this.runConfig.envMap = strMapToObj(projectEnvMap);
for (let d in data) { },
this.projectIds.add(d); setEnvGroup(id) {
} this.runConfig.environmentGroupId = id;
},
getWsProjects() {
this.$get("/project/getOwnerProjects", (res) => {
this.projectList = res.data;
});
},
showPopover() {
this.projectIds.clear();
let param = undefined;
let url = "";
if (this.type === "apiCase") {
url = "/test/plan/api/case/env";
param = this.planCaseIds;
} else if (this.type === "apiScenario") {
url = "/test/plan/api/scenario/env";
param = this.planCaseIds;
} else if (this.type === "plan") {
url = "/test/plan/case/env";
param = { id: this.planId };
}
this.$post(url, param, (res) => {
let data = res.data;
if (data) {
this.projectEnvListMap = data;
for (let d in data) {
this.projectIds.add(d);
} }
this.$refs.envPopover.openEnvSelect();
});
},
handleCommand(command) {
if (this.runConfig.runWithinResourcePool && this.runConfig.resourcePoolId == null) {
this.$warning(this.$t('workspace.env_group.please_select_run_within_resource_pool'));
return;
}
if (command === 'run') {
this.runConfig.isRun = true
this.handleRunBatch();
} else {
this.runConfig.isRun = false
this.handleRunBatch();
} }
this.$refs.envPopover.openEnvSelect();
});
},
handleCommand(command) {
if (
this.runConfig.runWithinResourcePool &&
this.runConfig.resourcePoolId == null
) {
this.$warning(
this.$t("workspace.env_group.please_select_run_within_resource_pool")
);
return;
}
if (command === "run") {
this.runConfig.isRun = true;
this.handleRunBatch();
} else {
this.runConfig.isRun = false;
this.handleRunBatch();
} }
}, },
}; },
};
</script> </script>
<style scoped> <style scoped>
.ms-mode-span { .env-container .title {
margin-right: 10px; width: 100px;
} min-width: 100px;
text-align: right;
padding-right: 10px;
}
.env-container .content {
width: 163px;
}
.ms-mode-div { .wrap {
margin-top: 20px; display: flex;
} align-items: center;
padding: 5px 10px 5px 10px;
}
.ms-failure-div { /deep/.content .el-popover__reference {
margin-top: 10px; width: 100%;
} }
.ms-failure-div-right { .mode-row {
padding-right: 10px; margin-top: 10px;
} }
.other-title {
height: 100%;
margin-top: 25px;
align-items: flex-start;
}
.other-content {
height: 100%;
}
.other-row {
height: 125px;
}
</style> </style>

@ -1 +1 @@
Subproject commit 298d8ad3fa5f305cb8c70dd01bc26aea01d2f099 Subproject commit 2e055b3fa8c7f24b2dfa7ec1e3ab39fd4f072007

View File

@ -3350,5 +3350,6 @@ export default {
valiate_fail: "Validate fail", valiate_fail: "Validate fail",
check_subitem: 'check subitem', check_subitem: 'check subitem',
pause: 'Pause', pause: 'Pause',
browser: "Browser",
} }
}; };

View File

@ -3359,5 +3359,6 @@ export default {
check_element: "请勾选元素", check_element: "请勾选元素",
check_subitem: '请选择子分类', check_subitem: '请选择子分类',
pause: '等待时间', pause: '等待时间',
browser: "浏览器",
} }
}; };

View File

@ -3336,5 +3336,6 @@ export default {
cmdExtractElement: "提取元素信息", cmdExtractElement: "提取元素信息",
valiate_fail: "校驗失敗,請檢查必填項", valiate_fail: "校驗失敗,請檢查必填項",
pause: '等待時間', pause: '等待時間',
browser: "瀏覽器",
} }
}; };