Merge remote-tracking branch 'origin/master'

This commit is contained in:
wenyann 2021-01-05 17:37:13 +08:00
commit 2d609fded2
22 changed files with 165 additions and 94 deletions

View File

@ -1,13 +1,10 @@
package io.metersphere.api.dto.definition; package io.metersphere.api.dto.definition;
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
import io.metersphere.base.domain.ApiTestCaseWithBLOBs; import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
import io.metersphere.controller.request.OrderRequest; import io.metersphere.controller.request.OrderRequest;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -32,6 +29,10 @@ public class ApiTestBatchRequest extends ApiTestCaseWithBLOBs {
private String name; private String name;
private String method;
private String path;
private List<String> moduleIds; private List<String> moduleIds;
private List<String> unSelectIds; private List<String> unSelectIds;
@ -39,13 +40,4 @@ public class ApiTestBatchRequest extends ApiTestCaseWithBLOBs {
private String protocol; private String protocol;
private String status; private String status;
public void cleanSelectParam() {
filters = new HashMap<>();
name = null;
moduleIds = new ArrayList<>();
protocol = null;
status = null;
}
} }

View File

@ -324,7 +324,10 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
if (responseAssertionResult.isPass()) { if (responseAssertionResult.isPass()) {
requestResult.addPassAssertions(); requestResult.addPassAssertions();
} }
responseResult.getAssertions().add(responseAssertionResult); //xpath 提取错误会添加断言错误
if (!responseAssertionResult.getMessage().contains("The required item type of the first operand of")) {
responseResult.getAssertions().add(responseAssertionResult);
}
} }
responseResult.setConsole(getConsole()); responseResult.setConsole(getConsole());

View File

@ -1,5 +1,6 @@
package io.metersphere.api.jmeter; package io.metersphere.api.jmeter;
import com.alibaba.fastjson.JSON;
import io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample; import io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample;
import org.apache.jmeter.extractor.JSR223PostProcessor; import org.apache.jmeter.extractor.JSR223PostProcessor;
import org.apache.jmeter.extractor.RegexExtractor; import org.apache.jmeter.extractor.RegexExtractor;
@ -30,12 +31,29 @@ public class JMeterVars {
* @param vars * @param vars
* @param extract * @param extract
*/ */
public static void addVars(Integer testId, JMeterVariables vars, String extract) { public static void addVars(Integer testId, JMeterVariables vars, String extract) {
JMeterVariables vs = new JMeterVariables(); JMeterVariables vs = new JMeterVariables();
if (!StringUtils.isEmpty(extract) && vars != null) { if (!StringUtils.isEmpty(extract) && vars != null) {
List<String> extracts = Arrays.asList(extract.split(";")); List<String> extracts = Arrays.asList(extract.split(";"));
Optional.ofNullable(extracts).orElse(new ArrayList<>()).forEach(item -> { Optional.ofNullable(extracts).orElse(new ArrayList<>()).forEach(item -> {
String nrKey = item + "_matchNr";
Object nr = vars.get(nrKey);
if (nr != null) {
int nrv = 0;
try {
nrv = Integer.valueOf(String.valueOf(nr));
} catch (Exception e) {
}
if (nrv > 0) {
List<Object> data = new ArrayList<>();
for (int i = 1; i < nrv + 1; i++) {
data.add(vars.get(item + "_" + i));
}
String array = JSON.toJSONString(data);
vars.put(item, array);
}
}
vs.put(item, vars.get(item) == null ? "" : vars.get(item)); vs.put(item, vars.get(item) == null ? "" : vars.get(item));
}); });
vs.remove("TESTSTART.MS"); // 标示变量移除 vs.remove("TESTSTART.MS"); // 标示变量移除

View File

@ -97,8 +97,10 @@ public class Swagger2Parser extends ApiImportAbstractParser {
String name = ""; String name = "";
if (StringUtils.isNotBlank(operation.getSummary())) { if (StringUtils.isNotBlank(operation.getSummary())) {
name = operation.getSummary(); name = operation.getSummary();
} else { } else if (StringUtils.isNotBlank(operation.getOperationId())) {
name = operation.getOperationId(); name = operation.getOperationId();
} else {
name = path;
} }
return buildApiDefinition(id, name, path, method); return buildApiDefinition(id, name, path, method);
} }

View File

@ -129,8 +129,10 @@ public class Swagger3Parser extends ApiImportAbstractParser {
String name = ""; String name = "";
if (StringUtils.isNotBlank(operation.getSummary())) { if (StringUtils.isNotBlank(operation.getSummary())) {
name = operation.getSummary(); name = operation.getSummary();
} else { } else if (StringUtils.isNotBlank(operation.getOperationId())) {
name = operation.getOperationId(); name = operation.getOperationId();
} else {
name = path;
} }
return buildApiDefinition(id, name, path, method); return buildApiDefinition(id, name, path, method);
} }

View File

@ -24,6 +24,7 @@ import io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper;
import io.metersphere.commons.constants.*; import io.metersphere.commons.constants.*;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.DateUtils; import io.metersphere.commons.utils.DateUtils;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.ServiceUtils; import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils; import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
@ -316,8 +317,12 @@ public class ApiAutomationService {
boolean isFirst = true; boolean isFirst = true;
for (ApiScenarioWithBLOBs item : apiScenarios) { for (ApiScenarioWithBLOBs item : apiScenarios) {
if (item.getStepTotal() == 0) { if (item.getStepTotal() == 0) {
MSException.throwException(item.getName() + "" + Translator.get("automation_exec_info")); // 只有一个场景且没有测试步骤则提示
break; if (apiScenarios.size() == 1) {
MSException.throwException((item.getName() + "" + Translator.get("automation_exec_info")));
}
LogUtil.warn(item.getName() + "" + Translator.get("automation_exec_info"));
continue;
} }
MsThreadGroup group = new MsThreadGroup(); MsThreadGroup group = new MsThreadGroup();
group.setLabel(item.getName()); group.setLabel(item.getName());
@ -335,14 +340,12 @@ public class ApiAutomationService {
// 多态JSON普通转换会丢失内容需要通过 ObjectMapper 获取 // 多态JSON普通转换会丢失内容需要通过 ObjectMapper 获取
if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) { if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) {
LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"), LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"),
new TypeReference<LinkedList<MsTestElement>>() { new TypeReference<LinkedList<MsTestElement>>() {});
});
scenario.setHashTree(elements); scenario.setHashTree(elements);
} }
if (StringUtils.isNotEmpty(element.getString("variables"))) { if (StringUtils.isNotEmpty(element.getString("variables"))) {
LinkedList<KeyValue> variables = mapper.readValue(element.getString("variables"), LinkedList<KeyValue> variables = mapper.readValue(element.getString("variables"),
new TypeReference<LinkedList<KeyValue>>() { new TypeReference<LinkedList<KeyValue>>() {});
});
scenario.setVariables(variables); scenario.setVariables(variables);
} }
group.setEnableCookieShare(scenario.isEnableCookieShare()); group.setEnableCookieShare(scenario.isEnableCookieShare());

View File

@ -1,5 +1,6 @@
package io.metersphere.api.service; package io.metersphere.api.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
@ -11,6 +12,8 @@ import io.metersphere.api.dto.definition.request.MsTestElement;
import io.metersphere.api.dto.definition.request.MsTestPlan; import io.metersphere.api.dto.definition.request.MsTestPlan;
import io.metersphere.api.dto.definition.request.MsThreadGroup; import io.metersphere.api.dto.definition.request.MsThreadGroup;
import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.scenario.request.RequestType;
import io.metersphere.api.jmeter.JMeterService; import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiDefinitionMapper; import io.metersphere.base.mapper.ApiDefinitionMapper;
@ -373,13 +376,33 @@ public class ApiTestCaseService {
if (request.isSelectAllDate()) { if (request.isSelectAllDate()) {
ids = this.getAllApiCaseIdsByFontedSelect(request.getFilters(), request.getModuleIds(), request.getName(), request.getProjectId(), request.getProtocol(), request.getUnSelectIds(), request.getStatus()); ids = this.getAllApiCaseIdsByFontedSelect(request.getFilters(), request.getModuleIds(), request.getName(), request.getProjectId(), request.getProtocol(), request.getUnSelectIds(), request.getStatus());
} }
request.cleanSelectParam();
ApiTestCaseExample apiDefinitionExample = new ApiTestCaseExample(); ApiTestCaseExample apiDefinitionExample = new ApiTestCaseExample();
apiDefinitionExample.createCriteria().andIdIn(ids); apiDefinitionExample.createCriteria().andIdIn(ids);
ApiTestCaseWithBLOBs apiDefinitionWithBLOBs = new ApiTestCaseWithBLOBs(); if (StringUtils.isNotEmpty(request.getPriority())) {
BeanUtils.copyBean(apiDefinitionWithBLOBs, request); ApiTestCaseWithBLOBs apiDefinitionWithBLOBs = new ApiTestCaseWithBLOBs();
apiDefinitionWithBLOBs.setUpdateTime(System.currentTimeMillis()); apiDefinitionWithBLOBs.setPriority(request.getPriority());
apiTestCaseMapper.updateByExampleSelective(apiDefinitionWithBLOBs, apiDefinitionExample); apiDefinitionWithBLOBs.setUpdateTime(System.currentTimeMillis());
apiTestCaseMapper.updateByExampleSelective(apiDefinitionWithBLOBs, apiDefinitionExample);
}
if ((StringUtils.isNotEmpty(request.getMethod()) || StringUtils.isNotEmpty(request.getPath())) && request.getProtocol().equals(RequestType.HTTP)) {
List<ApiTestCaseWithBLOBs> bloBs = apiTestCaseMapper.selectByExampleWithBLOBs(apiDefinitionExample);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiTestCaseMapper batchMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
bloBs.forEach(apiTestCase -> {
MsHTTPSamplerProxy req = JSON.parseObject(apiTestCase.getRequest(), MsHTTPSamplerProxy.class);
if (StringUtils.isNotEmpty(request.getMethod())) {
req.setMethod(request.getMethod());
}
if (StringUtils.isNotEmpty(request.getPath())) {
req.setPath(request.getPath());
}
String requestStr = JSON.toJSONString(req);
apiTestCase.setRequest(requestStr);
batchMapper.updateByPrimaryKeySelective(apiTestCase);
});
sqlSession.flushStatements();
}
} }
private List<String> getAllApiCaseIdsByFontedSelect(Map<String, List<String>> filters, List<String> moduleIds, String name, String projectId, String protocol, List<String> unSelectIds, String status) { private List<String> getAllApiCaseIdsByFontedSelect(Map<String, List<String>> filters, List<String> moduleIds, String name, String projectId, String protocol, List<String> unSelectIds, String status) {

View File

@ -35,7 +35,7 @@
ref="codeEdit"/> ref="codeEdit"/>
</el-col> </el-col>
<el-col :span="4" class="script-index"> <el-col :span="4" class="script-index">
<ms-dropdown :default-command="jsr223ProcessorData.language" :commands="languages" @command="languageChange"/> <ms-dropdown :default-command="jsr223ProcessorData.scriptLanguage" :commands="languages" @command="languageChange"/>
<div class="template-title">{{$t('api_test.request.processor.code_template')}}</div> <div class="template-title">{{$t('api_test.request.processor.code_template')}}</div>
<div v-for="(template, index) in codeTemplates" :key="index" class="code-template"> <div v-for="(template, index) in codeTemplates" :key="index" class="code-template">
<el-link :disabled="template.disabled" @click="addTemplate(template)">{{template.title}}</el-link> <el-link :disabled="template.disabled" @click="addTemplate(template)">{{template.title}}</el-link>
@ -135,7 +135,7 @@
this.jsr223ProcessorData.script = ""; this.jsr223ProcessorData.script = "";
} }
this.jsr223ProcessorData.script += template.value; this.jsr223ProcessorData.script += template.value;
if (this.jsr223ProcessorData.language === 'beanshell') { if (this.jsr223ProcessorData.scriptLanguage === 'beanshell') {
this.jsr223ProcessorData.script += ';'; this.jsr223ProcessorData.script += ';';
} }
this.reload(); this.reload();
@ -151,7 +151,7 @@
this.$nextTick(() => (this.isCodeEditAlive = true)); this.$nextTick(() => (this.isCodeEditAlive = true));
}, },
languageChange(language) { languageChange(language) {
this.jsr223ProcessorData.language = language; this.jsr223ProcessorData.scriptLanguage = language;
}, },
changeActive() { changeActive() {
this.jsr223ProcessorData.active = !this.jsr223ProcessorData.active; this.jsr223ProcessorData.active = !this.jsr223ProcessorData.active;

View File

@ -3,9 +3,10 @@
:is-api-list-enable="isApiListEnable" :is-api-list-enable="isApiListEnable"
@isApiListEnableChange="isApiListEnableChange"> @isApiListEnableChange="isApiListEnableChange">
<ms-environment-select :project-id="projectId" v-if="isTestPlan" :is-read-only="isReadOnly" @setEnvironment="setEnvironment"/> <ms-environment-select :project-id="projectId" v-if="isTestPlan" :is-read-only="isReadOnly" @setEnvironment="setEnvironment"/>
<el-input placeholder="搜索" @blur="initTable" class="search-input" size="small" @keyup.enter.native="initTable" v-model="condition.name"/>
<el-input placeholder="搜索" @blur="initTable" class="search-input" size="small" @keyup.enter.native="initTable" v-model="condition.name"/>
<el-table v-loading="result.loading" <el-table v-loading="result.loading"
border border
@ -253,8 +254,8 @@
.search-input { .search-input {
float: right; float: right;
width: 300px; width: 30%;
/*margin-bottom: 20px;*/ margin-bottom: 20px;
margin-right: 20px; margin-right: 20px;
} }

View File

@ -14,7 +14,10 @@
<el-option v-for="(type, index) in typeArr" :key="index" :value="type.id" :label="type.name"/> <el-option v-for="(type, index) in typeArr" :key="index" :value="type.id" :label="type.name"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="$t('test_track.case.updated_attr_value')" prop="value"> <el-form-item v-if="form.type ==='path'" :label="$t('test_track.case.updated_attr_value')" prop="value">
<el-input size="small" v-model="form.value"/>
</el-form-item>
<el-form-item v-else :label="$t('test_track.case.updated_attr_value')" prop="value">
<el-select v-model="form.value" style="width: 80%" :filterable="filterable"> <el-select v-model="form.value" style="width: 80%" :filterable="filterable">
<el-option v-for="(option, index) in options" :key="index" :value="option.id" :label="option.label"> <el-option v-for="(option, index) in options" :key="index" :value="option.id" :label="option.label">
<div v-if="option.email"> <div v-if="option.email">

View File

@ -43,7 +43,8 @@
<el-option :key="0" :value="''"> <el-option :key="0" :value="''">
<div style="margin-left: 40px"> <div style="margin-left: 40px">
<span style="font-size: 14px;color: #606266;font-weight: 48.93">{{$t('api_test.definition.select_comp.no_data')}}, <span style="font-size: 14px;color: #606266;font-weight: 48.93">{{$t('api_test.definition.select_comp.no_data')}},
</span><el-link type="primary" @click="createModules">{{$t('api_test.definition.select_comp.add_data')}}</el-link> </span>
<el-link type="primary" @click="createModules">{{$t('api_test.definition.select_comp.add_data')}}</el-link>
</div> </div>
</el-option> </el-option>
</div> </div>
@ -106,7 +107,6 @@
import {REQ_METHOD, API_STATUS} from "../../model/JsonData"; import {REQ_METHOD, API_STATUS} from "../../model/JsonData";
import MsJsr233Processor from "../processor/Jsr233Processor"; import MsJsr233Processor from "../processor/Jsr233Processor";
import {KeyValue} from "../../model/ApiTestModel"; import {KeyValue} from "../../model/ApiTestModel";
// import {append} from "./../../../../track/common/NodeTree";
export default { export default {
name: "MsAddCompleteHttpApi", name: "MsAddCompleteHttpApi",
@ -172,7 +172,7 @@
} }
}) })
}, },
createModules(){ createModules() {
this.$emit("createRootModelInTree"); this.$emit("createRootModelInTree");
}, },
getPath(id) { getPath(id) {
@ -185,7 +185,7 @@
return path[0].path; return path[0].path;
}, },
urlChange() { urlChange() {
if (!this.httpForm.path) return; if (!this.httpForm.path || this.httpForm.path.indexOf('?') === -1) return;
let url = this.getURL(this.addProtocol(this.httpForm.path)); let url = this.getURL(this.addProtocol(this.httpForm.path));
if (url) { if (url) {
this.httpForm.path = decodeURIComponent("/" + url.hostname + url.pathname); this.httpForm.path = decodeURIComponent("/" + url.hostname + url.pathname);
@ -202,7 +202,6 @@
getURL(urlStr) { getURL(urlStr) {
try { try {
let url = new URL(urlStr); let url = new URL(urlStr);
console.log(urlStr)
url.searchParams.forEach((value, key) => { url.searchParams.forEach((value, key) => {
if (key && value) { if (key && value) {
this.request.arguments.splice(0, 0, new KeyValue({name: key, required: false, value: value})); this.request.arguments.splice(0, 0, new KeyValue({name: key, required: false, value: value}));

View File

@ -15,7 +15,7 @@ export default class JSR223PostProcessor extends PostProcessor {
constructor(options = DEFAULT_OPTIONS) { constructor(options = DEFAULT_OPTIONS) {
super(options); super(options);
this.type = "JSR223PostProcessor"; this.type = "JSR223PostProcessor";
this.scriptLanguage = "java"; this.scriptLanguage = "beanshell";
this.parameters = []; this.parameters = [];
this.filename = undefined; this.filename = undefined;
this.cacheKey = true; this.cacheKey = true;

View File

@ -15,7 +15,7 @@ export default class JSR223PreProcessor extends PostProcessor {
constructor(options = DEFAULT_OPTIONS) { constructor(options = DEFAULT_OPTIONS) {
super(options); super(options);
this.type = "JSR223PreProcessor"; this.type = "JSR223PreProcessor";
this.scriptLanguage = "java"; this.scriptLanguage = "beanshell";
this.parameters = []; this.parameters = [];
this.filename = undefined; this.filename = undefined;
this.cacheKey = undefined; this.cacheKey = undefined;

View File

@ -101,14 +101,12 @@
import MsBottomContainer from "../BottomContainer"; import MsBottomContainer from "../BottomContainer";
import ShowMoreBtn from "../../../../track/case/components/ShowMoreBtn"; import ShowMoreBtn from "../../../../track/case/components/ShowMoreBtn";
import MsBatchEdit from "../basis/BatchEdit"; import MsBatchEdit from "../basis/BatchEdit";
import {API_METHOD_COLOUR, CASE_PRIORITY} from "../../model/JsonData"; import {API_METHOD_COLOUR, CASE_PRIORITY, REQ_METHOD} from "../../model/JsonData";
import {getCurrentProjectID} from "@/common/js/utils"; import {getCurrentProjectID} from "@/common/js/utils";
import ApiListContainer from "./ApiListContainer"; import ApiListContainer from "./ApiListContainer";
import PriorityTableItem from "../../../../track/common/tableItems/planview/PriorityTableItem"; import PriorityTableItem from "../../../../track/common/tableItems/planview/PriorityTableItem";
import ApiCaseList from "../case/ApiCaseList"; import ApiCaseList from "../case/ApiCaseList";
import {_filter, _sort} from "../../../../../../common/js/utils"; import {_filter, _sort} from "../../../../../../common/js/utils";
import TestPlanCaseListHeader from "../../../../track/plan/view/comonents/api/TestPlanCaseListHeader";
import MsEnvironmentSelect from "../case/MsEnvironmentSelect";
import {_handleSelect, _handleSelectAll} from "../../../../../../common/js/tableUtils"; import {_handleSelect, _handleSelectAll} from "../../../../../../common/js/tableUtils";
export default { export default {
@ -141,6 +139,8 @@
], ],
typeArr: [ typeArr: [
{id: 'priority', name: this.$t('test_track.case.priority')}, {id: 'priority', name: this.$t('test_track.case.priority')},
{id: 'method', name: this.$t('api_test.definition.api_type')},
{id: 'path', name: this.$t('api_test.request.path')},
], ],
priorityFilters: [ priorityFilters: [
{text: 'P0', value: 'P0'}, {text: 'P0', value: 'P0'},
@ -150,6 +150,7 @@
], ],
valueArr: { valueArr: {
priority: CASE_PRIORITY, priority: CASE_PRIORITY,
method: REQ_METHOD,
}, },
methodColorMap: new Map(API_METHOD_COLOUR), methodColorMap: new Map(API_METHOD_COLOUR),
tableData: [], tableData: [],
@ -159,8 +160,8 @@
screenHeight: document.documentElement.clientHeight - 330,// screenHeight: document.documentElement.clientHeight - 330,//
environmentId: undefined, environmentId: undefined,
selectAll: false, selectAll: false,
unSelection:[], unSelection: [],
selectDataCounts:0, selectDataCounts: 0,
} }
}, },
props: { props: {
@ -233,7 +234,7 @@
this.condition.status = "Trash"; this.condition.status = "Trash";
this.condition.moduleIds = []; this.condition.moduleIds = [];
} }
this.selectAll = false; this.selectAll = false;
this.unSelection = []; this.unSelection = [];
this.selectDataCounts = 0; this.selectDataCounts = 0;
this.condition.projectId = getCurrentProjectID(); this.condition.projectId = getCurrentProjectID();
@ -245,7 +246,7 @@
this.result = this.$post('/api/testcase/list/' + this.currentPage + "/" + this.pageSize, this.condition, response => { this.result = this.$post('/api/testcase/list/' + this.currentPage + "/" + this.pageSize, this.condition, response => {
this.total = response.data.itemCount; this.total = response.data.itemCount;
this.tableData = response.data.listObject; this.tableData = response.data.listObject;
this.unSelection = response.data.listObject.map(s=>s.id); this.unSelection = response.data.listObject.map(s => s.id);
}); });
} }
}, },
@ -312,24 +313,24 @@
}, },
handleDeleteBatch() { handleDeleteBatch() {
// if (this.trashEnable) { // if (this.trashEnable) {
this.$alert(this.$t('api_test.definition.request.delete_confirm') + "", '', { this.$alert(this.$t('api_test.definition.request.delete_confirm') + "", '', {
confirmButtonText: this.$t('commons.confirm'), confirmButtonText: this.$t('commons.confirm'),
callback: (action) => { callback: (action) => {
if (action === 'confirm') { if (action === 'confirm') {
let obj = {}; let obj = {};
obj.projectId = getCurrentProjectID(); obj.projectId = getCurrentProjectID();
obj.selectAllDate = this.isSelectAllDate; obj.selectAllDate = this.isSelectAllDate;
obj.unSelectIds = this.unSelection; obj.unSelectIds = this.unSelection;
obj.ids = Array.from(this.selectRows).map(row => row.id); obj.ids = Array.from(this.selectRows).map(row => row.id);
obj = Object.assign(obj, this.condition); obj = Object.assign(obj, this.condition);
this.$post('/api/testcase/deleteBatchByParam/', obj , () => { this.$post('/api/testcase/deleteBatchByParam/', obj, () => {
this.selectRows.clear(); this.selectRows.clear();
this.initTable(); this.initTable();
this.$success(this.$t('commons.delete_success')); this.$success(this.$t('commons.delete_success'));
}); });
}
} }
}); }
});
// } else { // } else {
// this.$alert(this.$t('api_test.definition.request.delete_confirm') + "", '', { // this.$alert(this.$t('api_test.definition.request.delete_confirm') + "", '', {
// confirmButtonText: this.$t('commons.confirm'), // confirmButtonText: this.$t('commons.confirm'),
@ -355,7 +356,6 @@
let param = {}; let param = {};
param[form.type] = form.value; param[form.type] = form.value;
param.ids = ids; param.ids = ids;
param.projectId = getCurrentProjectID(); param.projectId = getCurrentProjectID();
param.selectAllDate = this.isSelectAllDate; param.selectAllDate = this.isSelectAllDate;
param.unSelectIds = this.unSelection; param.unSelectIds = this.unSelection;
@ -367,11 +367,11 @@
}, },
handleDelete(apiCase) { handleDelete(apiCase) {
// if (this.trashEnable) { // if (this.trashEnable) {
this.$get('/api/testcase/delete/' + apiCase.id, () => { this.$get('/api/testcase/delete/' + apiCase.id, () => {
this.$success(this.$t('commons.delete_success')); this.$success(this.$t('commons.delete_success'));
this.initTable(); this.initTable();
}); });
return; return;
// } // }
// this.$alert(this.$t('api_test.definition.request.delete_confirm') + ' ' + apiCase.name + " ", '', { // this.$alert(this.$t('api_test.definition.request.delete_confirm') + ' ' + apiCase.name + " ", '', {
// confirmButtonText: this.$t('commons.confirm'), // confirmButtonText: this.$t('commons.confirm'),
@ -389,16 +389,16 @@
setEnvironment(data) { setEnvironment(data) {
this.environmentId = data.id; this.environmentId = data.id;
}, },
selectRowsCount(selection){ selectRowsCount(selection) {
let selectedIDs = this.getIds(selection); let selectedIDs = this.getIds(selection);
let allIDs = this.tableData.map(s=>s.id); let allIDs = this.tableData.map(s => s.id);
this.unSelection = allIDs.filter(function (val) { this.unSelection = allIDs.filter(function (val) {
return selectedIDs.indexOf(val) === -1 return selectedIDs.indexOf(val) === -1
}); });
if(this.isSelectAllDate){ if (this.isSelectAllDate) {
this.selectDataCounts =this.total - this.unSelection.length; this.selectDataCounts = this.total - this.unSelection.length;
}else { } else {
this.selectDataCounts =selection.size; this.selectDataCounts = selection.size;
} }
}, },
isSelectDataAll(dataType) { isSelectDataAll(dataType) {
@ -409,9 +409,9 @@
this.$refs.caseTable.toggleAllSelection(true); this.$refs.caseTable.toggleAllSelection(true);
} }
}, },
getIds(rowSets){ getIds(rowSets) {
let rowArray = Array.from(rowSets) let rowArray = Array.from(rowSets)
let ids = rowArray.map(s=>s.id); let ids = rowArray.map(s => s.id);
return ids; return ids;
} }
}, },

View File

@ -80,6 +80,7 @@
<el-table-column <el-table-column
prop="casePassingRate" prop="casePassingRate"
:width="100"
:label="$t('api_test.definition.api_case_passing_rate')" :label="$t('api_test.definition.api_case_passing_rate')"
show-overflow-tooltip/> show-overflow-tooltip/>

View File

@ -122,7 +122,7 @@ export default {
<style scoped> <style scoped>
.protocol-select { .protocol-select {
width: 95px; width: 92px;
height: 30px; height: 30px;
} }

View File

@ -34,7 +34,7 @@
ref="codeEdit"/> ref="codeEdit"/>
</el-col> </el-col>
<el-col :span="4" class="script-index"> <el-col :span="4" class="script-index">
<ms-dropdown :default-command="jsr223ProcessorData.language" :commands="languages" @command="languageChange"/> <ms-dropdown :default-command="jsr223ProcessorData.scriptLanguage" :commands="languages" @command="languageChange"/>
<div class="template-title">{{$t('api_test.request.processor.code_template')}}</div> <div class="template-title">{{$t('api_test.request.processor.code_template')}}</div>
<div v-for="(template, index) in codeTemplates" :key="index" class="code-template"> <div v-for="(template, index) in codeTemplates" :key="index" class="code-template">
<el-link :disabled="template.disabled" @click="addTemplate(template)">{{template.title}}</el-link> <el-link :disabled="template.disabled" @click="addTemplate(template)">{{template.title}}</el-link>
@ -140,7 +140,7 @@
this.jsr223ProcessorData.script = ""; this.jsr223ProcessorData.script = "";
} }
this.jsr223ProcessorData.script += template.value; this.jsr223ProcessorData.script += template.value;
if (this.jsr223ProcessorData.language === 'beanshell') { if (this.jsr223ProcessorData.scriptLanguage === 'beanshell') {
this.jsr223ProcessorData.script += ';'; this.jsr223ProcessorData.script += ';';
} }
this.reload(); this.reload();
@ -156,7 +156,7 @@
this.$nextTick(() => (this.isCodeEditAlive = true)); this.$nextTick(() => (this.isCodeEditAlive = true));
}, },
languageChange(language) { languageChange(language) {
this.jsr223ProcessorData.language = language; this.jsr223ProcessorData.scriptLanguage = language;
}, },
changeActive() { changeActive() {
this.active = !this.active; this.active = !this.active;

View File

@ -842,8 +842,7 @@ export class JSR223Processor extends BaseConfig {
this.active = false; this.active = false;
this.type = "JSR223Processor"; this.type = "JSR223Processor";
this.script = undefined; this.script = undefined;
this.language = "beanshell"; this.scriptLanguage = "beanshell";
this.scriptLanguage = "java";
this.enable = true; this.enable = true;
this.hashTree = []; this.hashTree = [];
this.set(options); this.set(options);

View File

@ -118,7 +118,21 @@ export default {
}, },
copyRequest(index) { copyRequest(index) {
let request = this.scenario.requests[index]; let request = this.scenario.requests[index];
this.scenario.requests.push(new RequestFactory(request)); let item = new RequestFactory(request);
if (item.body && item.body.kvs) {
item.body.kvs.forEach(kv => {
let files = [];
if (kv.files) {
kv.files.forEach(file => {
let fileCopy = {};
Object.assign(fileCopy, file);
files.push(fileCopy);
})
}
kv.files = files;
});
}
this.scenario.requests.push(item);
}, },
disableRequest(index) { disableRequest(index) {
this.scenario.requests[index].enable = false; this.scenario.requests[index].enable = false;

View File

@ -59,7 +59,11 @@
<style scoped> <style scoped>
.el-dialog { .el-dialog {
min-height: 700px; min-height: 600px;
}
.tree-aside {
max-height: 600px;
} }
.el-dialog >>> .el-dialog__body { .el-dialog >>> .el-dialog__body {

View File

@ -9,7 +9,7 @@
<template> <template>
<ckeditor v-if="!isReportView" :editor="editor" v-model="preview.content" :config="editorConfig"></ckeditor> <ckeditor v-if="!isReportView" :editor="editor" v-model="preview.content" :config="editorConfig"></ckeditor>
<div v-if="isReportView" v-html="preview.content"></div> <div class="rich-text-content" v-if="isReportView" v-html="preview.content"></div>
</template> </template>
</common-component> </common-component>
@ -53,4 +53,11 @@
<style scoped> <style scoped>
.rich-text-content >>> .table td {
border: solid 1px #e6e6e6;
min-width: 2em;
padding: .4em;
}
</style> </style>

View File

@ -142,9 +142,9 @@ html,body {
border: 1px solid #DCDFE6; border: 1px solid #DCDFE6;
border-radius:5px; border-radius:5px;
padding: 0px; padding: 0px;
margin-top: 5px; margin-top: 10px;
display: inline-block; display: inline-block;
margin-top: 25px; /*margin-top: 25px;*/
width: 50px; width: 50px;
} }
@ -164,8 +164,8 @@ html,body {
.ms-select-all .el-icon-arrow-down { .ms-select-all .el-icon-arrow-down {
position: absolute; position: absolute;
display: inline-block; display: inline-block;
top: -3px; top: -7px;
left: -40px; left: -38px;
width: 30px; width: 30px;
} }
/* 表格全选样式 --> */ /* 表格全选样式 --> */