Merge branch 'v1.4' of https://github.com/metersphere/metersphere into v1.4
This commit is contained in:
commit
0dbf3b943d
|
@ -0,0 +1,20 @@
|
||||||
|
package io.metersphere.api.dto.scenario.assertions;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class AssertionJSR223 extends AssertionType {
|
||||||
|
private String variable;
|
||||||
|
private String operator;
|
||||||
|
private String value;
|
||||||
|
private String desc;
|
||||||
|
private String name;
|
||||||
|
private String script;
|
||||||
|
private String language;
|
||||||
|
|
||||||
|
public AssertionJSR223() {
|
||||||
|
setType(AssertionType.JSR223);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ public class AssertionType {
|
||||||
public final static String REGEX = "Regex";
|
public final static String REGEX = "Regex";
|
||||||
public final static String DURATION = "Duration";
|
public final static String DURATION = "Duration";
|
||||||
public final static String JSON_PATH = "JSONPath";
|
public final static String JSON_PATH = "JSONPath";
|
||||||
|
public final static String JSR223 = "JSR223";
|
||||||
public final static String TEXT = "Text";
|
public final static String TEXT = "Text";
|
||||||
|
|
||||||
private String type;
|
private String type;
|
||||||
|
|
|
@ -8,5 +8,6 @@ import java.util.List;
|
||||||
public class Assertions {
|
public class Assertions {
|
||||||
private List<AssertionRegex> regex;
|
private List<AssertionRegex> regex;
|
||||||
private List<AssertionJsonPath> jsonPath;
|
private List<AssertionJsonPath> jsonPath;
|
||||||
|
private List<AssertionJSR223> jsr223;
|
||||||
private AssertionDuration duration;
|
private AssertionDuration duration;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col class="assertion-btn">
|
<el-col class="assertion-btn">
|
||||||
<el-button :disabled="isReadOnly" type="danger" size="mini" icon="el-icon-delete" circle @click="remove" v-if="edit"/>
|
<el-button :disabled="isReadOnly" type="danger" size="mini" icon="el-icon-delete" circle @click="remove" v-if="edit"/>
|
||||||
<el-button :disabled="isReadOnly" type="primary" size="small" @click="add" v-else>Add</el-button>
|
<el-button :disabled="isReadOnly" type="primary" size="small" @click="add" v-else>
|
||||||
|
{{ $t('api_test.request.assertions.add') }}
|
||||||
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col class="assertion-btn">
|
<el-col class="assertion-btn">
|
||||||
<el-button :disabled="isReadOnly" type="danger" size="mini" icon="el-icon-delete" circle @click="remove" v-if="edit"/>
|
<el-button :disabled="isReadOnly" type="danger" size="mini" icon="el-icon-delete" circle @click="remove" v-if="edit"/>
|
||||||
<el-button :disabled="isReadOnly" type="primary" size="small" @click="add" v-else>Add</el-button>
|
<el-button :disabled="isReadOnly" type="primary" size="small" @click="add" v-else>
|
||||||
|
{{ $t('api_test.request.assertions.add') }}
|
||||||
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,261 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-row type="flex" align="middle" v-if="!edit">
|
||||||
|
<div class="assertion-item label">
|
||||||
|
{{ assertion.desc }}
|
||||||
|
</div>
|
||||||
|
<div class="assertion-item btn">
|
||||||
|
<el-button :disabled="isReadOnly" type="success" size="small" @click="detail">
|
||||||
|
{{ $t('commons.edit') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button :disabled="isReadOnly" type="primary" size="small" @click="add">
|
||||||
|
{{ $t('api_test.request.assertions.add') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
<el-row type="flex" justify="space-between" align="middle" v-else>
|
||||||
|
<div class="assertion-item label">
|
||||||
|
{{ assertion.desc }}
|
||||||
|
</div>
|
||||||
|
<div class="assertion-item btn circle">
|
||||||
|
<el-button :disabled="isReadOnly" type="success" size="mini" icon="el-icon-edit" circle @click="detail"/>
|
||||||
|
<el-button :disabled="isReadOnly" type="danger" size="mini" icon="el-icon-delete" circle @click="remove"/>
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-dialog :title="$t('api_test.request.assertions.script')" :visible.sync="visible" width="900px">
|
||||||
|
<el-row type="flex" justify="space-between" align="middle" class="quick-script-block">
|
||||||
|
<div class="assertion-item input">
|
||||||
|
<el-input size="small" v-model="assertion.variable"
|
||||||
|
:placeholder="$t('api_test.request.assertions.variable_name')" @change="quickScript"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="assertion-item select">
|
||||||
|
<el-select v-model="assertion.operator" :placeholder="$t('commons.please_select')" size="small"
|
||||||
|
@change="changeOperator">
|
||||||
|
<el-option v-for="o in operators" :key="o.value" :label="$t(o.label)" :value="o.value"/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="assertion-item input">
|
||||||
|
<el-input size="small" v-model="assertion.value" :placeholder="$t('api_test.value')"
|
||||||
|
@change="quickScript" v-if="!hasEmptyOperator"/>
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
<el-input size="small" v-model="assertion.desc" :placeholder="$t('api_test.request.assertions.script_name')"
|
||||||
|
class="quick-script-block"/>
|
||||||
|
<ms-jsr233-processor ref="jsr233" :is-read-only="isReadOnly" :jsr223-processor="assertion" :templates="templates"
|
||||||
|
:height="300"/>
|
||||||
|
<template v-slot:footer v-if="!edit">
|
||||||
|
<ms-dialog-footer
|
||||||
|
@cancel="close"
|
||||||
|
@confirm="confirm"/>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {AssertionJSR223} from "../../model/ScenarioModel";
|
||||||
|
import MsJsr233Processor from "@/business/components/api/test/components/processor/Jsr233Processor";
|
||||||
|
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MsApiAssertionJsr223",
|
||||||
|
components: {MsDialogFooter, MsJsr233Processor},
|
||||||
|
props: {
|
||||||
|
assertion: {
|
||||||
|
type: AssertionJSR223,
|
||||||
|
default: () => {
|
||||||
|
return new AssertionJSR223();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
edit: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
index: Number,
|
||||||
|
list: Array,
|
||||||
|
callback: Function,
|
||||||
|
isReadOnly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
visible: false,
|
||||||
|
operators: {
|
||||||
|
EQ: {
|
||||||
|
label: "commons.adv_search.operators.equals",
|
||||||
|
value: "=="
|
||||||
|
},
|
||||||
|
NE: {
|
||||||
|
label: "commons.adv_search.operators.not_equals",
|
||||||
|
value: "!="
|
||||||
|
},
|
||||||
|
CONTAINS: {
|
||||||
|
label: "commons.adv_search.operators.like",
|
||||||
|
value: "contains"
|
||||||
|
},
|
||||||
|
NOT_CONTAINS: {
|
||||||
|
label: "commons.adv_search.operators.not_like",
|
||||||
|
value: "not contains"
|
||||||
|
},
|
||||||
|
GT: {
|
||||||
|
label: "commons.adv_search.operators.gt",
|
||||||
|
value: ">"
|
||||||
|
},
|
||||||
|
LT: {
|
||||||
|
label: "commons.adv_search.operators.lt",
|
||||||
|
value: "<"
|
||||||
|
},
|
||||||
|
IS_EMPTY: {
|
||||||
|
label: "commons.adv_search.operators.is_empty",
|
||||||
|
value: "is empty"
|
||||||
|
},
|
||||||
|
IS_NOT_EMPTY: {
|
||||||
|
label: "commons.adv_search.operators.is_not_empty",
|
||||||
|
value: "is not empty"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
templates: [
|
||||||
|
{
|
||||||
|
title: this.$t('api_test.request.assertions.set_failure_status'),
|
||||||
|
value: 'AssertionResult.setFailure(true)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.$t('api_test.request.assertions.set_failure_msg'),
|
||||||
|
value: 'AssertionResult.setFailureMessage("msg")',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
add() {
|
||||||
|
this.list.push(new AssertionJSR223(this.assertion));
|
||||||
|
this.callback();
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
this.list.splice(this.index, 1);
|
||||||
|
},
|
||||||
|
changeOperator(value) {
|
||||||
|
if (value.indexOf("empty") > 0 && !!this.assertion.value) {
|
||||||
|
this.assertion.value = "";
|
||||||
|
}
|
||||||
|
this.quickScript();
|
||||||
|
},
|
||||||
|
quickScript() {
|
||||||
|
if (this.assertion.variable && this.assertion.operator) {
|
||||||
|
let variable = this.assertion.variable;
|
||||||
|
let operator = this.assertion.operator;
|
||||||
|
let value = this.assertion.value || "";
|
||||||
|
let desc = "${" + variable + "} " + operator + " '" + value + "'";
|
||||||
|
let script = "value = vars.get(\"" + variable + "\");\n"
|
||||||
|
switch (this.assertion.operator) {
|
||||||
|
case "==":
|
||||||
|
script += "result = \"" + value + "\".equals(value);\n";
|
||||||
|
break;
|
||||||
|
case "!=":
|
||||||
|
script += "result = !\"" + value + "\".equals(value);\n";
|
||||||
|
break;
|
||||||
|
case "contains":
|
||||||
|
script += "result = value.contains(\"" + value + "\");\n";
|
||||||
|
break;
|
||||||
|
case "not contains":
|
||||||
|
script += "result = !value.contains(\"" + value + "\");\n";
|
||||||
|
break;
|
||||||
|
case ">":
|
||||||
|
desc = "${" + variable + "} " + operator + " " + value;
|
||||||
|
script += "number = Integer.parseInt(value);\n" +
|
||||||
|
"result = number > " + value + ";\n";
|
||||||
|
break;
|
||||||
|
case "<":
|
||||||
|
desc = "${" + variable + "} " + operator + " " + value;
|
||||||
|
script += "number = Integer.parseInt(value);\n" +
|
||||||
|
"result = number < " + value + ";\n";
|
||||||
|
break;
|
||||||
|
case "is empty":
|
||||||
|
desc = "${" + variable + "} " + operator
|
||||||
|
script += "result = value == void || value.length() == 0;\n";
|
||||||
|
break;
|
||||||
|
case "is not empty":
|
||||||
|
desc = "${" + variable + "} " + operator
|
||||||
|
script += "result = value != void && value.length() > 0;\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let msg = "assertion [" + desc + "]: false;"
|
||||||
|
script += "if (!result){\n" +
|
||||||
|
"\tmsg = \"" + msg + "\";\n" +
|
||||||
|
"\tAssertionResult.setFailureMessage(msg);\n" +
|
||||||
|
"\tAssertionResult.setFailure(true);\n" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
this.assertion.desc = desc;
|
||||||
|
this.assertion.script = script;
|
||||||
|
this.$refs.jsr233.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
detail() {
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
confirm() {
|
||||||
|
if (!this.edit) {
|
||||||
|
this.add();
|
||||||
|
}
|
||||||
|
if (!this.assertion.desc) {
|
||||||
|
this.assertion.desc = this.assertion.script;
|
||||||
|
}
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
hasEmptyOperator() {
|
||||||
|
return !!this.assertion.operator && this.assertion.operator.indexOf("empty") > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.assertion-item {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.assertion-item + .assertion-item {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.assertion-item.input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.assertion-item.select {
|
||||||
|
min-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.assertion-item.label {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.assertion-item.btn {
|
||||||
|
min-width: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.assertion-item.btn.circle {
|
||||||
|
text-align: right;
|
||||||
|
min-width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-script-block {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -21,7 +21,9 @@
|
||||||
<el-col class="assertion-btn">
|
<el-col class="assertion-btn">
|
||||||
<el-button :disabled="isReadOnly" type="danger" size="mini" icon="el-icon-delete" circle @click="remove"
|
<el-button :disabled="isReadOnly" type="danger" size="mini" icon="el-icon-delete" circle @click="remove"
|
||||||
v-if="edit"/>
|
v-if="edit"/>
|
||||||
<el-button :disabled="isReadOnly" type="primary" size="small" @click="add" v-else>Add</el-button>
|
<el-button :disabled="isReadOnly" type="primary" size="small" @click="add" v-else>
|
||||||
|
{{ $t('api_test.request.assertions.add') }}
|
||||||
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -29,7 +29,9 @@
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col class="assertion-btn">
|
<el-col class="assertion-btn">
|
||||||
<el-button :disabled="isReadOnly" type="primary" size="small" @click="add">Add</el-button>
|
<el-button :disabled="isReadOnly" type="primary" size="small" @click="add">
|
||||||
|
{{ $t('api_test.request.assertions.add') }}
|
||||||
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<el-option :label="$t('api_test.request.assertions.regex')" :value="options.REGEX"/>
|
<el-option :label="$t('api_test.request.assertions.regex')" :value="options.REGEX"/>
|
||||||
<el-option :label="'JSONPath'" :value="options.JSON_PATH"/>
|
<el-option :label="'JSONPath'" :value="options.JSON_PATH"/>
|
||||||
<el-option :label="$t('api_test.request.assertions.response_time')" :value="options.DURATION"/>
|
<el-option :label="$t('api_test.request.assertions.response_time')" :value="options.DURATION"/>
|
||||||
|
<el-option :label="$t('api_test.request.assertions.jsr223')" :value="options.JSR223"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="20">
|
<el-col :span="20">
|
||||||
|
@ -17,7 +18,10 @@
|
||||||
<ms-api-assertion-json-path :is-read-only="isReadOnly" :list="assertions.jsonPath" v-if="type === options.JSON_PATH" :callback="after"/>
|
<ms-api-assertion-json-path :is-read-only="isReadOnly" :list="assertions.jsonPath" v-if="type === options.JSON_PATH" :callback="after"/>
|
||||||
<ms-api-assertion-duration :is-read-only="isReadOnly" v-model="time" :duration="assertions.duration"
|
<ms-api-assertion-duration :is-read-only="isReadOnly" v-model="time" :duration="assertions.duration"
|
||||||
v-if="type === options.DURATION" :callback="after"/>
|
v-if="type === options.DURATION" :callback="after"/>
|
||||||
<el-button v-if="!type" :disabled="true" type="primary" size="small">Add</el-button>
|
<ms-api-assertion-jsr223 :is-read-only="isReadOnly" :list="assertions.jsr223" v-if="type === options.JSR223" :callback="after"/>
|
||||||
|
<el-button v-if="!type" :disabled="true" type="primary" size="small">
|
||||||
|
{{ $t('api_test.request.assertions.add') }}
|
||||||
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
@ -46,12 +50,14 @@
|
||||||
import {ASSERTION_TYPE, Assertions, HttpRequest, JSONPath} from "../../model/ScenarioModel";
|
import {ASSERTION_TYPE, Assertions, HttpRequest, JSONPath} from "../../model/ScenarioModel";
|
||||||
import MsApiAssertionsEdit from "./ApiAssertionsEdit";
|
import MsApiAssertionsEdit from "./ApiAssertionsEdit";
|
||||||
import MsApiAssertionJsonPath from "./ApiAssertionJsonPath";
|
import MsApiAssertionJsonPath from "./ApiAssertionJsonPath";
|
||||||
|
import MsApiAssertionJsr223 from "@/business/components/api/test/components/assertion/ApiAssertionJsr223";
|
||||||
import MsApiJsonpathSuggestList from "./ApiJsonpathSuggestList";
|
import MsApiJsonpathSuggestList from "./ApiJsonpathSuggestList";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiAssertions",
|
name: "MsApiAssertions",
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
|
MsApiAssertionJsr223,
|
||||||
MsApiJsonpathSuggestList,
|
MsApiJsonpathSuggestList,
|
||||||
MsApiAssertionJsonPath,
|
MsApiAssertionJsonPath,
|
||||||
MsApiAssertionsEdit, MsApiAssertionDuration, MsApiAssertionRegex, MsApiAssertionText},
|
MsApiAssertionsEdit, MsApiAssertionDuration, MsApiAssertionRegex, MsApiAssertionText},
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
{{ $t("api_test.request.assertions.regex") }}
|
{{ $t("api_test.request.assertions.regex") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="regex-item" v-for="(regex, index) in assertions.regex" :key="index">
|
<div class="regex-item" v-for="(regex, index) in assertions.regex" :key="index">
|
||||||
<ms-api-assertion-regex :is-read-only="isReadOnly" :list="assertions.regex" :regex="regex" :edit="true" :index="index"/>
|
<ms-api-assertion-regex :is-read-only="isReadOnly" :list="assertions.regex"
|
||||||
|
:regex="regex" :edit="true" :index="index"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -14,7 +15,18 @@
|
||||||
{{ 'JSONPath' }}
|
{{ 'JSONPath' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="regex-item" v-for="(jsonPath, index) in assertions.jsonPath" :key="index">
|
<div class="regex-item" v-for="(jsonPath, index) in assertions.jsonPath" :key="index">
|
||||||
<ms-api-assertion-json-path :is-read-only="isReadOnly" :list="assertions.jsonPath" :json-path="jsonPath" :edit="true" :index="index"/>
|
<ms-api-assertion-json-path :is-read-only="isReadOnly" :list="assertions.jsonPath"
|
||||||
|
:json-path="jsonPath" :edit="true" :index="index"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="assertion-item-editing jsr223" v-if="assertions.jsr223.length > 0">
|
||||||
|
<div>
|
||||||
|
{{ $t("api_test.request.assertions.script") }}
|
||||||
|
</div>
|
||||||
|
<div class="regex-item" v-for="(assertion, index) in assertions.jsr223" :key="index">
|
||||||
|
<ms-api-assertion-jsr223 :is-read-only="isReadOnly" :list="assertions.jsr223"
|
||||||
|
:assertion="assertion" :edit="true" :index="index"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -22,7 +34,8 @@
|
||||||
<div>
|
<div>
|
||||||
{{ $t("api_test.request.assertions.response_time") }}
|
{{ $t("api_test.request.assertions.response_time") }}
|
||||||
</div>
|
</div>
|
||||||
<ms-api-assertion-duration :is-read-only="isReadOnly" v-model="assertions.duration.value" :duration="assertions.duration" :edit="true"/>
|
<ms-api-assertion-duration :is-read-only="isReadOnly" v-model="assertions.duration.value"
|
||||||
|
:duration="assertions.duration" :edit="true"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -33,11 +46,12 @@
|
||||||
import MsApiAssertionDuration from "./ApiAssertionDuration";
|
import MsApiAssertionDuration from "./ApiAssertionDuration";
|
||||||
import {Assertions} from "../../model/ScenarioModel";
|
import {Assertions} from "../../model/ScenarioModel";
|
||||||
import MsApiAssertionJsonPath from "./ApiAssertionJsonPath";
|
import MsApiAssertionJsonPath from "./ApiAssertionJsonPath";
|
||||||
|
import MsApiAssertionJsr223 from "@/business/components/api/test/components/assertion/ApiAssertionJsr223";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiAssertionsEdit",
|
name: "MsApiAssertionsEdit",
|
||||||
|
|
||||||
components: {MsApiAssertionJsonPath, MsApiAssertionDuration, MsApiAssertionRegex},
|
components: {MsApiAssertionJsr223, MsApiAssertionJsonPath, MsApiAssertionDuration, MsApiAssertionRegex},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
assertions: Assertions,
|
assertions: Assertions,
|
||||||
|
@ -74,6 +88,10 @@
|
||||||
border-left: 2px solid #DD0240;
|
border-left: 2px solid #DD0240;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.assertion-item-editing.jsr223 {
|
||||||
|
border-left: 2px solid #1FDD02;
|
||||||
|
}
|
||||||
|
|
||||||
.regex-item {
|
.regex-item {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="20" class="script-content">
|
<el-col :span="20">
|
||||||
<ms-code-edit v-if="isCodeEditAlive" :mode="codeEditModeMap[jsr223Processor.language]" :read-only="isReadOnly" :data.sync="jsr223Processor.script" theme="eclipse" :modes="['java','python']" ref="codeEdit"/>
|
<ms-code-edit v-if="isCodeEditAlive" :mode="codeEditModeMap[jsr223Processor.language]" :read-only="isReadOnly"
|
||||||
|
:data.sync="jsr223Processor.script" theme="eclipse" :modes="['java','python']" ref="codeEdit"
|
||||||
|
:height="height"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4" class="script-index">
|
<el-col :span="4" class="script-index">
|
||||||
<ms-dropdown :default-command="jsr223Processor.language" :commands="languages" @command="languageChange"/>
|
<ms-dropdown :default-command="jsr223Processor.language" :commands="languages" @command="languageChange"/>
|
||||||
|
@ -11,7 +13,9 @@
|
||||||
<el-link :disabled="template.disabled" @click="addTemplate(template)">{{ template.title }}</el-link>
|
<el-link :disabled="template.disabled" @click="addTemplate(template)">{{ template.title }}</el-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="document-url">
|
<div class="document-url">
|
||||||
<el-link href="https://jmeter.apache.org/usermanual/component_reference.html#BeanShell_PostProcessor" type="primary">{{$t('commons.reference_documentation')}}</el-link>
|
<el-link href="https://jmeter.apache.org/usermanual/component_reference.html#BeanShell_PostProcessor"
|
||||||
|
type="primary">{{ $t('commons.reference_documentation') }}
|
||||||
|
</el-link>
|
||||||
<ms-instructions-icon :content="$t('api_test.request.processor.bean_shell_processor_tip')"/>
|
<ms-instructions-icon :content="$t('api_test.request.processor.bean_shell_processor_tip')"/>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -24,11 +28,33 @@
|
||||||
import MsInstructionsIcon from "../../../../common/components/MsInstructionsIcon";
|
import MsInstructionsIcon from "../../../../common/components/MsInstructionsIcon";
|
||||||
import MsDropdown from "../../../../common/components/MsDropdown";
|
import MsDropdown from "../../../../common/components/MsDropdown";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsJsr233Processor",
|
name: "MsJsr233Processor",
|
||||||
components: {MsDropdown, MsInstructionsIcon, MsCodeEdit},
|
components: {MsDropdown, MsInstructionsIcon, MsCodeEdit},
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
isReadOnly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
jsr223Processor: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
isPreProcessor: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
templates: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 230
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
codeTemplates: [
|
codeTemplates: [
|
||||||
|
@ -62,7 +88,8 @@
|
||||||
title: this.$t('api_test.request.processor.code_template_get_response_result'),
|
title: this.$t('api_test.request.processor.code_template_get_response_result'),
|
||||||
value: 'prev.getResponseDataAsString()',
|
value: 'prev.getResponseDataAsString()',
|
||||||
disabled: this.isPreProcessor
|
disabled: this.isPreProcessor
|
||||||
}
|
},
|
||||||
|
...this.templates
|
||||||
],
|
],
|
||||||
isCodeEditAlive: true,
|
isCodeEditAlive: true,
|
||||||
languages: [
|
languages: [
|
||||||
|
@ -74,22 +101,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
isReadOnly: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
jsr223Processor: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
isPreProcessor: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
watch: {
|
||||||
jsr223Processor() {
|
jsr223Processor() {
|
||||||
this.reload();
|
this.reload();
|
||||||
|
@ -123,10 +134,6 @@
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.script-content {
|
|
||||||
height: calc(100vh - 570px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.script-index {
|
.script-index {
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -501,6 +501,12 @@ export class JSR223Processor extends DefaultTestElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class JSR223Assertion extends JSR223Processor {
|
||||||
|
constructor(testName, processor) {
|
||||||
|
super('JSR223Assertion', 'TestBeanGUI', 'JSR223Assertion', testName, processor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class JSR223PreProcessor extends JSR223Processor {
|
export class JSR223PreProcessor extends JSR223Processor {
|
||||||
constructor(testName, processor) {
|
constructor(testName, processor) {
|
||||||
super('JSR223PreProcessor', 'TestBeanGUI', 'JSR223PreProcessor', testName, processor)
|
super('JSR223PreProcessor', 'TestBeanGUI', 'JSR223PreProcessor', testName, processor)
|
||||||
|
|
|
@ -25,7 +25,7 @@ import {
|
||||||
ThreadGroup,
|
ThreadGroup,
|
||||||
XPath2Extractor,
|
XPath2Extractor,
|
||||||
IfController as JMXIfController,
|
IfController as JMXIfController,
|
||||||
ConstantTimer as JMXConstantTimer, TCPSampler,
|
ConstantTimer as JMXConstantTimer, TCPSampler, JSR223Assertion,
|
||||||
} from "./JMX";
|
} from "./JMX";
|
||||||
import Mock from "mockjs";
|
import Mock from "mockjs";
|
||||||
import {funcFilters} from "@/common/js/func-filter";
|
import {funcFilters} from "@/common/js/func-filter";
|
||||||
|
@ -94,7 +94,8 @@ export const ASSERTION_TYPE = {
|
||||||
TEXT: "Text",
|
TEXT: "Text",
|
||||||
REGEX: "Regex",
|
REGEX: "Regex",
|
||||||
JSON_PATH: "JSON",
|
JSON_PATH: "JSON",
|
||||||
DURATION: "Duration"
|
DURATION: "Duration",
|
||||||
|
JSR223: "JSR223",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ASSERTION_REGEX_SUBJECT = {
|
export const ASSERTION_REGEX_SUBJECT = {
|
||||||
|
@ -716,16 +717,34 @@ export class KeyValue extends BaseConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class BeanShellProcessor extends BaseConfig {
|
||||||
|
constructor(options) {
|
||||||
|
super();
|
||||||
|
this.script = undefined;
|
||||||
|
this.set(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class JSR223Processor extends BaseConfig {
|
||||||
|
constructor(options) {
|
||||||
|
super();
|
||||||
|
this.script = undefined;
|
||||||
|
this.language = "beanshell";
|
||||||
|
this.set(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class Assertions extends BaseConfig {
|
export class Assertions extends BaseConfig {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super();
|
super();
|
||||||
this.text = [];
|
this.text = [];
|
||||||
this.regex = [];
|
this.regex = [];
|
||||||
this.jsonPath = [];
|
this.jsonPath = [];
|
||||||
|
this.jsr223 = [];
|
||||||
this.duration = undefined;
|
this.duration = undefined;
|
||||||
|
|
||||||
this.set(options);
|
this.set(options);
|
||||||
this.sets({text: Text, regex: Regex, jsonPath: JSONPath}, options);
|
this.sets({text: Text, regex: Regex, jsonPath: JSONPath, jsr223: AssertionJSR223}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
initOptions(options) {
|
initOptions(options) {
|
||||||
|
@ -742,22 +761,23 @@ export class AssertionType extends BaseConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BeanShellProcessor extends BaseConfig {
|
export class AssertionJSR223 extends AssertionType {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super();
|
super(ASSERTION_TYPE.JSR223);
|
||||||
this.script = undefined;
|
this.variable = undefined;
|
||||||
this.set(options);
|
this.operator = undefined;
|
||||||
}
|
this.value = undefined;
|
||||||
}
|
this.desc = undefined;
|
||||||
|
|
||||||
|
this.name = undefined;
|
||||||
export class JSR223Processor extends BaseConfig {
|
|
||||||
constructor(options) {
|
|
||||||
super();
|
|
||||||
this.script = undefined;
|
this.script = undefined;
|
||||||
this.language = "beanshell";
|
this.language = "beanshell";
|
||||||
this.set(options);
|
this.set(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isValid() {
|
||||||
|
return !!this.script && !!this.language;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Text extends AssertionType {
|
export class Text extends AssertionType {
|
||||||
|
@ -1406,6 +1426,12 @@ class JMXGenerator {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (assertions.jsr223.length > 0) {
|
||||||
|
assertions.jsr223.filter(this.filter).forEach(item => {
|
||||||
|
httpSamplerProxy.put(this.getJSR223Assertion(item));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (assertions.duration.isValid()) {
|
if (assertions.duration.isValid()) {
|
||||||
let name = "Response In Time: " + assertions.duration.value
|
let name = "Response In Time: " + assertions.duration.value
|
||||||
httpSamplerProxy.put(new DurationAssertion(name, assertions.duration.value));
|
httpSamplerProxy.put(new DurationAssertion(name, assertions.duration.value));
|
||||||
|
@ -1417,6 +1443,11 @@ class JMXGenerator {
|
||||||
return new JSONPathAssertion(name, jsonPath);
|
return new JSONPathAssertion(name, jsonPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getJSR223Assertion(item) {
|
||||||
|
let name = item.desc;
|
||||||
|
return new JSR223Assertion(name, item);
|
||||||
|
}
|
||||||
|
|
||||||
getResponseAssertion(regex) {
|
getResponseAssertion(regex) {
|
||||||
let name = regex.description;
|
let name = regex.description;
|
||||||
let type = JMX_ASSERTION_CONDITION.CONTAINS; // 固定用Match,自己写正则
|
let type = JMX_ASSERTION_CONDITION.CONTAINS; // 固定用Match,自己写正则
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<editor v-model="formatData" :lang="mode" @init="editorInit" :theme="theme"/>
|
<editor v-model="formatData" :lang="mode" @init="editorInit" :theme="theme" :height="height"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
height: [String, Number],
|
||||||
data: {
|
data: {
|
||||||
type: String
|
type: String
|
||||||
},
|
},
|
||||||
|
|
|
@ -558,6 +558,12 @@ export default {
|
||||||
expression: "Expression",
|
expression: "Expression",
|
||||||
response_in_time: "Response in time",
|
response_in_time: "Response in time",
|
||||||
ignore_status: "Ignore Status",
|
ignore_status: "Ignore Status",
|
||||||
|
add: "Add",
|
||||||
|
script_name: "Script name",
|
||||||
|
script: "Script",
|
||||||
|
variable_name: "Variable name",
|
||||||
|
set_failure_status: "Set failure status",
|
||||||
|
set_failure_msg: "Set failure message",
|
||||||
json_path_add: "Add JONPATH Assertions",
|
json_path_add: "Add JONPATH Assertions",
|
||||||
json_path_err: "The response result is not in JSON format",
|
json_path_err: "The response result is not in JSON format",
|
||||||
json_path_suggest: "JSONPath Assertion Suggest",
|
json_path_suggest: "JSONPath Assertion Suggest",
|
||||||
|
|
|
@ -545,6 +545,7 @@ export default {
|
||||||
text: "文本",
|
text: "文本",
|
||||||
regex: "正则",
|
regex: "正则",
|
||||||
response_time: "响应时间",
|
response_time: "响应时间",
|
||||||
|
jsr223: "脚本",
|
||||||
select_type: "请选择类型",
|
select_type: "请选择类型",
|
||||||
select_subject: "请选择对象",
|
select_subject: "请选择对象",
|
||||||
select_condition: "请选择条件",
|
select_condition: "请选择条件",
|
||||||
|
@ -562,6 +563,13 @@ export default {
|
||||||
json_path_suggest: "推荐JSONPath断言",
|
json_path_suggest: "推荐JSONPath断言",
|
||||||
json_path_clear: "清空JSONPath断言",
|
json_path_clear: "清空JSONPath断言",
|
||||||
debug_first: "请先执行调试获取响应结果",
|
debug_first: "请先执行调试获取响应结果",
|
||||||
|
ignore_status: "忽略状态",
|
||||||
|
add: "添加",
|
||||||
|
script_name: "脚本名称",
|
||||||
|
script: "脚本",
|
||||||
|
variable_name: "变量名称",
|
||||||
|
set_failure_status: "设置失败状态",
|
||||||
|
set_failure_msg: "设置失败消息",
|
||||||
},
|
},
|
||||||
extract: {
|
extract: {
|
||||||
label: "提取",
|
label: "提取",
|
||||||
|
|
|
@ -562,6 +562,13 @@ export default {
|
||||||
json_path_suggest: "推薦JSONPath斷言",
|
json_path_suggest: "推薦JSONPath斷言",
|
||||||
json_path_clear: "清空JSONPath斷言",
|
json_path_clear: "清空JSONPath斷言",
|
||||||
debug_first: "請先執行調試獲取響應結果",
|
debug_first: "請先執行調試獲取響應結果",
|
||||||
|
ignore_status: "忽略狀態",
|
||||||
|
add: "添加",
|
||||||
|
script_name: "腳本名稱",
|
||||||
|
script: "腳本",
|
||||||
|
variable_name: "變量名稱",
|
||||||
|
set_failure_status: "設置失敗狀態",
|
||||||
|
set_failure_msg: "設置失敗消息",
|
||||||
},
|
},
|
||||||
extract: {
|
extract: {
|
||||||
label: "提取",
|
label: "提取",
|
||||||
|
|
Loading…
Reference in New Issue