api界面,未完待续
This commit is contained in:
parent
30f6745b90
commit
f7a11e9405
|
@ -26,13 +26,14 @@
|
|||
</ms-api-collapse-item>
|
||||
</ms-api-collapse>
|
||||
</div>
|
||||
<el-button class="scenario-create" type="primary" size="mini" icon="el-icon-plus" plain @click="create"/>
|
||||
<el-button class="scenario-create" type="primary" size="mini" icon="el-icon-plus" plain
|
||||
@click="createScenario"/>
|
||||
</el-aside>
|
||||
|
||||
<el-main class="scenario-main">
|
||||
<div class="scenario-form">
|
||||
<ms-api-scenario-form :scenario="selected"></ms-api-scenario-form>
|
||||
<ms-api-request-form :request="selected"></ms-api-request-form>
|
||||
<ms-api-scenario-form :scenario="selected" v-if="isScenario"></ms-api-scenario-form>
|
||||
<ms-api-request-form :request="selected" v-if="isRequest"></ms-api-request-form>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
@ -49,6 +50,7 @@
|
|||
import MsApiRequest from "./components/ApiRequest";
|
||||
import MsApiRequestForm from "./components/ApiRequestForm";
|
||||
import MsApiScenarioForm from "./components/ApiScenarioForm";
|
||||
import {Scenario, Request} from "./model/APIModel";
|
||||
|
||||
export default {
|
||||
name: "MsApiScenarioConfig",
|
||||
|
@ -64,6 +66,17 @@
|
|||
},
|
||||
|
||||
methods: {
|
||||
createScenario: function () {
|
||||
let scenario = new Scenario({name: "Scenario"});
|
||||
this.scenarios.push(scenario);
|
||||
},
|
||||
deleteScenario: function (index) {
|
||||
this.scenarios.splice(index, 1);
|
||||
if (this.scenarios.length === 0) {
|
||||
this.createScenario();
|
||||
this.select(this.scenarios[0]);
|
||||
}
|
||||
},
|
||||
handleChange: function (index) {
|
||||
this.select(this.scenarios[index]);
|
||||
},
|
||||
|
@ -74,35 +87,23 @@
|
|||
break;
|
||||
}
|
||||
},
|
||||
createScenario: function () {
|
||||
return {
|
||||
type: "Scenario",
|
||||
name: "Scenario",
|
||||
address: "",
|
||||
file: "",
|
||||
variables: [],
|
||||
headers: [],
|
||||
requests: []
|
||||
}
|
||||
},
|
||||
deleteScenario: function (index) {
|
||||
this.scenarios.splice(index, 1);
|
||||
if (this.scenarios.length === 0) {
|
||||
this.create();
|
||||
}
|
||||
},
|
||||
create: function () {
|
||||
let scenario = this.createScenario();
|
||||
this.scenarios.push(scenario);
|
||||
},
|
||||
select: function (obj) {
|
||||
this.selected = obj;
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isScenario() {
|
||||
return this.selected instanceof Scenario;
|
||||
},
|
||||
isRequest() {
|
||||
return this.selected instanceof Request;
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.scenarios.length === 0) {
|
||||
this.create();
|
||||
this.createScenario();
|
||||
this.select(this.scenarios[0]);
|
||||
}
|
||||
}
|
||||
|
@ -137,6 +138,9 @@
|
|||
}
|
||||
|
||||
.scenario-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row :gutter="10" type="flex" align="middle">
|
||||
<el-col :span="4">
|
||||
<el-select class="assertion-item" v-model="regex.subject" size="small"
|
||||
:placeholder="$t('api_test.request.assertions.select_subject')">
|
||||
<el-option label="Http-Code" value="HTTP-CODE"></el-option>
|
||||
<el-option label="Header" value="HEADER"></el-option>
|
||||
<el-option label="Body" value="BODY"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="19">
|
||||
<el-input v-model="regex.expression" maxlength="255" size="small" show-word-limit
|
||||
:placeholder="$t('api_test.request.assertions.expression')"/>
|
||||
</el-col>
|
||||
<el-col :span="1" class="assertion-btn">
|
||||
<el-button type="danger" size="mini" icon="el-icon-delete" circle @click="remove" v-if="edit"/>
|
||||
<el-button type="primary" size="small" icon="el-icon-plus" plain @click="add" v-else/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {Regex} from "../model/APIModel";
|
||||
|
||||
export default {
|
||||
name: "MsApiAssertionRegex",
|
||||
|
||||
props: {
|
||||
regex: {
|
||||
type: Regex,
|
||||
default: () => {
|
||||
return new Regex();
|
||||
}
|
||||
},
|
||||
edit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
index: Number,
|
||||
list: Array
|
||||
},
|
||||
|
||||
methods: {
|
||||
add: function () {
|
||||
this.list.push(new Regex(this.regex));
|
||||
},
|
||||
remove: function () {
|
||||
this.list.splice(this.index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.assertion-item {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.assertion-btn {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row :gutter="10" align="middle">
|
||||
<el-col :span="23">
|
||||
<el-input v-model="time" step="100" size="small" type="number"
|
||||
:placeholder="$t('api_test.request.assertions.response_in_time')"/>
|
||||
</el-col>
|
||||
<el-col :span="1" class="assertion-btn">
|
||||
<el-button type="danger" size="mini" icon="el-icon-delete" circle @click="remove" v-if="edit"/>
|
||||
<el-button type="primary" size="small" icon="el-icon-plus" plain @click="add" v-else/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {ResponseTime} from "../model/APIModel";
|
||||
|
||||
export default {
|
||||
name: "MsApiAssertionResponseTime",
|
||||
|
||||
props: {
|
||||
edit: Boolean,
|
||||
responseTime: ResponseTime
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
time: this.responseTime.responseInTime
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
add: function () {
|
||||
this.remove();
|
||||
setTimeout(() => {
|
||||
this.responseTime.responseInTime = this.time;
|
||||
})
|
||||
},
|
||||
remove: function () {
|
||||
this.responseTime.responseInTime = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.assertion-btn {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,95 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="4">
|
||||
<el-select class="assertion-item" v-model="subject" size="small"
|
||||
:placeholder="$t('api_test.request.assertions.select_subject')">
|
||||
<el-option label="Http-Code" value="HTTP-CODE"></el-option>
|
||||
<el-option label="Header" value="HEADER"></el-option>
|
||||
<el-option label="Body" value="BODY"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-select class="assertion-item" v-model="condition" size="small"
|
||||
:placeholder="$t('api_test.request.assertions.select_contains')">
|
||||
<el-option :label="$t('api_test.request.assertions.contains')" value="CONTAINS"></el-option>
|
||||
<el-option :label="$t('api_test.request.assertions.not_contains')" value="NOT_CONTAINS"></el-option>
|
||||
<el-option :label="$t('api_test.request.assertions.equals')" value="EQUALS"></el-option>
|
||||
<el-option :label="$t('api_test.request.assertions.start_with')" value="START_WITH"></el-option>
|
||||
<el-option :label="$t('api_test.request.assertions.end_with')" value="END_WITH"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="15">
|
||||
<el-input v-model="value" maxlength="255" size="small" show-word-limit
|
||||
:placeholder="$t('api_test.request.assertions.value')"/>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<el-button type="primary" size="small" icon="el-icon-plus" plain @click="add"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {Regex} from "../model/APIModel";
|
||||
|
||||
export default {
|
||||
name: "MsApiAssertionText",
|
||||
|
||||
props: {
|
||||
list: Array
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
subject: "",
|
||||
condition: "",
|
||||
value: ""
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
add: function () {
|
||||
this.list.push(this.toRegex());
|
||||
},
|
||||
toRegex: function () {
|
||||
let expression = "";
|
||||
let description = "";
|
||||
switch (this.condition) {
|
||||
case "CONTAINS":
|
||||
expression = ".*" + this.value + ".*";
|
||||
description = "contains: " + this.value;
|
||||
break;
|
||||
case "NOT_CONTAINS":
|
||||
expression = "^((?!" + this.value + ").)*$";
|
||||
description = "not contains: " + this.value;
|
||||
break;
|
||||
case "EQUALS":
|
||||
expression = "^" + this.value + "$";
|
||||
description = "equals: " + this.value;
|
||||
break;
|
||||
case "START_WITH":
|
||||
expression = "^" + this.value;
|
||||
description = "start with: " + this.value;
|
||||
break;
|
||||
case "END_WITH":
|
||||
expression = this.value + "$";
|
||||
description = "end with: " + this.value;
|
||||
break;
|
||||
}
|
||||
return new Regex({
|
||||
subject: this.subject,
|
||||
expression: expression,
|
||||
description: description
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.assertion-item {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="4">
|
||||
<el-select class="assertion-item" v-model="type" :placeholder="$t('api_test.request.assertions.select_type')"
|
||||
size="small">
|
||||
<el-option :label="$t('api_test.request.assertions.text')" :value="options.TEXT"/>
|
||||
<el-option :label="$t('api_test.request.assertions.regex')" :value="options.REGEX"/>
|
||||
<el-option :label="$t('api_test.request.assertions.response_time')" :value="options.RESPONSE_TIME"/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<ms-api-assertion-text :list="assertions.regex" v-if="type === options.TEXT"/>
|
||||
<ms-api-assertion-regex :list="assertions.regex" v-if="type === options.REGEX"/>
|
||||
<ms-api-assertion-response-time :response-time="assertions.responseTime" v-if="type === options.RESPONSE_TIME"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<ms-api-assertions-edit :assertions="assertions"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsApiAssertionText from "./ApiAssertionText";
|
||||
import MsApiAssertionRegex from "./ApiAssertionRegex";
|
||||
import MsApiAssertionResponseTime from "./ApiAssertionResponseTime";
|
||||
import {ASSERTION_TYPE, Assertions, Regex} from "../model/APIModel";
|
||||
import MsApiAssertionsEdit from "./ApiAssertionsEdit";
|
||||
|
||||
export default {
|
||||
name: "MsApiAssertions",
|
||||
|
||||
components: {MsApiAssertionsEdit, MsApiAssertionResponseTime, MsApiAssertionRegex, MsApiAssertionText},
|
||||
|
||||
props: {
|
||||
assertions: Assertions
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
options: ASSERTION_TYPE,
|
||||
type: "",
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
createRegex: function () {
|
||||
return new Regex();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.assertion-item {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,57 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="assertion-item-editing regex" v-if="assertions.regex.length > 0">
|
||||
<div>
|
||||
{{$t("api_test.request.assertions.regex")}}
|
||||
</div>
|
||||
<div class="regex-item" v-for="(regex, index) in assertions.regex" :key="index">
|
||||
<ms-api-assertion-regex :list="assertions.regex" :regex="regex" :edit="true" :index="index"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="assertion-item-editing response-time" v-if="assertions.responseTime.isValid()">
|
||||
<div>
|
||||
{{$t("api_test.request.assertions.response_time")}}
|
||||
</div>
|
||||
<ms-api-assertion-response-time :response-time="assertions.responseTime" :edit="true"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsApiAssertionRegex from "./ApiAssertionRegex";
|
||||
import MsApiAssertionResponseTime from "./ApiAssertionResponseTime";
|
||||
import {Assertions} from "../model/APIModel";
|
||||
|
||||
export default {
|
||||
name: "MsApiAssertionsEdit",
|
||||
|
||||
components: {MsApiAssertionResponseTime, MsApiAssertionRegex},
|
||||
|
||||
props: {
|
||||
assertions: Assertions
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.assertion-item-editing {
|
||||
padding-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.assertion-item-editing.regex {
|
||||
border-left: 2px solid #7B0274;
|
||||
}
|
||||
|
||||
.assertion-item-editing.response-time {
|
||||
border-left: 2px solid #DD0240;
|
||||
}
|
||||
|
||||
.regex-item {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
|
@ -1,15 +1,15 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-radio-group v-model="body.type" size="mini">
|
||||
<el-radio-button label="kv">
|
||||
<el-radio-button :label="type.KV">
|
||||
{{$t('api_test.request.body_kv')}}
|
||||
</el-radio-button>
|
||||
<el-radio-button label="text">
|
||||
<el-radio-button :label="type.TEXT">
|
||||
{{$t('api_test.request.body_text')}}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
|
||||
<ms-api-key-value :items="body.kvs" v-if="isKV"/>
|
||||
<ms-api-key-value :items="body.kvs" v-if="body.isKV()"/>
|
||||
|
||||
<el-input class="textarea" type="textarea" v-model="body.text" :autosize="{ minRows: 10, maxRows: 25}" resize="none"
|
||||
v-else/>
|
||||
|
@ -18,23 +18,26 @@
|
|||
|
||||
<script>
|
||||
import MsApiKeyValue from "./ApiKeyValue";
|
||||
import {Body, BODY_TYPE} from "../model/APIModel";
|
||||
|
||||
export default {
|
||||
name: "MsApiBody",
|
||||
components: {MsApiKeyValue},
|
||||
props: {
|
||||
body: Object
|
||||
body: Body
|
||||
},
|
||||
|
||||
data() {
|
||||
return {};
|
||||
return {
|
||||
type: BODY_TYPE
|
||||
};
|
||||
},
|
||||
|
||||
methods: {},
|
||||
|
||||
computed: {
|
||||
isKV() {
|
||||
return this.body.type === "kv";
|
||||
created() {
|
||||
if (this.body.type === null) {
|
||||
this.body.type = BODY_TYPE.KV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
<el-input v-model="item.value" placeholder="Value" size="small" maxlength="100" @change="check"/>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<el-button size="mini" class="el-icon-delete-solid" circle @click="remove(index)"/>
|
||||
<el-button size="mini" class="el-icon-delete-solid" circle @click="remove(index)"
|
||||
:disabled="isDisable(index)"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
@ -20,6 +21,8 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {KeyValue} from "../model/APIModel";
|
||||
|
||||
export default {
|
||||
name: "MsApiKeyValue",
|
||||
|
||||
|
@ -29,23 +32,20 @@
|
|||
},
|
||||
|
||||
methods: {
|
||||
create: function () {
|
||||
return {
|
||||
key: "",
|
||||
value: ""
|
||||
}
|
||||
add: function () {
|
||||
this.items.push(new KeyValue());
|
||||
},
|
||||
remove: function (index) {
|
||||
this.items.splice(index, 1);
|
||||
if (this.items.length === 0) {
|
||||
this.items.push(this.create());
|
||||
this.add();
|
||||
}
|
||||
},
|
||||
check: function () {
|
||||
let isNeedCreate = true;
|
||||
let removeIndex = -1;
|
||||
this.items.forEach((item, index) => {
|
||||
if (item.key === "" && item.value === "") {
|
||||
if (!item.key && !item.value) {
|
||||
// 多余的空行
|
||||
if (index !== this.items.length - 1) {
|
||||
removeIndex = index;
|
||||
|
@ -55,18 +55,21 @@
|
|||
}
|
||||
});
|
||||
if (isNeedCreate) {
|
||||
this.items.push(this.create());
|
||||
this.add();
|
||||
}
|
||||
if (removeIndex !== -1) {
|
||||
this.remove(removeIndex);
|
||||
}
|
||||
// TODO 检查key重复
|
||||
},
|
||||
isDisable: function (index) {
|
||||
return this.items.length - 1 === index;
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.items.length === 0) {
|
||||
this.items.push(this.create());
|
||||
this.add();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,28 +2,30 @@
|
|||
<div class="request-container">
|
||||
<div class="request-item" v-for="(request, index) in requests" :key="index" @click="select(request)"
|
||||
:class="{'selected': isSelected(request)}">
|
||||
<span class="request-method">
|
||||
{{request.method}}
|
||||
</span>
|
||||
<span class="request-name">
|
||||
{{request.name}}
|
||||
</span>
|
||||
<span class="request-btn">
|
||||
<el-dropdown trigger="click" @command="handleCommand">
|
||||
<span class="el-dropdown-link el-icon-more"></span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="{type: 'copy', index: index}">复制请求</el-dropdown-item>
|
||||
<el-dropdown-item :command="{type: 'delete', index: index}">删除请求</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</span>
|
||||
<el-row type="flex">
|
||||
<div class="request-method">
|
||||
{{request.method}}
|
||||
</div>
|
||||
<div class="request-name">
|
||||
{{request.name}}
|
||||
</div>
|
||||
<div class="request-btn">
|
||||
<el-dropdown trigger="click" @command="handleCommand">
|
||||
<span class="el-dropdown-link el-icon-more"></span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="{type: 'copy', index: index}">复制请求</el-dropdown-item>
|
||||
<el-dropdown-item :command="{type: 'delete', index: index}">删除请求</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-button class="request-create" type="primary" size="mini" icon="el-icon-plus" plain @click="create"/>
|
||||
<el-button class="request-create" type="primary" size="mini" icon="el-icon-plus" plain @click="createRequest"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {generateId} from 'element-ui/src/utils/util';
|
||||
import {Request} from "../model/APIModel";
|
||||
|
||||
export default {
|
||||
name: "MsApiRequest",
|
||||
|
@ -34,7 +36,7 @@
|
|||
|
||||
data() {
|
||||
return {
|
||||
selected: 0
|
||||
selected: 0,
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -47,10 +49,20 @@
|
|||
},
|
||||
|
||||
methods: {
|
||||
create: function () {
|
||||
let request = this.createRequest();
|
||||
createRequest: function () {
|
||||
let request = new Request({method: "GET"});
|
||||
this.requests.push(request);
|
||||
},
|
||||
copyRequest: function (index) {
|
||||
let request = this.requests[index];
|
||||
this.requests.push(JSON.parse(JSON.stringify(request)));
|
||||
},
|
||||
deleteRequest: function (index) {
|
||||
this.requests.splice(index, 1);
|
||||
if (this.requests.length === 0) {
|
||||
this.createRequest();
|
||||
}
|
||||
},
|
||||
handleCommand: function (command) {
|
||||
switch (command.type) {
|
||||
case "copy":
|
||||
|
@ -61,33 +73,6 @@
|
|||
break;
|
||||
}
|
||||
},
|
||||
copyRequest: function (index) {
|
||||
let request = this.requests[index];
|
||||
this.requests.push(JSON.parse(JSON.stringify(request)));
|
||||
},
|
||||
deleteRequest: function (index) {
|
||||
this.requests.splice(index, 1);
|
||||
if (this.requests.length === 0) {
|
||||
this.create();
|
||||
}
|
||||
},
|
||||
createRequest: function () {
|
||||
return {
|
||||
randomId: generateId(),
|
||||
type: "Request",
|
||||
method: "GET",
|
||||
name: "",
|
||||
parameters: [],
|
||||
headers: [],
|
||||
body: {
|
||||
type: "kv",
|
||||
kvs: [],
|
||||
text: ""
|
||||
},
|
||||
assertions: [],
|
||||
extract: []
|
||||
}
|
||||
},
|
||||
select: function (request) {
|
||||
this.selected = request;
|
||||
this.open(request);
|
||||
|
@ -96,7 +81,7 @@
|
|||
|
||||
created() {
|
||||
if (this.requests.length === 0) {
|
||||
this.create();
|
||||
this.createRequest();
|
||||
this.select(this.requests[0]);
|
||||
}
|
||||
}
|
||||
|
@ -126,11 +111,13 @@
|
|||
|
||||
.request-method {
|
||||
padding: 0 5px;
|
||||
width: 60px;
|
||||
color: #1E90FF;
|
||||
}
|
||||
|
||||
.request-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<el-form :model="request" :rules="rules" ref="request" label-width="100px" label-position="left" v-if="isRequest">
|
||||
<el-form :model="request" :rules="rules" ref="request" label-width="100px">
|
||||
<el-form-item :label="$t('api_test.request.name')" prop="name">
|
||||
<el-input v-model="request.name"></el-input>
|
||||
<el-input v-model="request.name" maxlength="100"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('api_test.request.url')" prop="url">
|
||||
<el-input v-model="request.url" :placeholder="$t('api_test.request.url_describe')">
|
||||
<el-input v-model="request.url" maxlength="100" :placeholder="$t('api_test.request.url_description')">
|
||||
<el-select v-model="request.method" slot="prepend" class="request-method-select">
|
||||
<el-option label="GET" value="GET"></el-option>
|
||||
<el-option label="POST" value="POST"></el-option>
|
||||
|
@ -29,8 +29,8 @@
|
|||
<el-tab-pane :label="$t('api_test.request.body')" name="body" v-if="isNotGet">
|
||||
<ms-api-body :body="request.body"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('api_test.request.assertions')" name="assertions" v-if="false">
|
||||
TODO
|
||||
<el-tab-pane :label="$t('api_test.request.assertions.label')" name="assertions">
|
||||
<ms-api-assertions :assertions="request.assertions"></ms-api-assertions>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('api_test.request.extract')" name="extract" v-if="false">
|
||||
TODO
|
||||
|
@ -42,10 +42,11 @@
|
|||
<script>
|
||||
import MsApiKeyValue from "./ApiKeyValue";
|
||||
import MsApiBody from "./ApiBody";
|
||||
import MsApiAssertions from "./ApiAssertions";
|
||||
|
||||
export default {
|
||||
name: "MsApiRequestForm",
|
||||
components: {MsApiBody, MsApiKeyValue},
|
||||
components: {MsApiAssertions, MsApiBody, MsApiKeyValue},
|
||||
props: {
|
||||
request: Object
|
||||
},
|
||||
|
@ -53,14 +54,19 @@
|
|||
data() {
|
||||
return {
|
||||
activeName: "parameters",
|
||||
rules: {}
|
||||
rules: {
|
||||
name: [
|
||||
{required: true, message: this.$t('api_test.scenario.input_name'), trigger: 'blur'},
|
||||
{max: 100, message: this.$t('commons.input_limit', [0, 100]), trigger: 'blur'}
|
||||
],
|
||||
url: [
|
||||
{max: 100, message: this.$t('commons.input_limit', [0, 100]), trigger: 'blur'}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isRequest() {
|
||||
return this.request.type === "Request";
|
||||
},
|
||||
isNotGet() {
|
||||
return this.request.method !== "GET";
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<el-form :model="scenario" :rules="rules" ref="scenario" label-width="100px" label-position="left" v-if="isScenario">
|
||||
<el-form :model="scenario" :rules="rules" ref="scenario" label-width="100px">
|
||||
<el-form-item :label="$t('api_test.scenario.name')" prop="name">
|
||||
<el-input v-model="scenario.name"></el-input>
|
||||
<el-input v-model="scenario.name" maxlength="100"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('api_test.scenario.base_url')" prop="url">
|
||||
<el-input :placeholder="$t('api_test.scenario.base_url_describe')" v-model="scenario.url"></el-input>
|
||||
<el-input :placeholder="$t('api_test.scenario.base_url_description')" v-model="scenario.url" maxlength="100"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-tabs v-model="activeName">
|
||||
|
@ -32,15 +32,17 @@
|
|||
data() {
|
||||
return {
|
||||
activeName: "variables",
|
||||
rules: {}
|
||||
rules: {
|
||||
name: [
|
||||
{required: true, message: this.$t('api_test.scenario.input_name'), trigger: 'blur'},
|
||||
{max: 100, message: this.$t('commons.input_limit', [0, 100]), trigger: 'blur'}
|
||||
],
|
||||
url: [
|
||||
{max: 100, message: this.$t('commons.input_limit', [0, 100]), trigger: 'blur'}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isScenario() {
|
||||
return this.scenario.type === "Scenario";
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
import {generateId} from "element-ui/src/utils/util";
|
||||
|
||||
const assign = function (obj, options) {
|
||||
for (let name in options) {
|
||||
if (options.hasOwnProperty(name)) {
|
||||
obj[name] = options[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const BODY_TYPE = {
|
||||
KV: "KV",
|
||||
TEXT: "TEXT"
|
||||
}
|
||||
|
||||
export const ASSERTION_TYPE = {
|
||||
TEXT: "TEXT",
|
||||
REGEX: "REGEX",
|
||||
RESPONSE_TIME: "RESPONSE_TIME"
|
||||
}
|
||||
|
||||
export class Scenario {
|
||||
constructor(options) {
|
||||
this.name = null;
|
||||
this.url = null;
|
||||
this.variables = [];
|
||||
this.headers = [];
|
||||
this.requests = [];
|
||||
|
||||
assign(this, options);
|
||||
}
|
||||
}
|
||||
|
||||
export class Request {
|
||||
constructor(options) {
|
||||
this.randomId = generateId();
|
||||
this.name = null;
|
||||
this.url = null;
|
||||
this.method = null;
|
||||
this.parameters = [];
|
||||
this.headers = [];
|
||||
this.body = new Body();
|
||||
this.assertions = new Assertions();
|
||||
this.extract = [];
|
||||
|
||||
assign(this, options);
|
||||
}
|
||||
}
|
||||
|
||||
export class Body {
|
||||
constructor(options) {
|
||||
this.type = null;
|
||||
this.text = null;
|
||||
this.kvs = [];
|
||||
|
||||
assign(this, options);
|
||||
}
|
||||
|
||||
isKV() {
|
||||
return this.type === BODY_TYPE.KV;
|
||||
}
|
||||
}
|
||||
|
||||
export class KeyValue {
|
||||
constructor(options) {
|
||||
this.key = null;
|
||||
this.value = null;
|
||||
|
||||
assign(this, options);
|
||||
}
|
||||
}
|
||||
|
||||
export class Assertions {
|
||||
constructor(options) {
|
||||
this.text = [];
|
||||
this.regex = [];
|
||||
this.responseTime = new ResponseTime();
|
||||
|
||||
assign(this, options);
|
||||
}
|
||||
}
|
||||
|
||||
class AssertionType {
|
||||
constructor(type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
export class Text extends AssertionType {
|
||||
constructor(options) {
|
||||
super(ASSERTION_TYPE.TEXT);
|
||||
this.subject = null;
|
||||
this.condition = null;
|
||||
this.value = null;
|
||||
|
||||
assign(this, options);
|
||||
}
|
||||
}
|
||||
|
||||
export class Regex extends AssertionType {
|
||||
constructor(options) {
|
||||
super(ASSERTION_TYPE.REGEX);
|
||||
this.subject = null;
|
||||
this.expression = null;
|
||||
this.description = null;
|
||||
|
||||
assign(this, options);
|
||||
}
|
||||
}
|
||||
|
||||
export class ResponseTime extends AssertionType {
|
||||
constructor(options) {
|
||||
super(ASSERTION_TYPE.RESPONSE_TIME);
|
||||
this.responseInTime = null;
|
||||
|
||||
assign(this, options);
|
||||
}
|
||||
|
||||
isValid() {
|
||||
return this.responseInTime !== null && this.responseInTime > 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -45,7 +45,8 @@ export default {
|
|||
'refresh': '刷新',
|
||||
'remark': '备注',
|
||||
'delete': '删除',
|
||||
'not_filled': '未填写'
|
||||
'not_filled': '未填写',
|
||||
'please_select': '请选择',
|
||||
},
|
||||
workspace: {
|
||||
'create': '创建工作空间',
|
||||
|
@ -169,25 +170,43 @@ export default {
|
|||
},
|
||||
api_test: {
|
||||
scenario: {
|
||||
input_name: "请输入场景名称",
|
||||
name: "场景名称",
|
||||
base_url: "基础URL",
|
||||
base_url_describe: "基础URL作为所有请求的URL前缀",
|
||||
base_url_description: "基础URL作为所有请求的URL前缀",
|
||||
variables: "变量",
|
||||
headers: "请求头"
|
||||
},
|
||||
request: {
|
||||
input_name: "请输入请求名称",
|
||||
name: "请求名称",
|
||||
method: "请求方法",
|
||||
url: "请求URL",
|
||||
url_describe: "例如: https://fit2cloud.com",
|
||||
url_description: "例如: https://fit2cloud.com",
|
||||
parameters: "请求参数",
|
||||
parameters_desc: "参数追加到URL,例如https://fit2cloud.com/entries?key1=Value1&Key2=Value2",
|
||||
headers: "请求头",
|
||||
body: "请求内容",
|
||||
body_kv: "键值对",
|
||||
body_text: "文本",
|
||||
assertions: "断言",
|
||||
extract: "提取"
|
||||
assertions: {
|
||||
label: "断言",
|
||||
text: "文本",
|
||||
regex: "正则",
|
||||
response_time: "响应时间",
|
||||
select_type: "请选择类型",
|
||||
select_subject: "请选择对象",
|
||||
select_contains: "请选择条件",
|
||||
contains: "包含",
|
||||
not_contains: "不包含",
|
||||
equals: "等于",
|
||||
start_with: "以...开始",
|
||||
end_with: "以...结束",
|
||||
value: "值",
|
||||
expression: "正则表达式",
|
||||
response_in_time: "响应时间在...毫秒以内",
|
||||
},
|
||||
extract: "提取",
|
||||
}
|
||||
},
|
||||
test_track: {
|
||||
|
|
Loading…
Reference in New Issue