场景公用变量和Header
This commit is contained in:
parent
62bf729e8c
commit
709c207fcc
|
@ -6,10 +6,12 @@
|
|||
<div class="kv-row" v-for="(item, index) in items" :key="index">
|
||||
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
||||
<el-col>
|
||||
<el-input v-model="item.name" placeholder="Key" size="small" maxlength="100" @change="change"/>
|
||||
<el-input v-model="item.name" size="small" maxlength="100" @change="change"
|
||||
:placeholder="$t('api_test.key')"/>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input v-model="item.value" placeholder="Value" size="small" maxlength="100" @change="change"/>
|
||||
<el-input v-model="item.value" size="small" maxlength="100" @change="change"
|
||||
:placeholder="$t('api_test.value')"/>
|
||||
</el-col>
|
||||
<el-col class="kv-delete">
|
||||
<el-button size="mini" class="el-icon-delete-solid" circle @click="remove(index)"
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
|
||||
<script>
|
||||
|
||||
import MsApiCollapseItem from "./ApiCollapseItem";
|
||||
import MsApiCollapse from "./ApiCollapse";
|
||||
import MsApiCollapseItem from "./collapse/ApiCollapseItem";
|
||||
import MsApiCollapse from "./collapse/ApiCollapse";
|
||||
import MsApiRequestConfig from "./ApiRequestConfig";
|
||||
import MsApiRequestForm from "./ApiRequestForm";
|
||||
import MsApiScenarioForm from "./ApiScenarioForm";
|
||||
|
|
|
@ -8,24 +8,25 @@
|
|||
<!-- <el-input :placeholder="$t('api_test.scenario.base_url_description')" v-model="scenario.url" maxlength="100"/>-->
|
||||
<!-- </el-form-item>-->
|
||||
|
||||
<!-- <el-tabs v-model="activeName">-->
|
||||
<!-- <el-tab-pane :label="$t('api_test.scenario.parameters')" name="parameters">-->
|
||||
<!-- <ms-api-key-value :items="scenario.parameters" :description="$t('api_test.scenario.kv_description')"/>-->
|
||||
<!-- </el-tab-pane>-->
|
||||
<!-- <el-tab-pane :label="$t('api_test.scenario.headers')" name="headers">-->
|
||||
<!-- <ms-api-key-value :items="scenario.headers" :description="$t('api_test.scenario.kv_description')"/>-->
|
||||
<!-- </el-tab-pane>-->
|
||||
<!-- </el-tabs>-->
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane :label="$t('api_test.scenario.variables')" name="parameters">
|
||||
<ms-api-scenario-variables :items="scenario.variables" :description="$t('api_test.scenario.kv_description')"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('api_test.scenario.headers')" name="headers">
|
||||
<ms-api-key-value :items="scenario.headers" :description="$t('api_test.scenario.kv_description')"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsApiKeyValue from "./ApiKeyValue";
|
||||
import {Scenario} from "../model/ScenarioModel";
|
||||
import MsApiScenarioVariables from "./ApiScenarioVariables";
|
||||
|
||||
export default {
|
||||
name: "MsApiScenarioForm",
|
||||
components: {MsApiKeyValue},
|
||||
components: {MsApiScenarioVariables, MsApiKeyValue},
|
||||
props: {
|
||||
scenario: Scenario
|
||||
},
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
<template>
|
||||
<div>
|
||||
<span class="kv-description" v-if="description">
|
||||
{{description}}
|
||||
</span>
|
||||
<div class="kv-row" v-for="(item, index) in items" :key="index">
|
||||
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
||||
<el-col>
|
||||
<ms-api-variable-input v-model="item.name" size="small" maxlength="100" @change="change"
|
||||
:placeholder="$t('api_test.variable_name')"/>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input v-model="item.value" size="small" maxlength="100" @change="change"
|
||||
:placeholder="$t('api_test.value')"/>
|
||||
</el-col>
|
||||
<el-col class="kv-delete">
|
||||
<el-button size="mini" class="el-icon-delete-solid" circle @click="remove(index)"
|
||||
:disabled="isDisable(index)"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {KeyValue} from "../model/ScenarioModel";
|
||||
import MsApiVariableInput from "./ApiVariableInput";
|
||||
|
||||
export default {
|
||||
name: "MsApiScenarioVariables",
|
||||
components: {MsApiVariableInput},
|
||||
props: {
|
||||
description: String,
|
||||
items: Array
|
||||
},
|
||||
|
||||
methods: {
|
||||
remove: function (index) {
|
||||
this.items.splice(index, 1);
|
||||
this.$emit('change', this.items);
|
||||
},
|
||||
change: function () {
|
||||
let isNeedCreate = true;
|
||||
let removeIndex = -1;
|
||||
this.items.forEach((item, index) => {
|
||||
if (!item.name && !item.value) {
|
||||
// 多余的空行
|
||||
if (index !== this.items.length - 1) {
|
||||
removeIndex = index;
|
||||
}
|
||||
// 没有空行,需要创建空行
|
||||
isNeedCreate = false;
|
||||
}
|
||||
});
|
||||
if (isNeedCreate) {
|
||||
this.items.push(new KeyValue());
|
||||
}
|
||||
this.$emit('change', this.items);
|
||||
// TODO 检查key重复
|
||||
},
|
||||
isDisable: function (index) {
|
||||
return this.items.length - 1 === index;
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.items.length === 0) {
|
||||
this.items.push(new KeyValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.kv-description {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.kv-row {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.kv-delete {
|
||||
width: 60px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,89 @@
|
|||
<template>
|
||||
<div class="variable-input">
|
||||
<el-input :value="value" v-bind="$attrs" :size="size" @change="change" @input="input"/>
|
||||
<div class="variable-combine" v-if="value">
|
||||
<div class="variable">{{variable}}</div>
|
||||
<el-tooltip :content="$t('api_test.copied')" manual v-model="visible" placement="top" :visible-arrow="false">
|
||||
<i class="el-icon-copy-document copy" @click="copy"/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsApiVariableInput",
|
||||
|
||||
props: ['value', 'size'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
copy() {
|
||||
let input = document.createElement("input");
|
||||
document.body.appendChild(input);
|
||||
input.value = this.variable;
|
||||
input.select();
|
||||
if (input.setSelectionRange) {
|
||||
input.setSelectionRange(0, input.value.length);
|
||||
}
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(input);
|
||||
this.visible = true;
|
||||
setTimeout(() => {
|
||||
this.visible = false;
|
||||
}, 1000);
|
||||
},
|
||||
change(value) {
|
||||
this.$emit('change', value);
|
||||
},
|
||||
input(value) {
|
||||
this.$emit('input', value);
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
variable() {
|
||||
return "${" + this.value + "}";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.variable-input {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.variable-combine {
|
||||
color: #7F7F7F;
|
||||
max-width: 80px;
|
||||
line-height: 32px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 25px;
|
||||
margin-right: -20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.variable-combine .variable {
|
||||
display: inline-block;
|
||||
max-width: 60px;
|
||||
margin-right: 10px;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.variable-combine .copy {
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
color: #1E90FF;
|
||||
}
|
||||
</style>
|
|
@ -2,17 +2,8 @@
|
|||
<div>
|
||||
<el-row :gutter="10" type="flex" justify="space-between" align="middle">
|
||||
<el-col :span="10">
|
||||
<div class="variable">
|
||||
<el-input v-model="common.variable" maxlength="60" size="small" @input="change"
|
||||
:placeholder="$t('api_test.request.extract.variable_name')"/>
|
||||
<div class="variable-combine" v-if="common.variable && edit">
|
||||
<div class="value">{{common.value}}</div>
|
||||
<el-tooltip :content="$t('api_test.request.extract.copied')" manual v-model="visible" placement="top"
|
||||
:visible-arrow="false">
|
||||
<i class="el-icon-copy-document copy" @click="copy"></i>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<ms-api-variable-input v-model="common.variable" size="small" maxlength="60" @change="change"
|
||||
:placeholder="$t('api_test.variable_name')"/>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input v-model="common.expression" maxlength="255" size="small" :placeholder="expression"/>
|
||||
|
@ -27,10 +18,11 @@
|
|||
|
||||
<script>
|
||||
import {EXTRACT_TYPE, ExtractCommon} from "../../model/ScenarioModel";
|
||||
import MsApiVariableInput from "../ApiVariableInput";
|
||||
|
||||
export default {
|
||||
name: "MsApiExtractCommon",
|
||||
|
||||
components: {MsApiVariableInput},
|
||||
props: {
|
||||
extractType: {
|
||||
type: String,
|
||||
|
|
|
@ -371,10 +371,10 @@ export class Arguments extends DefaultTestElement {
|
|||
|
||||
let collectionProp = this.collectionProp('Arguments.arguments');
|
||||
this.args.forEach(arg => {
|
||||
let elementProp = collectionProp.elementProp(arg.name, 'HTTPArgument');
|
||||
elementProp.boolProp('HTTPArgument.always_encode', arg.encode || true);
|
||||
let elementProp = collectionProp.elementProp(arg.name, 'Argument');
|
||||
elementProp.stringProp('Argument.name', arg.name);
|
||||
elementProp.stringProp('Argument.value', arg.value);
|
||||
elementProp.stringProp('Argument.desc', arg.desc);
|
||||
elementProp.stringProp('Argument.metadata', arg.metadata || "=");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
ResponseCodeAssertion,
|
||||
ResponseDataAssertion,
|
||||
ResponseHeadersAssertion,
|
||||
BackendListener, RegexExtractor, JSONPostProcessor, XPath2Extractor
|
||||
BackendListener, RegexExtractor, JSONPostProcessor, XPath2Extractor, Arguments
|
||||
} from "./JMX";
|
||||
|
||||
export const uuid = function () {
|
||||
|
@ -124,12 +124,12 @@ export class Scenario extends BaseConfig {
|
|||
this.id = uuid();
|
||||
this.name = null;
|
||||
this.url = null;
|
||||
this.parameters = [];
|
||||
this.variables = [];
|
||||
this.headers = [];
|
||||
this.requests = [];
|
||||
|
||||
this.set(options);
|
||||
this.sets({parameters: KeyValue, headers: KeyValue, requests: Request}, options);
|
||||
this.sets({variables: KeyValue, headers: KeyValue, requests: Request}, options);
|
||||
}
|
||||
|
||||
initOptions(options) {
|
||||
|
@ -397,6 +397,10 @@ class JMXGenerator {
|
|||
test.scenarioDefinition.forEach(scenario => {
|
||||
let threadGroup = new ThreadGroup(scenario.name + SPLIT + scenario.id);
|
||||
|
||||
this.addScenarioVariables(threadGroup, scenario);
|
||||
|
||||
this.addScenarioHeaders(threadGroup, scenario);
|
||||
|
||||
scenario.requests.forEach(request => {
|
||||
if (!request.isValid()) return;
|
||||
|
||||
|
@ -434,6 +438,22 @@ class JMXGenerator {
|
|||
this.jmeterTestPlan.put(testPlan);
|
||||
}
|
||||
|
||||
addScenarioVariables(threadGroup, scenario) {
|
||||
let args = scenario.variables.filter(this.filter)
|
||||
if (args.length > 0) {
|
||||
let name = scenario.name + " Variables"
|
||||
threadGroup.put(new Arguments(name, args));
|
||||
}
|
||||
}
|
||||
|
||||
addScenarioHeaders(threadGroup, scenario) {
|
||||
let headers = scenario.headers.filter(this.filter)
|
||||
if (headers.length > 0) {
|
||||
let name = scenario.name + " Headers"
|
||||
threadGroup.put(new HeaderManager(name, headers));
|
||||
}
|
||||
}
|
||||
|
||||
addRequestHeader(httpSamplerProxy, request) {
|
||||
let name = request.name + " Headers";
|
||||
let headers = request.headers.filter(this.filter);
|
||||
|
|
|
@ -209,15 +209,19 @@ export default {
|
|||
reset: "Rest",
|
||||
input_name: "Please enter the test name",
|
||||
select_project: "Select project",
|
||||
variable_name: "Variable name",
|
||||
copied: "copied",
|
||||
key: "Key",
|
||||
value: "Value",
|
||||
scenario: {
|
||||
config: "Scenario Config",
|
||||
input_name: "Please enter the scenario name",
|
||||
name: "Scenario Name",
|
||||
base_url: "Base URL",
|
||||
base_url_description: "Base URL as URL prefix for all requests",
|
||||
parameters: "Parameters",
|
||||
variables: "Variables",
|
||||
headers: "Headers",
|
||||
kv_description: "Will be used for requests where the item is not set",
|
||||
kv_description: "Variables are available for all requests",
|
||||
},
|
||||
request: {
|
||||
input_name: "Please enter the request name",
|
||||
|
@ -225,7 +229,7 @@ export default {
|
|||
method: "Method",
|
||||
url: "URL",
|
||||
url_description: "etc: https://fit2cloud.com",
|
||||
parameters: "Parameters",
|
||||
parameters: "Query parameters",
|
||||
parameters_desc: "Parameters will be appended to the URL e.g. https://fit2cloud.com?Name=Value&Name2=Value2",
|
||||
headers: "Headers",
|
||||
body: "Body",
|
||||
|
@ -246,18 +250,16 @@ export default {
|
|||
end_with: "End With",
|
||||
value: "Value",
|
||||
expression: "Expression",
|
||||
response_in_time: "Response Time",
|
||||
response_in_time: "Response in time",
|
||||
},
|
||||
extract: {
|
||||
label: "Extract from response",
|
||||
select_type: "Choose type",
|
||||
description: "Extract data from the response and store it in variables. Use the variables in subsequent requests.",
|
||||
regex: "Regex",
|
||||
variable_name: "Variable name",
|
||||
regex_expression: "Regular expression",
|
||||
json_path_expression: "JSONPath expression",
|
||||
xpath_expression: "XPath expression",
|
||||
copied: "Copied"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -209,15 +209,19 @@ export default {
|
|||
reset: "重置",
|
||||
input_name: "请输入测试名称",
|
||||
select_project: "请选择项目",
|
||||
variable_name: "变量名",
|
||||
copied: "已拷贝",
|
||||
key: "键",
|
||||
value: "值",
|
||||
scenario: {
|
||||
config: "场景配置",
|
||||
input_name: "请输入场景名称",
|
||||
name: "场景名称",
|
||||
base_url: "基础URL",
|
||||
base_url_description: "基础URL作为所有请求的URL前缀",
|
||||
parameters: "请求变量",
|
||||
variables: "自定义变量",
|
||||
headers: "请求头",
|
||||
kv_description: "将用于未设置该项的请求",
|
||||
kv_description: "所有请求可以使用自定义变量",
|
||||
},
|
||||
request: {
|
||||
input_name: "请输入请求名称",
|
||||
|
@ -253,11 +257,9 @@ export default {
|
|||
select_type: "请选择类型",
|
||||
description: "从响应结果中提取数据并将其存储在变量中,在后续请求中使用变量。",
|
||||
regex: "正则",
|
||||
variable_name: "变量名",
|
||||
regex_expression: "Perl型正则表达式",
|
||||
json_path_expression: "JSONPath表达式",
|
||||
xpath_expression: "XPath表达式",
|
||||
copied: "已拷贝"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue