fix(接口测试): 修复场景步骤拖拽问题
--bug=1017459 --user=赵勇 【接口测试】github#18262,接口自动化:引用了如图场景,然后自定义一个脚本,放到引用的场景里面去,发现只执行了引用的这个场景,自己自定义的脚本没有执行 https://www.tapd.cn/55049933/s/1283209
This commit is contained in:
parent
540865db48
commit
88a3858c31
|
@ -1,21 +1,22 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||
import io.metersphere.api.dto.definition.ApiDefinitionResult;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseInfo;
|
||||
import io.metersphere.api.dto.definition.request.ElementUtil;
|
||||
import io.metersphere.base.domain.Project;
|
||||
import io.metersphere.base.mapper.ProjectMapper;
|
||||
import io.metersphere.service.definition.ApiDefinitionService;
|
||||
import io.metersphere.service.definition.ApiTestCaseService;
|
||||
import io.metersphere.base.domain.ApiDefinition;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
import io.metersphere.base.domain.Project;
|
||||
import io.metersphere.base.mapper.ApiDefinitionMapper;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ProjectMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
|
||||
import io.metersphere.commons.constants.ElementConstants;
|
||||
import io.metersphere.commons.constants.PropertyConstant;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.commons.utils.JSONUtil;
|
||||
import io.metersphere.service.definition.ApiDefinitionService;
|
||||
import io.metersphere.service.definition.ApiTestCaseService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.json.JSONArray;
|
||||
|
@ -36,6 +37,8 @@ public class MsHashTreeService {
|
|||
@Resource
|
||||
private ApiDefinitionService apiDefinitionService;
|
||||
@Resource
|
||||
private ApiDefinitionMapper apiDefinitionMapper;
|
||||
@Resource
|
||||
private ExtApiScenarioMapper extApiScenarioMapper;
|
||||
|
||||
@Resource
|
||||
|
@ -44,7 +47,7 @@ public class MsHashTreeService {
|
|||
public static final String CASE = "CASE";
|
||||
public static final String REFERENCED = "referenced";
|
||||
public static final String REF = "REF";
|
||||
public static final String CREATED = "Created";
|
||||
public static final String COPY = "Copy";
|
||||
public static final String REF_TYPE = "refType";
|
||||
public static final String ID = "id";
|
||||
public static final String NAME = "name";
|
||||
|
@ -165,17 +168,13 @@ public class MsHashTreeService {
|
|||
isExist = true;
|
||||
this.setElement(element, apiTestCase.getNum(), enable, apiTestCase.getVersionName(), apiTestCase.getVersionEnable());
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.equalsIgnoreCase(element.optString(REFERENCED), "Copy")) {
|
||||
ApiDefinitionResult definitionWithBLOBs = apiDefinitionService.getById(element.optString(ID));
|
||||
if (definitionWithBLOBs != null) {
|
||||
Project project = projectMapper.selectByPrimaryKey(definitionWithBLOBs.getProjectId());
|
||||
definitionWithBLOBs.setProjectName(project.getName());
|
||||
definitionWithBLOBs.setVersionEnable(project.getVersionEnable());
|
||||
element.put(ID, definitionWithBLOBs.getId());
|
||||
this.setElement(element, definitionWithBLOBs.getNum(), enable, definitionWithBLOBs.getVersionName(), definitionWithBLOBs.getVersionEnable());
|
||||
isExist = true;
|
||||
}
|
||||
} else if (StringUtils.equalsIgnoreCase(element.optString(REFERENCED), COPY)) {
|
||||
ApiDefinition definition = apiDefinitionMapper.selectByPrimaryKey(element.optString(ID));
|
||||
if (definition != null) {
|
||||
Project project = projectMapper.selectByPrimaryKey(definition.getProjectId());
|
||||
element.put(ID, definition.getId());
|
||||
this.setElement(element, definition.getNum(), enable, project.getName(), project.getVersionEnable());
|
||||
isExist = true;
|
||||
}
|
||||
}
|
||||
if (!isExist) {
|
||||
|
|
|
@ -183,11 +183,13 @@
|
|||
<el-tree node-key="resourceId" :props="props" :data="scenarioDefinition" class="ms-tree"
|
||||
:expand-on-click-node="false"
|
||||
:allow-drop="allowDrop"
|
||||
:allow-drag="allowDrag"
|
||||
:empty-text="$t('api_test.scenario.step_info')"
|
||||
highlight-current
|
||||
:show-checkbox="isBatchProcess"
|
||||
@check-change="chooseHeadsUp"
|
||||
@node-drag-end="allowDrag" @node-click="nodeClick" draggable ref="stepTree" :key="reloadTree">
|
||||
@node-drag-end="nodeDragEnd" @node-click="nodeClick" draggable ref="stepTree"
|
||||
:key="reloadTree">
|
||||
|
||||
<el-row class="custom-tree-node" :gutter="10" type="flex" align="middle" slot-scope="{node, data}"
|
||||
style="width: 100%">
|
||||
|
@ -1562,6 +1564,12 @@ export default {
|
|||
environmentConfigClose() {
|
||||
this.getEnvironments();
|
||||
},
|
||||
allowDrag(node) {
|
||||
if (node.data && node.data.disabled && node.parent.data && node.parent.data.disabled) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
allowDrop(draggingNode, dropNode, dropType) {
|
||||
if (draggingNode.data.type === 'Assertions' || dropNode.data.type === 'Assertions') {
|
||||
return false;
|
||||
|
@ -1576,12 +1584,13 @@ export default {
|
|||
}
|
||||
return false;
|
||||
} else if (dropType === "inner" && dropNode.data.referenced !== 'REF' && dropNode.data.referenced !== 'Deleted'
|
||||
&& !dropNode.data.disabled
|
||||
&& (this.stepFilter.get(dropNode.data.type) && this.stepFilter.get(dropNode.data.type).indexOf(draggingNode.data.type) != -1)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
allowDrag(draggingNode, dropNode, dropType) {
|
||||
nodeDragEnd(draggingNode, dropNode, dropType) {
|
||||
if (dropNode && draggingNode && dropType) {
|
||||
this.sort();
|
||||
this.forceRerender();
|
||||
|
|
|
@ -136,6 +136,7 @@ export default {
|
|||
this.isShowNum = this.scenario.num ? true : false;
|
||||
if (this.scenario.id && this.scenario.referenced === 'REF' && !this.scenario.loaded && this.scenario.hashTree) {
|
||||
this.scenario.root = this.node.parent.parent ? false : true;
|
||||
this.scenario.disabled = true;
|
||||
this.recursive(this.scenario.hashTree, this.scenario.projectId, true);
|
||||
}
|
||||
},
|
||||
|
@ -233,6 +234,7 @@ export default {
|
|||
}
|
||||
}
|
||||
if (this.scenario && this.scenario.hashTree && this.node.expanded) {
|
||||
this.scenario.disabled = true;
|
||||
this.recursive(this.scenario.hashTree, this.scenario.projectId, (this.scenario.id && this.scenario.referenced === 'REF'));
|
||||
}
|
||||
this.reload();
|
||||
|
|
|
@ -1,23 +1,58 @@
|
|||
<template>
|
||||
<div>
|
||||
<ms-run :debug="true" :environment="envMap" :reportId="reportId" :saved="false" :runMode="'DEFINITION'" :run-data="debugData" @errorRefresh="errorRefresh" @runRefresh="runRefresh" ref="runTest"/>
|
||||
<api-base-component :if-from-variable-advance="ifFromVariableAdvance" @copy="copyRow" @active="active(controller)" @remove="remove" :data="controller" :draggable="draggable" :is-max="isMax" :show-btn="showBtn" :show-version="showVersion" color="#02A7F0"
|
||||
background-color="#F4F4F5" :title="$t('api_test.automation.loop_controller')">
|
||||
|
||||
<ms-run
|
||||
:debug="true"
|
||||
:environment="envMap"
|
||||
:reportId="reportId"
|
||||
:saved="false"
|
||||
:runMode="'DEFINITION'"
|
||||
:run-data="debugData"
|
||||
@errorRefresh="errorRefresh"
|
||||
@runRefresh="runRefresh"
|
||||
ref="runTest"/>
|
||||
<api-base-component
|
||||
:if-from-variable-advance="ifFromVariableAdvance"
|
||||
:data="controller"
|
||||
:draggable="draggable"
|
||||
:is-max="isMax"
|
||||
:show-btn="showBtn"
|
||||
:show-version="showVersion"
|
||||
:title="$t('api_test.automation.loop_controller')"
|
||||
@copy="copyRow"
|
||||
@active="active(controller)"
|
||||
@remove="remove"
|
||||
color="#02A7F0"
|
||||
background-color="#F4F4F5">
|
||||
<template v-slot:headerLeft>
|
||||
<i class="icon el-icon-arrow-right" :class="{'is-active': controller.active}" style="margin-right: 10px" v-if="!isMax"/>
|
||||
<el-radio @change="changeRadio" class="ms-radio ms-radio-margin" v-model="controller.loopType" label="LOOP_COUNT">{{ $t('loop.loops_title') }}</el-radio>
|
||||
<el-radio @change="changeRadio" class="ms-radio ms-radio-margin" v-model="controller.loopType" label="FOREACH">{{ $t('loop.foreach') }}</el-radio>
|
||||
<el-radio @change="changeRadio" class="ms-radio ms-radio-margin" v-model="controller.loopType" label="WHILE">{{ $t('loop.while') }}</el-radio>
|
||||
<i class="icon el-icon-arrow-right" :class="{'is-active': controller.active}" style="margin-right: 10px"
|
||||
v-if="!isMax"/>
|
||||
<el-radio :disabled="controller.disabled" @change="changeRadio" class="ms-radio ms-radio-margin"
|
||||
v-model="controller.loopType" label="LOOP_COUNT">
|
||||
{{ $t('loop.loops_title') }}
|
||||
</el-radio>
|
||||
<el-radio :disabled="controller.disabled" @change="changeRadio" class="ms-radio ms-radio-margin"
|
||||
v-model="controller.loopType" label="FOREACH">
|
||||
{{ $t('loop.foreach') }}
|
||||
</el-radio>
|
||||
<el-radio :disabled="controller.disabled" @change="changeRadio" class="ms-radio ms-radio-margin"
|
||||
v-model="controller.loopType" label="WHILE">
|
||||
{{ $t('loop.while') }}
|
||||
</el-radio>
|
||||
</template>
|
||||
|
||||
<template v-slot:message>
|
||||
<span v-if="requestResult && requestResult.scenarios && requestResult.scenarios.length > 0 " style="color: #8c939d;margin-right: 10px">
|
||||
</span>
|
||||
<span v-if="requestResult && requestResult.scenarios && requestResult.scenarios.length > 0 "
|
||||
style="color: #8c939d;margin-right: 10px"/>
|
||||
</template>
|
||||
|
||||
<template v-slot:button>
|
||||
<el-button @click="conn" :disabled="!controller.enable" :tip="$t('api_test.run')" icon="el-icon-video-play" style="background-color: #409EFF;color: white;padding: 5px" size="mini" circle/>
|
||||
<el-button
|
||||
:disabled="!controller.enable"
|
||||
:tip="$t('api_test.run')"
|
||||
@click="conn"
|
||||
icon="el-icon-video-play"
|
||||
class="ms-conn"
|
||||
size="mini" circle/>
|
||||
</template>
|
||||
<div v-if="controller.loopType==='LOOP_COUNT'" draggable v-loading="loading">
|
||||
<el-row>
|
||||
|
@ -28,14 +63,19 @@
|
|||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="ms-span ms-radio">{{ $t('loop.interval') }}</span>
|
||||
<el-input-number size="small" v-model="controller.countController.interval" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="0" :step="1000"/>
|
||||
<el-input-number
|
||||
v-model="controller.countController.interval"
|
||||
:disabled="controller.disabled"
|
||||
:placeholder="$t('commons.millisecond')"
|
||||
:max="1000*10000000"
|
||||
:min="0" :step="1000" size="small"/>
|
||||
<span class="ms-span ms-radio">ms</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="ms-span ms-radio">{{ $t('loop.proceed') }}</span>
|
||||
<el-tooltip class="item" effect="dark" :content="$t('api_test.automation.loop_content')" placement="top">>
|
||||
<el-switch v-model="controller.countController.proceed" @change="switchChange"/>
|
||||
|
||||
<el-switch :disabled="controller.disabled" v-model="controller.countController.proceed"
|
||||
@change="switchChange"/>
|
||||
</el-tooltip>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -44,29 +84,64 @@
|
|||
<div v-else-if="controller.loopType==='FOREACH'" draggable v-loading="loading">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-input :placeholder="$t('api_test.automation.loop_return_val')" v-model="controller.forEachController.returnVal" size="small"/>
|
||||
<el-input
|
||||
:disabled="controller.disabled"
|
||||
:placeholder="$t('api_test.automation.loop_return_val')"
|
||||
v-model="controller.forEachController.returnVal" size="small"/>
|
||||
</el-col>
|
||||
<el-col :span="1" style="margin-top: 6px">
|
||||
<span style="margin:10px 10px 10px">in</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-input :placeholder="$t('api_test.automation.loop_input_val')" v-model="controller.forEachController.inputVal" size="small"/>
|
||||
<el-input
|
||||
:disabled="controller.disabled"
|
||||
:placeholder="$t('api_test.automation.loop_input_val')"
|
||||
v-model="controller.forEachController.inputVal" size="small"/>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<span class="ms-span ms-radio">{{ $t('loop.interval') }}</span>
|
||||
<el-input-number size="small" v-model="controller.forEachController.interval" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="0" :step="1000"/>
|
||||
<el-input-number
|
||||
v-model="controller.forEachController.interval"
|
||||
:disabled="controller.disabled"
|
||||
size="small"
|
||||
:placeholder="$t('commons.millisecond')"
|
||||
:max="1000*10000000"
|
||||
:min="0"
|
||||
:step="1000"/>
|
||||
<span class="ms-span ms-radio">ms</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div v-else draggable v-loading="loading">
|
||||
<el-input size="small" v-model="controller.whileController.variable" style="width: 20%" :placeholder="$t('api_test.request.condition_variable')"/>
|
||||
<el-select v-model="controller.whileController.operator" :placeholder="$t('commons.please_select')" size="small" @change="change" style="width: 10%;margin-left: 10px">
|
||||
<el-input
|
||||
v-model="controller.whileController.variable"
|
||||
:disabled="controller.disabled"
|
||||
size="small"
|
||||
:placeholder="$t('api_test.request.condition_variable')"
|
||||
style="width: 20%"
|
||||
/>
|
||||
<el-select
|
||||
v-model="controller.whileController.operator"
|
||||
:disabled="controller.disabled"
|
||||
:placeholder="$t('commons.please_select')" size="small"
|
||||
@change="change" style="width: 10%;margin-left: 10px">
|
||||
<el-option v-for="o in operators" :key="o.value" :label="$t(o.label)" :value="o.value"/>
|
||||
</el-select>
|
||||
<el-input size="small" v-model="controller.whileController.value" :placeholder="$t('api_test.value')" v-if="!hasEmptyOperator" style="width: 20%;margin-left: 20px"/>
|
||||
<el-input
|
||||
v-model="controller.whileController.value"
|
||||
:disabled="controller.disabled"
|
||||
size="small"
|
||||
:placeholder="$t('api_test.value')"
|
||||
v-if="!hasEmptyOperator" style="width: 20%;margin-left: 20px"/>
|
||||
<span class="ms-span ms-radio">{{ $t('loop.timeout') }}</span>
|
||||
<el-input-number size="small" v-model="controller.whileController.timeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="3000" :step="1000"/>
|
||||
<el-input-number
|
||||
v-model="controller.whileController.timeout"
|
||||
:disabled="controller.disabled"
|
||||
size="small"
|
||||
:placeholder="$t('commons.millisecond')"
|
||||
:max="1000*10000000"
|
||||
:min="3000"
|
||||
:step="1000"/>
|
||||
<span class="ms-span ms-radio">ms</span>
|
||||
</div>
|
||||
|
||||
|
@ -75,7 +150,8 @@
|
|||
<i class="el-icon-loading" style="font-size: 16px"/>
|
||||
{{ $t('commons.testing') }}
|
||||
</span>
|
||||
<span class="ms-step-debug-code" :class="node.data.code ==='ERROR'?'ms-req-error':'ms-req-success'" v-if="!loading && !node.data.testing && node.data.debug">
|
||||
<span class="ms-step-debug-code" :class="node.data.code ==='ERROR'?'ms-req-error':'ms-req-success'"
|
||||
v-if="!loading && !node.data.testing && node.data.debug">
|
||||
{{ getCode() }}
|
||||
</span>
|
||||
</template>
|
||||
|
@ -412,4 +488,10 @@ export default {
|
|||
white-space: nowrap;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.ms-conn {
|
||||
background-color: #409EFF;
|
||||
color: white;
|
||||
padding: 5px
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue