refactor(接口定义): 重构接口用例代码,去除一些无用的组件

This commit is contained in:
fit2-zhao 2021-10-26 16:22:28 +08:00 committed by fit2-zhao
parent 98d47b8bdd
commit 87db8a6c66
5 changed files with 122 additions and 339 deletions

View File

@ -11,8 +11,6 @@ import io.metersphere.api.dto.definition.request.ElementUtil;
import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.api.dto.definition.request.auth.MsAuthManager; import io.metersphere.api.dto.definition.request.auth.MsAuthManager;
import io.metersphere.api.dto.definition.request.dns.MsDNSCacheManager; import io.metersphere.api.dto.definition.request.dns.MsDNSCacheManager;
import io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor;
import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor;
import io.metersphere.api.dto.scenario.Body; import io.metersphere.api.dto.scenario.Body;
import io.metersphere.api.dto.scenario.HttpConfig; import io.metersphere.api.dto.scenario.HttpConfig;
import io.metersphere.api.dto.scenario.HttpConfigCondition; import io.metersphere.api.dto.scenario.HttpConfigCondition;
@ -284,6 +282,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
} }
} }
private void initConnectAndResponseTimeout(ParameterConfig config) { private void initConnectAndResponseTimeout(ParameterConfig config) {
if (config.isEffective(this.getProjectId())) { if (config.isEffective(this.getProjectId())) {
String useEvnId = config.getConfig().get(this.getProjectId()).getApiEnvironmentid(); String useEvnId = config.getConfig().get(this.getProjectId()).getApiEnvironmentid();
@ -604,7 +603,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
stringBuffer.append(path); stringBuffer.append(path);
stringBuffer.append("/"); stringBuffer.append("/");
Map<String, String> keyValueMap = new HashMap<>(); Map<String, String> keyValueMap = new HashMap<>();
this.getRest().stream().filter(KeyValue::isEnable).filter(KeyValue::isValid).forEach(keyValue -> this.getRest().stream().filter(KeyValue::isEnable).filter(KeyValue::isValid).filter(KeyValue::valueIsNotEmpty).forEach(keyValue ->
keyValueMap.put(keyValue.getName(), keyValue.getValue() != null && keyValue.getValue().startsWith("@") ? keyValueMap.put(keyValue.getName(), keyValue.getValue() != null && keyValue.getValue().startsWith("@") ?
ScriptEngineUtils.buildFunctionCallString(keyValue.getValue()) : keyValue.getValue()) ScriptEngineUtils.buildFunctionCallString(keyValue.getValue()) : keyValue.getValue())
); );
@ -613,7 +612,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
Matcher m = p.matcher(path); Matcher m = p.matcher(path);
while (m.find()) { while (m.find()) {
String group = m.group(2); String group = m.group(2);
if (!isVariable(path, group)) { if (!isVariable(path, group) && keyValueMap.containsKey(group)) {
path = path.replace("{" + group + "}", keyValueMap.get(group)); path = path.replace("{" + group + "}", keyValueMap.get(group));
} }
} }

View File

@ -58,6 +58,10 @@ public class KeyValue {
this(name, value, description, "", required); this(name, value, description, "", required);
} }
public boolean valueIsNotEmpty() {
return StringUtils.isNotEmpty(this.getValue());
}
public boolean isValid() { public boolean isValid() {
return (StringUtils.isNotBlank(name) || "JSON-SCHEMA".equals(type)) && !StringUtils.equalsIgnoreCase(type, "file"); return (StringUtils.isNotBlank(name) || "JSON-SCHEMA".equals(type)) && !StringUtils.equalsIgnoreCase(type, "file");
} }

View File

@ -2,13 +2,12 @@
<el-header style="width: 100% ;padding: 0px"> <el-header style="width: 100% ;padding: 0px">
<el-card> <el-card>
<el-row> <el-row>
<el-col :span="api.protocol==='HTTP'? 3:5"> <el-col :span="api.protocol==='HTTP'? 7:9">
<el-checkbox v-model="isSelectAll" class="select-all"/>
<el-tooltip :content="api.name"> <el-tooltip :content="api.name">
<span class="ms-col-name"> {{api.name}}</span> <span class="ms-col-name"> {{api.name}}</span>
</el-tooltip> </el-tooltip>
</el-col> </el-col>
<el-col :span="api.protocol==='HTTP'? 1:3"> <el-col :span="api.protocol==='HTTP'? 6:8">
<el-tag size="mini" :style="{'background-color': getColor(true, api.method), border: getColor(true, api.method)}" class="api-el-tag"> <el-tag size="mini" :style="{'background-color': getColor(true, api.method), border: getColor(true, api.method)}" class="api-el-tag">
{{ api.method}} {{ api.method}}
</el-tag> </el-tag>
@ -16,34 +15,6 @@
<el-col :span="api.protocol==='HTTP'? 4:0"> <el-col :span="api.protocol==='HTTP'? 4:0">
<div class="variable-combine" style="margin-left: 10px">{{api.path ===null ? " " : api.path}}</div> <div class="variable-combine" style="margin-left: 10px">{{api.path ===null ? " " : api.path}}</div>
</el-col> </el-col>
<el-col :span="2" v-if="!isCaseEdit">
<div>{{$t('test_track.plan_view.case_count')}}{{apiCaseList.length}}</div>
</el-col>
<el-col :span="3">
<div>
<el-select size="small" :placeholder="$t('api_test.definition.request.grade_order_asc')" v-model="condition.order"
:disabled="isCaseEdit"
class="ms-api-header-select" @change="search" clearable>
<el-option v-for="grd in priorities" :key="grd.id" :label="$t(grd.label)" :value="grd.id"/>
</el-select>
</div>
</el-col>
<el-col :span="4">
<div class="ms-api-header-select" style="margin-right: 20px">
<el-row>
<el-col :span="12">
<el-input size="small" :placeholder="$t('api_test.definition.request.select_case')"
:disabled="isCaseEdit"
v-model="condition.name" @blur="search" @keyup.enter.native="search"/>
</el-col>
<el-col :span="12">
<el-link type="primary" style="margin-left: 5px" @click="open">{{$t('commons.adv_search.title')}}</el-link>
</el-col>
</el-row>
</div>
</el-col>
<el-col :span="5"> <el-col :span="5">
<div> <div>
<ms-environment-select <ms-environment-select
@ -53,16 +24,8 @@
@setEnvironment="setEnvironment" ref="environmentSelect"/> @setEnvironment="setEnvironment" ref="environmentSelect"/>
</div> </div>
</el-col> </el-col>
<!-- <el-col :span="1" v-if="!(isReadOnly || isCaseEdit) && !(this.$store.state.currentApiCase && this.$store.state.currentApiCase.case)">-->
<!-- <el-button size="small" type="primary" @click="addCase" v-permission="['PROJECT_API_DEFINITION:READ+CREATE_CASE']">+{{ $t('api_test.definition.request.case') }}-->
<!-- </el-button>-->
<!-- </el-col>-->
</el-row> </el-row>
</el-card> </el-card>
<!--高级搜索-->
<ms-table-adv-search-bar :condition.sync="condition" :showLink="false" ref="searchBar" @search="search"/>
</el-header> </el-header>
</template> </template>
@ -72,22 +35,18 @@
import MsTag from "../../../../common/components/MsTag"; import MsTag from "../../../../common/components/MsTag";
import MsEnvironmentSelect from "./MsEnvironmentSelect"; import MsEnvironmentSelect from "./MsEnvironmentSelect";
import {API_METHOD_COLOUR} from "../../model/JsonData"; import {API_METHOD_COLOUR} from "../../model/JsonData";
import MsTableAdvSearchBar from "@/business/components/common/components/search/MsTableAdvSearchBar";
export default { export default {
name: "ApiCaseHeader", name: "ApiCaseHeader",
components: {MsEnvironmentSelect, MsTag, ApiEnvironmentConfig, MsTableAdvSearchBar}, components: {MsEnvironmentSelect, MsTag, ApiEnvironmentConfig},
data() { data() {
return { return {
methodColorMap: new Map(API_METHOD_COLOUR), methodColorMap: new Map(API_METHOD_COLOUR),
isSelectAll: false
} }
}, },
props: { props: {
api: Object, api: Object,
projectId: String, projectId: String,
priorities: Array, priorities: Array,
apiCaseList: Array,
isReadOnly: Boolean, isReadOnly: Boolean,
useEnvironment: String, useEnvironment: String,
isCaseEdit: Boolean, isCaseEdit: Boolean,
@ -100,11 +59,6 @@
}, },
created() { created() {
}, },
watch: {
isSelectAll() {
this.$emit('selectAll', this.isSelectAll);
},
},
methods: { methods: {
refreshEnvironment(){ refreshEnvironment(){
this.$refs.environmentSelect.refreshEnvironment(); this.$refs.environmentSelect.refreshEnvironment();
@ -114,16 +68,6 @@
this.$emit('setEnvironment', data.id); this.$emit('setEnvironment', data.id);
} }
}, },
search() {
if (this.priorities && this.condition.order) {
for (let index in this.priorities) {
if (this.priorities[index].id === this.condition.order) {
this.condition.orders = [this.priorities[index]];
}
}
}
this.$emit('getApiTest');
},
open() { open() {
this.$refs.searchBar.open(); this.$refs.searchBar.open();
}, },

View File

@ -2,24 +2,6 @@
<el-card style="margin-top: 5px" @click.native="selectTestCase(apiCase,$event)" v-loading="saveLoading"> <el-card style="margin-top: 5px" @click.native="selectTestCase(apiCase,$event)" v-loading="saveLoading">
<div @click="active(apiCase)" v-if="type!=='detail'"> <div @click="active(apiCase)" v-if="type!=='detail'">
<el-row> <el-row>
<el-col :span="3">
<el-row>
<el-col :span="2" style="margin-top: 5px">
<el-checkbox class="item-select" v-model="apiCase.selected"/>
</el-col>
<el-col :span="2" style="margin-top: 2px">
<show-more-btn :is-show="apiCase.selected" :buttons="buttons" :size="selectSize"/>
</el-col>
<el-col :span="20">
<div class="el-step__icon is-text ms-api-col">
<div class="el-step__icon-inner">{{ index + 1 }}</div>
</div>
<el-select size="mini" v-model="apiCase.priority" class="ms-api-select" @change="changePriority(apiCase)">
<el-option v-for="grd in priorities" :key="grd.id" :label="grd.name" :value="grd.id"/>
</el-select>
</el-col>
</el-row>
</el-col>
<el-col :span="api.protocol==='HTTP'?4:8" v-loading="loading && !(apiCase.active||type==='detail')"> <el-col :span="api.protocol==='HTTP'?4:8" v-loading="loading && !(apiCase.active||type==='detail')">
<span @click.stop> <span @click.stop>
<i class="icon el-icon-arrow-right" :class="{'is-active': apiCase.active}" @click="active(apiCase)"/> <i class="icon el-icon-arrow-right" :class="{'is-active': apiCase.active}" @click="active(apiCase)"/>
@ -43,6 +25,11 @@
</span> </span>
</div> </div>
</el-col> </el-col>
<el-col :span="2">
<el-select size="mini" v-model="apiCase.priority" class="ms-api-select" @change="changePriority(apiCase)" :disabled="loaded">
<el-option v-for="grd in priorities" :key="grd.id" :label="grd.name" :value="grd.id"/>
</el-select>
</el-col>
<el-col :span="api.protocol==='HTTP'?4:0"> <el-col :span="api.protocol==='HTTP'?4:0">
<span v-if="api.protocol==='HTTP'"> <span v-if="api.protocol==='HTTP'">
<el-tag size="mini" :style="{'background-color': getColor(true, apiCase.request.method), border: getColor(true, apiCase.request.method)}" <el-tag size="mini" :style="{'background-color': getColor(true, apiCase.request.method), border: getColor(true, apiCase.request.method)}"
@ -54,10 +41,10 @@
</el-tooltip> </el-tooltip>
</span> </span>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="5">
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-select size="small" v-model="apiCase.caseStatus" style="margin-right: 5px" @change="saveTestCase(apiCase,true)"> <el-select size="small" v-model="apiCase.caseStatus" style="margin-right: 5px" @change="saveTestCase(apiCase,true)" :disabled="loaded">
<el-option v-for="item in options" :key="item.id" :label="$t(item.label)" :value="item.id"/> <el-option v-for="item in options" :key="item.id" :label="$t(item.label)" :value="item.id"/>
</el-select> </el-select>
</el-col> </el-col>
@ -65,7 +52,7 @@
<div class="tag-item" @click.stop> <div class="tag-item" @click.stop>
<el-select v-model="apiCase.follows" multiple clearable <el-select v-model="apiCase.follows" multiple clearable
:placeholder="$t('api_test.automation.follow_people')" filterable size="small" :placeholder="$t('api_test.automation.follow_people')" filterable size="small"
@change="saveTestCase(apiCase,true)" style="width: 100%"> @change="saveTestCase(apiCase,true)" style="width: 100%" :disabled="loaded">
<el-option <el-option
v-for="item in maintainerOptions" v-for="item in maintainerOptions"
:key="item.id" :key="item.id"
@ -78,7 +65,7 @@
</el-row> </el-row>
<el-row style="margin-top: 5px"> <el-row style="margin-top: 5px">
<div class="tag-item" @click.stop> <div class="tag-item" @click.stop>
<ms-input-tag :currentScenario="apiCase" ref="tag" @keyup.enter.native="saveTestCase(apiCase,true)"/> <ms-input-tag :currentScenario="apiCase" ref="tag" @keyup.enter.native="saveTestCase(apiCase,true)" :disabled="loaded"/>
</div> </div>
</el-row> </el-row>
</el-col> </el-col>
@ -86,7 +73,7 @@
<el-col :span="3"> <el-col :span="3">
<span @click.stop> <span @click.stop>
<ms-tip-button @click="singleRun(apiCase)" :tip="$t('api_test.run')" icon="el-icon-video-play" v-permission="['PROJECT_API_DEFINITION:READ+RUN']" <ms-tip-button @click="singleRun(apiCase)" :tip="$t('api_test.run')" icon="el-icon-video-play" v-permission="['PROJECT_API_DEFINITION:READ+RUN']"
class="run-button" size="mini" :disabled="!apiCase.id" circle v-if="!loading"/> class="run-button" size="mini" :disabled="!apiCase.id || loaded" circle v-if="!loading"/>
<el-tooltip :content="$t('report.stop_btn')" placement="top" :enterable="false" v-else> <el-tooltip :content="$t('report.stop_btn')" placement="top" :enterable="false" v-else>
<el-button :disabled="!apiCase.id" @click.once="stop(apiCase)" size="mini" style="color:white;padding: 0;width: 28px;height: 28px;" class="stop-btn" circle> <el-button :disabled="!apiCase.id" @click.once="stop(apiCase)" size="mini" style="color:white;padding: 0;width: 28px;height: 28px;" class="stop-btn" circle>
<div style="transform: scale(0.72)"> <div style="transform: scale(0.72)">
@ -95,14 +82,14 @@
</el-button> </el-button>
</el-tooltip> </el-tooltip>
<ms-tip-button @click="copyCase(apiCase)" :tip="$t('commons.copy')" icon="el-icon-document-copy" v-permission="['PROJECT_API_DEFINITION:READ+COPY_CASE']" <ms-tip-button @click="copyCase(apiCase)" :tip="$t('commons.copy')" icon="el-icon-document-copy" v-permission="['PROJECT_API_DEFINITION:READ+COPY_CASE']"
size="mini" :disabled="!apiCase.id || isCaseEdit" circle/> size="mini" :disabled="!apiCase.id || isCaseEdit || loaded" circle/>
<ms-tip-button @click="deleteCase(index,apiCase)" :tip="$t('commons.delete')" icon="el-icon-delete" v-permission="['PROJECT_API_SCENARIO:READ+DELETE_CASE']" <ms-tip-button @click="deleteCase(index,apiCase)" :tip="$t('commons.delete')" icon="el-icon-delete" v-permission="['PROJECT_API_SCENARIO:READ+DELETE_CASE']"
size="mini" :disabled="!apiCase.id || isCaseEdit" circle/> size="mini" :disabled="!apiCase.id || isCaseEdit" circle/>
<ms-api-extend-btns :is-case-edit="isCaseEdit" :environment="environment" :row="apiCase"/> <ms-api-extend-btns :is-case-edit="isCaseEdit" :environment="environment" :row="apiCase"/>
</span> </span>
</el-col> </el-col>
<el-col :span="2"> <el-col :span="4">
<el-link @click.stop type="danger" v-if="apiCase.execResult && apiCase.execResult==='error'" @click="showExecResult(apiCase)"> <el-link @click.stop type="danger" v-if="apiCase.execResult && apiCase.execResult==='error'" @click="showExecResult(apiCase)">
{{ getResult(apiCase.execResult) }} {{ getResult(apiCase.execResult) }}
</el-link> </el-link>
@ -128,16 +115,16 @@
<div v-if="apiCase.active||type==='detail'" v-loading="loading"> <div v-if="apiCase.active||type==='detail'" v-loading="loading">
<el-divider></el-divider> <el-divider></el-divider>
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p> <p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
<ms-api-request-form :isShowEnable="true" :showScript="true" :is-read-only="isReadOnly" :headers="apiCase.request.headers " :request="apiCase.request" v-if="api.protocol==='HTTP'"/> <ms-api-request-form :isShowEnable="true" :showScript="true" :headers="apiCase.request.headers " :request="apiCase.request" v-if="api.protocol==='HTTP'"/>
<tcp-format-parameters :showScript="true" :request="apiCase.request" v-if="api.method==='TCP' && apiCase.request.esbDataStruct == null"/> <tcp-format-parameters :showScript="true" :request="apiCase.request" v-if="api.method==='TCP' && apiCase.request.esbDataStruct == null"/>
<esb-definition v-xpack :request="apiCase.request" :showScript="true" v-if="showXpackCompnent&&api.method==='ESB'" ref="esbDefinition"/> <esb-definition v-xpack :request="apiCase.request" :showScript="true" v-if="isXpack&&api.method==='ESB'" ref="esbDefinition"/>
<ms-sql-basis-parameters :showScript="true" :request="apiCase.request" v-if="api.protocol==='SQL'"/> <ms-sql-basis-parameters :showScript="true" :request="apiCase.request" v-if="api.protocol==='SQL'"/>
<ms-dubbo-basis-parameters :showScript="true" :request="apiCase.request" v-if="api.protocol==='DUBBO'"/> <ms-dubbo-basis-parameters :showScript="true" :request="apiCase.request" v-if="api.protocol==='DUBBO'"/>
<!-- HTTP 请求返回数据 --> <!-- HTTP 请求返回数据 -->
<p class="tip">{{ $t('api_test.definition.request.res_param') }}</p> <p class="tip">{{ $t('api_test.definition.request.res_param') }}</p>
<div v-if="showXpackCompnent&&api.method==='ESB'"> <div v-if="isXpack&&api.method==='ESB'">
<esb-definition-response v-xpack v-if="showXpackCompnent" :currentProtocol="apiCase.request.protocol" :request="apiCase.request" :is-api-component="false" :show-options-button="false" :show-header="true" :api-item="apiCase"/> <esb-definition-response v-xpack v-if="isXpack" :currentProtocol="apiCase.request.protocol" :request="apiCase.request" :is-api-component="false" :show-options-button="false" :show-header="true" :api-item="apiCase"/>
</div> </div>
<div v-else> <div v-else>
<api-response-component :currentProtocol="apiCase.request.protocol" :api-item="apiCase" :result="runResult"/> <api-response-component :currentProtocol="apiCase.request.protocol" :api-item="apiCase" :result="runResult"/>
@ -225,8 +212,7 @@ export default {
['error', this.$t('test_track.plan_view.execute_result') + '' + this.$t('api_test.home_page.detail_card.execution_failed')], ['error', this.$t('test_track.plan_view.execute_result') + '' + this.$t('api_test.home_page.detail_card.execution_failed')],
['default', this.$t('test_track.plan_view.execute_result') + '' + this.$t('api_test.home_page.detail_card.unexecute')] ['default', this.$t('test_track.plan_view.execute_result') + '' + this.$t('api_test.home_page.detail_card.unexecute')]
]), ]),
showXpackCompnent: false, isXpack: false,
isReadOnly: false,
selectedEvent: Object, selectedEvent: Object,
priorities: PRIORITY, priorities: PRIORITY,
runData: [], runData: [],
@ -236,17 +222,17 @@ export default {
condition: {}, condition: {},
responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []}, responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []},
isShowInput: false, isShowInput: false,
buttons: [
{name: this.$t('api_test.automation.batch_execute'), handleClick: this.handleRunBatch},
{name: this.$t('test_track.case.batch_edit_case'), handleClick: this.handleEditBatch}
],
methodColorMap: new Map(API_METHOD_COLOUR), methodColorMap: new Map(API_METHOD_COLOUR),
saveLoading: false, saveLoading: false,
beforeRequest: {},
} }
}, },
props: { props: {
runResult: {}, runResult: {},
selectSize: Number, loaded: {
type: Boolean,
default: false,
},
apiCase: { apiCase: {
type: Object, type: Object,
default() { default() {
@ -266,6 +252,7 @@ export default {
return {} return {}
} }
}, },
currentApi: {},
type: String, type: String,
isCaseEdit: Boolean, isCaseEdit: Boolean,
loading: { loading: {
@ -278,35 +265,27 @@ export default {
}, },
created() { created() {
if (requireComponent != null && JSON.stringify(esbDefinition) != '{}' && JSON.stringify(esbDefinitionResponse) != '{}') { if (requireComponent != null && JSON.stringify(esbDefinition) != '{}' && JSON.stringify(esbDefinitionResponse) != '{}') {
this.showXpackCompnent = true; this.isXpack = true;
} }
if (this.apiCase && this.apiCase.id) { if (this.apiCase && this.apiCase.id) {
this.$get('/api/testcase/follow/' + this.apiCase.id, response => { this.$get('/api/testcase/follow/' + this.apiCase.id, response => {
this.apiCase.follows = response.data; this.apiCase.follows = response.data;
}); });
} }
}, if (this.currentApi && this.currentApi.request) {
watch: { this.beforeRequest = JSON.parse(JSON.stringify(this.currentApi.request));
'apiCase.selected'() {
this.$emit('apiCaseSelected');
} }
}, },
methods: { methods: {
hasPermission, hasPermission,
openHis(row) { openHis(row) {
this.$refs.changeHistory.open(row.id,["接口定义用例" , "接口定義用例" , "Api definition case"]); this.$refs.changeHistory.open(row.id, ["接口定义用例", "接口定義用例", "Api definition case"]);
},
handleRunBatch() {
this.$emit('batchRun');
}, },
getColor(enable, method) { getColor(enable, method) {
if (enable) { if (enable) {
return this.methodColorMap.get(method); return this.methodColorMap.get(method);
} }
}, },
handleEditBatch() {
this.$emit('batchEditCase');
},
deleteCase(index, row) { deleteCase(index, row) {
this.$alert(this.$t('api_test.definition.request.delete_case_confirm') + ' ' + row.name + " ", '', { this.$alert(this.$t('api_test.definition.request.delete_case_confirm') + ' ' + row.name + " ", '', {
confirmButtonText: this.$t('commons.confirm'), confirmButtonText: this.$t('commons.confirm'),
@ -348,14 +327,14 @@ export default {
} }
if ($event.currentTarget.className.indexOf('is-selected') > 0) { if ($event.currentTarget.className.indexOf('is-selected') > 0) {
$event.currentTarget.className = "el-card is-always-shadow"; $event.currentTarget.className = "el-card is-always-shadow";
this.$emit('selectTestCase', null); this.currentApi.request = this.beforeRequest;
} else { } else {
if (this.selectedEvent.currentTarget != undefined) { if (this.selectedEvent.currentTarget != undefined) {
this.selectedEvent.currentTarget.className = "el-card is-always-shadow"; this.selectedEvent.currentTarget.className = "el-card is-always-shadow";
} }
this.selectedEvent.currentTarget = $event.currentTarget; this.selectedEvent.currentTarget = $event.currentTarget;
$event.currentTarget.className = "el-card is-always-shadow is-selected"; $event.currentTarget.className = "el-card is-always-shadow is-selected";
this.$emit('selectTestCase', item); this.currentApi.request = item.request;
} }
}, },
changePriority(row) { changePriority(row) {

View File

@ -4,43 +4,37 @@
<template v-slot:header> <template v-slot:header>
<api-case-header <api-case-header
:api="api" :api="api"
@getApiTest="getApiTest"
@setEnvironment="setEnvironment" @setEnvironment="setEnvironment"
@addCase="addCase" @addCase="addCase"
@selectAll="selectAll"
:condition="condition" :condition="condition"
:priorities="priorities" :priorities="priorities"
:apiCaseList="apiCaseList"
:is-read-only="isReadOnly"
:project-id="projectId" :project-id="projectId"
:useEnvironment="environment" :useEnvironment="environment"
:is-case-edit="isCaseEdit" :is-case-edit="isCaseEdit"
ref="header" ref="header"/>
/>
</template> </template>
<el-container v-if="!result.loading"> <el-container v-if="!result.loading">
<el-main> <el-main>
<div v-for="(item,index) in apiCaseList" :key="item.id ? item.id : item.uuid"> <div v-for="(item,index) in apiCaseList" :key="item.id ? item.id : item.uuid">
<api-case-item :loading="singleLoading && singleRunId === item.id || batchLoadingIds.indexOf(item.id) > -1" <api-case-item
@refresh="refresh" :loading="singleLoading && singleRunId === item.id || batchLoadingIds.indexOf(item.id) > -1"
@singleRun="singleRun" @refresh="refresh"
@stop="stop" @singleRun="singleRun"
@refreshModule="refreshModule" @stop="stop"
@copyCase="copyCase" @refreshModule="refreshModule"
@showExecResult="showExecResult" @copyCase="copyCase"
@batchEditCase="batchEditCase" @showExecResult="showExecResult"
@batchRun="batchRun" @showHistory="showHistory"
@apiCaseSelected="apiCaseSelected" @reLoadCase="reLoadCase"
@showHistory="showHistory" :environment="environment"
@reLoadCase="reLoadCase" :is-case-edit="isCaseEdit"
:environment="environment" :api="api"
:select-size="selectSize" :currentApi="currentApi"
:is-case-edit="isCaseEdit" :loaded="loaded"
:api="api" :runResult="runResult"
:runResult="runResult" :maintainerOptions="maintainerOptions"
:maintainerOptions="maintainerOptions" :api-case="item" :index="index" ref="apiCaseItem"/>
:api-case="item" :index="index" ref="apiCaseItem"/>
</div> </div>
</el-main> </el-main>
</el-container> </el-container>
@ -49,11 +43,7 @@
<!-- 执行组件 --> <!-- 执行组件 -->
<ms-run :debug="false" :reportId="reportId" :run-data="runData" :env-map="envMap" <ms-run :debug="false" :reportId="reportId" :run-data="runData" :env-map="envMap"
@runRefresh="runRefresh" @errorRefresh="errorRefresh" ref="runTest"/> @runRefresh="runRefresh" @errorRefresh="errorRefresh" ref="runTest"/>
<!--批量编辑-->
<ms-batch-edit ref="batchEdit" @batchEdit="batchEdit" :typeArr="typeArr" :data-count="selectdCases.length" :value-arr="valueArr"/>
<ms-task-center ref="taskCenter" :show-menu="false"/> <ms-task-center ref="taskCenter" :show-menu="false"/>
</div> </div>
</template> </template>
<script> <script>
@ -61,22 +51,24 @@
import ApiCaseHeader from "./ApiCaseHeader"; import ApiCaseHeader from "./ApiCaseHeader";
import {getCurrentProjectID, getUUID} from "@/common/js/utils"; import {getCurrentProjectID, getUUID} from "@/common/js/utils";
import MsDrawer from "../../../../common/components/MsDrawer"; import MsDrawer from "../../../../common/components/MsDrawer";
import {CASE_ORDER, CASE_PRIORITY, DUBBO_METHOD, REQ_METHOD, SQL_METHOD, TCP_METHOD} from "../../model/JsonData"; import {CASE_ORDER} from "../../model/JsonData";
import {API_CASE_CONFIGS} from "@/business/components/common/components/search/search-components"; import {API_CASE_CONFIGS} from "@/business/components/common/components/search/search-components";
export default { export default {
name: 'ApiCaseList', name: 'ApiCaseList',
components: { components: {
MsDrawer, MsDrawer,
MsRun: () => import("../Run"),
ApiCaseHeader, ApiCaseHeader,
MsRun: () => import("../Run"),
ApiCaseItem: () => import("./ApiCaseItem"), ApiCaseItem: () => import("./ApiCaseItem"),
MsBatchEdit: () => import("../basis/BatchEdit"),
MsTaskCenter: () => import("../../../../task/TaskCenter"), MsTaskCenter: () => import("../../../../task/TaskCenter"),
}, },
props: { props: {
createCase: String, createCase: String,
loaded: Boolean, loaded: {
type: Boolean,
default: false
},
refreshSign: String, refreshSign: String,
currentApi: { currentApi: {
type: Object type: Object
@ -85,11 +77,7 @@ export default {
data() { data() {
return { return {
result: {}, result: {},
grades: [],
environment: "", environment: "",
isReadOnly: false,
selectedEvent: Object,
selectSize: 0,
priorities: CASE_ORDER, priorities: CASE_ORDER,
apiCaseList: [], apiCaseList: [],
batchLoadingIds: [], batchLoadingIds: [],
@ -97,28 +85,13 @@ export default {
singleRunId: "", singleRunId: "",
runResult: {}, runResult: {},
runData: [], runData: [],
selectdCases: [],
reportId: "", reportId: "",
testCaseId: "", testCaseId: "",
checkedCases: new Set(),
visible: false, visible: false,
condition: { condition: {
components: API_CASE_CONFIGS components: API_CASE_CONFIGS
}, },
api: {}, api: {},
typeArr: [
{id: 'priority', name: this.$t('test_track.case.priority')}
],
priorityFilters: [
{text: 'P0', value: 'P0'},
{text: 'P1', value: 'P1'},
{text: 'P2', value: 'P2'},
{text: 'P3', value: 'P3'}
],
valueArr: {
priority: CASE_PRIORITY,
method: REQ_METHOD,
},
envMap: new Map, envMap: new Map,
maintainerOptions: [], maintainerOptions: [],
}; };
@ -160,16 +133,6 @@ export default {
this.maintainerOptions = response.data; this.maintainerOptions = response.data;
}); });
}, },
apiCaseSelected() {
this.selectSize = 0;
if (this.apiCaseList.length > 0) {
this.apiCaseList.forEach(item => {
if (item.selected && item.id) {
this.selectSize++;
}
});
}
},
open(api, testCaseId) { open(api, testCaseId) {
this.api = api; this.api = api;
// testCaseId // testCaseId
@ -204,11 +167,14 @@ export default {
this.visible = true; this.visible = true;
}, },
runTestCase(api, testCaseId) { runTestCase(api, testCaseId) {
this.api = api; if (api && testCaseId) {
// testCaseId this.api = api;
this.testCaseId = testCaseId; this.testCaseId = testCaseId;
this.condition = {components: API_CASE_CONFIGS}; this.condition = {components: API_CASE_CONFIGS};
this.getApiTestToRunTestCase(testCaseId); this.getTestCase().then(() => {
this.singleRun(this.apiCaseList[0]);
});
}
this.visible = true; this.visible = true;
}, },
saveApiAndCase(api) { saveApiAndCase(api) {
@ -230,7 +196,6 @@ export default {
this.addCase(); this.addCase();
} }
}, },
apiCaseClose() { apiCaseClose() {
this.apiCaseList = []; this.apiCaseList = [];
this.visible = false; this.visible = false;
@ -243,13 +208,6 @@ export default {
this.batchLoadingIds = []; this.batchLoadingIds = [];
this.singleLoading = false; this.singleLoading = false;
this.singleRunId = ""; this.singleRunId = "";
if (this.$refs.header.isSelectAll) {
this.$refs.header.isSelectAll = false;
} else {
this.apiCaseList.forEach(item => {
this.$set(item, 'selected', false);
});
}
// //
let obj = {envId: this.environment, show: true}; let obj = {envId: this.environment, show: true};
this.batchEdit(obj); this.batchEdit(obj);
@ -257,111 +215,78 @@ export default {
this.$refs.apiCaseItem.runLoading = false; this.$refs.apiCaseItem.runLoading = false;
this.$success(this.$t('organization.integration.successful_operation')); this.$success(this.$t('organization.integration.successful_operation'));
this.$store.state.currentApiCase = {refresh: true}; this.$store.state.currentApiCase = {refresh: true};
this.getApiTest(); this.getTestCase();
}, },
errorRefresh() { errorRefresh() {
this.batchLoadingIds = []; this.batchLoadingIds = [];
this.singleLoading = false; this.singleLoading = false;
this.singleRunId = ""; this.singleRunId = "";
this.$refs.apiCaseItem.runLoading = false; this.$refs.apiCaseItem.runLoading = false;
//this.$emit("refresh");
}, },
refresh() { refresh() {
this.$emit('refresh'); this.$emit('refresh');
}, },
reLoadCase(){ reLoadCase() {
this.$emit('reLoadCase'); this.$emit('reLoadCase');
}, },
selectAll(isSelectAll) { formatCase(apiCase) {
this.apiCaseList.forEach(item => { if (apiCase.tags && apiCase.tags.length > 0) {
this.$set(item, 'selected', isSelectAll); apiCase.tags = JSON.parse(apiCase.tags);
}
if (Object.prototype.toString.call(apiCase.request).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
apiCase.request = JSON.parse(apiCase.request);
}
if (!apiCase.request.hashTree) {
apiCase.request.hashTree = [];
}
const index = this.runData.findIndex(d => d.name === apiCase.id);
if (index !== -1) {
apiCase.active = true;
} else {
if (this.condition.id && this.condition.id != "") {
apiCase.active = true;
}
}
if (apiCase && apiCase.request && apiCase.request.useEnvironment) {
this.environment = apiCase.request.useEnvironment;
}
},
getTestCase() {
return new Promise((resolve) => {
this.environment = "";
this.result = this.$get("/api/testcase/findById/" + this.testCaseId, response => {
let apiCase = response.data;
if (apiCase) {
this.formatCase(apiCase);
this.apiCaseList = [apiCase];
}
resolve();
});
}); });
}, },
getApiTest(addCase) { getApiLoadCase() {
this.environment = "";
if (this.api) { if (this.api) {
this.condition.projectId = this.projectId; this.condition.projectId = this.projectId;
if (this.isCaseEdit) {
this.condition.id = this.testCaseId;
}
this.condition.apiDefinitionId = this.api.id; this.condition.apiDefinitionId = this.api.id;
this.result = this.$post("/api/testcase/list", this.condition, response => { this.result = this.$post("/api/testcase/list", this.condition, response => {
let data = []; let data = response.data;
if (response.data) { if (data) {
data = response.data; data.forEach(apiCase => {
} this.formatCase(apiCase);
data.forEach(apiCase => { });
if (apiCase.tags && apiCase.tags.length > 0) { this.apiCaseList = data;
apiCase.tags = JSON.parse(apiCase.tags);
this.$set(apiCase, 'selected', false);
}
if (Object.prototype.toString.call(apiCase.request).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
apiCase.request = JSON.parse(apiCase.request);
}
if (!apiCase.request.hashTree) {
apiCase.request.hashTree = [];
}
const index = this.runData.findIndex(d => d.name === apiCase.id);
if (index !== -1) {
apiCase.active = true;
} else {
if (this.condition.id && this.condition.id != "") {
apiCase.active = true;
}
}
});
this.apiCaseList = data;
if (this.apiCaseList[0] && this.apiCaseList[0].request && this.apiCaseList[0].request.useEnvironment) {
this.environment = this.apiCaseList[0].request.useEnvironment;
}
if (addCase && this.apiCaseList.length === 0 && !this.loaded) {
this.addCase();
} }
}); });
} }
}, },
getApiTestToRunTestCase(testCaseId) { getApiTest(addCase) {
if (this.api) { if (this.loaded) {
this.condition.projectId = this.projectId; this.getApiLoadCase();
if (this.isCaseEdit) { } else {
this.condition.id = this.testCaseId; this.getTestCase().then(() => {
} if (addCase && !this.loaded && this.apiCaseList.length === 0) {
if (this.api) {
this.condition.apiDefinitionId = this.api.id;
}
this.result = this.$post("/api/testcase/list", this.condition, response => {
let data = [];
if (response.data) {
data = response.data;
}
data.forEach(apiCase => {
if (apiCase.tags && apiCase.tags.length > 0) {
apiCase.tags = JSON.parse(apiCase.tags);
this.$set(apiCase, 'selected', false);
}
if (Object.prototype.toString.call(apiCase.request).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
apiCase.request = JSON.parse(apiCase.request);
}
if (!apiCase.request.hashTree) {
apiCase.request.hashTree = [];
}
});
this.apiCaseList = data;
if (this.apiCaseList[0] && this.apiCaseList[0].request && this.apiCaseList[0].request.useEnvironment) {
this.environment = this.apiCaseList[0].request.useEnvironment;
}
if (this.apiCaseList.length === 0 && !this.loaded) {
this.addCase(); this.addCase();
} }
this.apiCaseList.forEach(apicase => {
if (apicase.id === testCaseId) {
let data = apicase;
data.message = true;
this.singleRun(data);
}
});
}); });
} }
}, },
@ -398,14 +323,11 @@ export default {
this.visible = false; this.visible = false;
this.$emit('showExecResult', row); this.$emit('showExecResult', row);
}, },
singleRun(row) { singleRun(row) {
if (this.currentApi.protocol !== "SQL" && this.currentApi.protocol !== "DUBBO" && this.currentApi.protocol !== "dubbo://" && !this.environment) { if (this.currentApi.protocol !== "SQL" && this.currentApi.protocol !== "DUBBO" && this.currentApi.protocol !== "dubbo://" && !this.environment) {
this.$warning(this.$t('api_test.environment.select_environment')); this.$warning(this.$t('api_test.environment.select_environment'));
return; return;
} }
this.selectdCases = [];
this.selectdCases.push(row.id);
this.runData = []; this.runData = [];
this.singleLoading = true; this.singleLoading = true;
this.singleRunId = row.id; this.singleRunId = row.id;
@ -427,67 +349,11 @@ export default {
this.$success(this.$t('report.test_stop_success')); this.$success(this.$t('report.test_stop_success'));
}); });
}, },
batchRun() {
if (this.currentApi.protocol !== "SQL" && this.currentApi.protocol !== "DUBBO" && this.currentApi.protocol !== "dubbo://" && !this.environment) {
this.$warning(this.$t('api_test.environment.select_environment'));
return;
}
this.envMap = new Map();
this.envMap.set(getCurrentProjectID(), this.environment);
this.runData = [];
this.batchLoadingIds = [];
this.selectdCases = [];
if (this.apiCaseList.length > 0) {
this.apiCaseList.forEach(item => {
if (item.selected && item.id) {
item.request.name = item.id;
item.request.useEnvironment = this.environment;
this.runData.push(item.request);
this.batchLoadingIds.push(item.id);
this.selectdCases.push(item.id);
}
});
if (this.runData.length > 0) {
/*触发执行操作*/
this.reportId = getUUID().substring(0, 8);
} else {
this.$warning("请勾选要执行的用例!");
}
} else {
this.$warning("没有可执行的用例!");
}
},
batchEditCase() {
if (this.apiCaseList.length > 0) {
this.apiCaseList.forEach(item => {
if (item.selected && item.id) {
this.selectdCases.push(item.id);
}
});
}
if (this.selectdCases.length === 0) {
this.$warning("请选择用例!");
return;
}
// //
if (this.currentApi.protocol === 'HTTP') {
this.valueArr.method = REQ_METHOD;
} else if (this.currentApi.protocol === 'TCP') {
this.valueArr.method = TCP_METHOD;
} else if (this.currentApi.protocol === 'SQL') {
this.valueArr.method = SQL_METHOD;
} else if (this.currentApi.protocol === 'DUBBO') {
this.valueArr.method = DUBBO_METHOD;
}
this.$refs.batchEdit.open();
},
batchEdit(form) { batchEdit(form) {
let param = {}; let param = {};
if (form) { if (form) {
param[form.type] = form.value; param[form.type] = form.value;
param.ids = this.selectdCases; param.ids = [this.testCaseId];
param.projectId = this.projectId; param.projectId = this.projectId;
param.envId = form.envId; param.envId = form.envId;
if (this.api) { if (this.api) {
@ -501,16 +367,7 @@ export default {
if (!form.show) { if (!form.show) {
this.$success(this.$t('commons.save_success')); this.$success(this.$t('commons.save_success'));
} }
this.selectdCases = []; this.apiCaseList[0].active = true;
this.getResult();
});
},
getResult() {
this.apiCaseList.forEach(apiCase => {
const index = this.runData.findIndex(d => d.name === apiCase.id);
if (index !== -1) {
apiCase.active = true;
}
}); });
}, },
showHistory(id) { showHistory(id) {