Merge branch 'v1.6'
This commit is contained in:
commit
f3dc01d3a9
|
@ -5,9 +5,9 @@ pipeline {
|
|||
}
|
||||
}
|
||||
options { quietPeriod(600) }
|
||||
parameters {
|
||||
string(name: 'IMAGE_NAME', defaultValue: 'metersphere', description: '构建后的 Docker 镜像名称')
|
||||
string(name: 'IMAGE_PREFIX', defaultValue: 'registry.cn-qingdao.aliyuncs.com/metersphere', description: '构建后的 Docker 镜像带仓库名的前缀')
|
||||
environment {
|
||||
IMAGE_NAME = 'metersphere'
|
||||
IMAGE_PREFIX = 'registry.cn-qingdao.aliyuncs.com/metersphere'
|
||||
}
|
||||
stages {
|
||||
stage('Build/Test') {
|
||||
|
|
|
@ -324,7 +324,10 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
|||
if (responseAssertionResult.isPass()) {
|
||||
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());
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.metersphere.api.jmeter;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample;
|
||||
import org.apache.jmeter.extractor.JSR223PostProcessor;
|
||||
import org.apache.jmeter.extractor.RegexExtractor;
|
||||
|
@ -30,12 +31,29 @@ public class JMeterVars {
|
|||
* @param vars
|
||||
* @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();
|
||||
|
||||
if (!StringUtils.isEmpty(extract) && vars != null) {
|
||||
List<String> extracts = Arrays.asList(extract.split(";"));
|
||||
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.remove("TESTSTART.MS"); // 标示变量移除
|
||||
|
|
|
@ -97,8 +97,10 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
|||
String name = "";
|
||||
if (StringUtils.isNotBlank(operation.getSummary())) {
|
||||
name = operation.getSummary();
|
||||
} else {
|
||||
} else if (StringUtils.isNotBlank(operation.getOperationId())) {
|
||||
name = operation.getOperationId();
|
||||
} else {
|
||||
name = path;
|
||||
}
|
||||
return buildApiDefinition(id, name, path, method);
|
||||
}
|
||||
|
|
|
@ -129,8 +129,10 @@ public class Swagger3Parser extends ApiImportAbstractParser {
|
|||
String name = "";
|
||||
if (StringUtils.isNotBlank(operation.getSummary())) {
|
||||
name = operation.getSummary();
|
||||
} else {
|
||||
} else if (StringUtils.isNotBlank(operation.getOperationId())) {
|
||||
name = operation.getOperationId();
|
||||
} else {
|
||||
name = path;
|
||||
}
|
||||
return buildApiDefinition(id, name, path, method);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import io.metersphere.track.service.TestPlanApiCaseService;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
@ -60,6 +61,9 @@ public class ApiDefinitionExecResultService {
|
|||
}
|
||||
|
||||
public void deleteByResourceIds(List<String> ids) {
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
ApiDefinitionExecResultExample example = new ApiDefinitionExecResultExample();
|
||||
example.createCriteria().andResourceIdIn(ids);
|
||||
apiDefinitionExecResultMapper.deleteByExample(example);
|
||||
|
|
|
@ -88,7 +88,7 @@ public class JmeterFileService {
|
|||
if (!CollectionUtils.isEmpty(testData)) {
|
||||
for (String k : testData.keySet()) {
|
||||
String v = testData.get(k);
|
||||
files.put("k", v.getBytes(StandardCharsets.UTF_8));
|
||||
files.put(k, v.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ public class JmeterFileService {
|
|||
if (!CollectionUtils.isEmpty(jarFiles)) {
|
||||
for (String k : jarFiles.keySet()) {
|
||||
byte[] v = jarFiles.get(k);
|
||||
files.put("k", v);
|
||||
files.put(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
ref="codeEdit"/>
|
||||
</el-col>
|
||||
<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 v-for="(template, index) in codeTemplates" :key="index" class="code-template">
|
||||
<el-link :disabled="template.disabled" @click="addTemplate(template)">{{template.title}}</el-link>
|
||||
|
@ -135,7 +135,7 @@
|
|||
this.jsr223ProcessorData.script = "";
|
||||
}
|
||||
this.jsr223ProcessorData.script += template.value;
|
||||
if (this.jsr223ProcessorData.language === 'beanshell') {
|
||||
if (this.jsr223ProcessorData.scriptLanguage === 'beanshell') {
|
||||
this.jsr223ProcessorData.script += ';';
|
||||
}
|
||||
this.reload();
|
||||
|
@ -151,7 +151,7 @@
|
|||
this.$nextTick(() => (this.isCodeEditAlive = true));
|
||||
},
|
||||
languageChange(language) {
|
||||
this.jsr223ProcessorData.language = language;
|
||||
this.jsr223ProcessorData.scriptLanguage = language;
|
||||
},
|
||||
changeActive() {
|
||||
this.jsr223ProcessorData.active = !this.jsr223ProcessorData.active;
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
:is-api-list-enable="isApiListEnable"
|
||||
@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"
|
||||
border
|
||||
|
@ -253,8 +254,8 @@
|
|||
|
||||
.search-input {
|
||||
float: right;
|
||||
width: 300px;
|
||||
/*margin-bottom: 20px;*/
|
||||
width: 30%;
|
||||
margin-bottom: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ export default class JSR223PostProcessor extends PostProcessor {
|
|||
constructor(options = DEFAULT_OPTIONS) {
|
||||
super(options);
|
||||
this.type = "JSR223PostProcessor";
|
||||
this.scriptLanguage = "java";
|
||||
this.scriptLanguage = "beanshell";
|
||||
this.parameters = [];
|
||||
this.filename = undefined;
|
||||
this.cacheKey = true;
|
||||
|
|
|
@ -15,7 +15,7 @@ export default class JSR223PreProcessor extends PostProcessor {
|
|||
constructor(options = DEFAULT_OPTIONS) {
|
||||
super(options);
|
||||
this.type = "JSR223PreProcessor";
|
||||
this.scriptLanguage = "java";
|
||||
this.scriptLanguage = "beanshell";
|
||||
this.parameters = [];
|
||||
this.filename = undefined;
|
||||
this.cacheKey = undefined;
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
|
||||
<el-table-column
|
||||
prop="casePassingRate"
|
||||
:width="100"
|
||||
:label="$t('api_test.definition.api_case_passing_rate')"
|
||||
show-overflow-tooltip/>
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ export default {
|
|||
<style scoped>
|
||||
|
||||
.protocol-select {
|
||||
width: 95px;
|
||||
width: 92px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
ref="codeEdit"/>
|
||||
</el-col>
|
||||
<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 v-for="(template, index) in codeTemplates" :key="index" class="code-template">
|
||||
<el-link :disabled="template.disabled" @click="addTemplate(template)">{{template.title}}</el-link>
|
||||
|
@ -140,7 +140,7 @@
|
|||
this.jsr223ProcessorData.script = "";
|
||||
}
|
||||
this.jsr223ProcessorData.script += template.value;
|
||||
if (this.jsr223ProcessorData.language === 'beanshell') {
|
||||
if (this.jsr223ProcessorData.scriptLanguage === 'beanshell') {
|
||||
this.jsr223ProcessorData.script += ';';
|
||||
}
|
||||
this.reload();
|
||||
|
@ -156,7 +156,7 @@
|
|||
this.$nextTick(() => (this.isCodeEditAlive = true));
|
||||
},
|
||||
languageChange(language) {
|
||||
this.jsr223ProcessorData.language = language;
|
||||
this.jsr223ProcessorData.scriptLanguage = language;
|
||||
},
|
||||
changeActive() {
|
||||
this.active = !this.active;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</el-link>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="ref">{{ $t('api_test.automation.view_ref') }}</el-dropdown-item>
|
||||
<el-dropdown-item :disabled="isCaseEdit" command="add_plan">{{ $t('api_test.automation.batch_add_plan') }}</el-dropdown-item>
|
||||
<!--<el-dropdown-item :disabled="isCaseEdit" command="add_plan">{{ $t('api_test.automation.batch_add_plan') }}</el-dropdown-item>-->
|
||||
</el-dropdown-menu>
|
||||
<ms-reference-view ref="viewRef"/>
|
||||
<!--测试计划-->
|
||||
|
|
|
@ -842,8 +842,7 @@ export class JSR223Processor extends BaseConfig {
|
|||
this.active = false;
|
||||
this.type = "JSR223Processor";
|
||||
this.script = undefined;
|
||||
this.language = "beanshell";
|
||||
this.scriptLanguage = "java";
|
||||
this.scriptLanguage = "beanshell";
|
||||
this.enable = true;
|
||||
this.hashTree = [];
|
||||
this.set(options);
|
||||
|
|
|
@ -118,7 +118,21 @@ export default {
|
|||
},
|
||||
copyRequest(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) {
|
||||
this.scenario.requests[index].enable = false;
|
||||
|
|
|
@ -59,7 +59,11 @@
|
|||
<style scoped>
|
||||
|
||||
.el-dialog {
|
||||
min-height: 700px;
|
||||
min-height: 600px;
|
||||
}
|
||||
|
||||
.tree-aside {
|
||||
max-height: 600px;
|
||||
}
|
||||
|
||||
.el-dialog >>> .el-dialog__body {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<template>
|
||||
<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>
|
||||
|
||||
</common-component>
|
||||
|
@ -53,4 +53,11 @@
|
|||
|
||||
<style scoped>
|
||||
|
||||
.rich-text-content >>> .table td {
|
||||
border: solid 1px #e6e6e6;
|
||||
min-width: 2em;
|
||||
padding: .4em;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
|
|
@ -142,9 +142,9 @@ html,body {
|
|||
border: 1px solid #DCDFE6;
|
||||
border-radius:5px;
|
||||
padding: 0px;
|
||||
margin-top: 5px;
|
||||
margin-top: 10px;
|
||||
display: inline-block;
|
||||
margin-top: 25px;
|
||||
/*margin-top: 25px;*/
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
|
@ -164,8 +164,8 @@ html,body {
|
|||
.ms-select-all .el-icon-arrow-down {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
top: -3px;
|
||||
left: -40px;
|
||||
top: -7px;
|
||||
left: -38px;
|
||||
width: 30px;
|
||||
}
|
||||
/* 表格全选样式 --> */
|
||||
|
|
Loading…
Reference in New Issue