feat(接口自动化): 添加导入导出
This commit is contained in:
parent
63d4a7ad81
commit
561c9fea71
|
@ -15,11 +15,28 @@
|
|||
ref="nodeTree">
|
||||
|
||||
<template v-slot:header>
|
||||
<el-input :placeholder="$t('test_track.module.search')" v-model="condition.filterText" size="small">
|
||||
<!--<el-input :placeholder="$t('test_track.module.search')" v-model="condition.filterText" size="small">-->
|
||||
<!--<template v-slot:append>-->
|
||||
<!--<el-button v-if="!isReadOnly" icon="el-icon-folder-add" @click="addScenario" v-tester/>-->
|
||||
<!--</template>-->
|
||||
<!--</el-input>-->
|
||||
|
||||
<el-input class="filter-input" :class="{'read-only': isReadOnly}" :placeholder="$t('test_track.module.search')" v-model="condition.filterText"
|
||||
size="small">
|
||||
<template v-slot:append>
|
||||
<el-button v-if="!isReadOnly" icon="el-icon-folder-add" @click="addScenario" v-tester/>
|
||||
<el-dropdown v-if="!isReadOnly" size="small" split-button type="primary" class="ms-api-button" @click="handleCommand('add-api')"
|
||||
v-tester
|
||||
@command="handleCommand">
|
||||
<el-button icon="el-icon-folder-add" @click="addScenario"></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="add-scenario">{{ $t('api_test.automation.add_scenario') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="import">{{ $t('api_test.api_import.label') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="export">{{ $t('report.export') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
<module-trash-button v-if="!isReadOnly" :condition="condition" :exe="enableTrash"/>
|
||||
</template>
|
||||
|
||||
|
@ -29,8 +46,9 @@
|
|||
@saveAsEdit="saveAsEdit"
|
||||
@refresh="refresh"
|
||||
ref="basisScenario"/>
|
||||
</div>
|
||||
|
||||
<api-import ref="apiImport" :moduleOptions="moduleOptions" @refresh="$emit('refresh')"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -40,6 +58,7 @@
|
|||
import MsNodeTree from "../../../track/common/NodeTree";
|
||||
import {buildNodePath} from "../../definition/model/NodeTree";
|
||||
import ModuleTrashButton from "../../definition/components/module/ModuleTrashButton";
|
||||
import ApiImport from "./common/ScenarioImport";
|
||||
|
||||
export default {
|
||||
name: 'MsApiScenarioModule',
|
||||
|
@ -48,6 +67,7 @@
|
|||
MsNodeTree,
|
||||
MsAddBasisScenario,
|
||||
SelectMenu,
|
||||
ApiImport
|
||||
},
|
||||
props: {
|
||||
isReadOnly: {
|
||||
|
@ -77,6 +97,7 @@
|
|||
projectId: "",
|
||||
data: [],
|
||||
currentModule: undefined,
|
||||
moduleOptions: [],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -98,7 +119,28 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
handleCommand(e) {
|
||||
switch (e) {
|
||||
case "add-scenario":
|
||||
this.addScenario();
|
||||
break;
|
||||
case "import":
|
||||
this.result = this.$get("/api/automation/module/list/" + getCurrentProjectID(), response => {
|
||||
if (response.data != undefined && response.data != null) {
|
||||
this.data = response.data;
|
||||
let moduleOptions = [];
|
||||
this.data.forEach(node => {
|
||||
buildNodePath(node, {path: ''}, moduleOptions);
|
||||
});
|
||||
this.moduleOptions = moduleOptions
|
||||
}
|
||||
});
|
||||
this.$refs.apiImport.open(this.currentModule);
|
||||
break;
|
||||
case "export":
|
||||
break;
|
||||
}
|
||||
},
|
||||
list() {
|
||||
let url = undefined;
|
||||
if (this.isPlanModel) {
|
||||
|
|
|
@ -0,0 +1,299 @@
|
|||
<template>
|
||||
<el-dialog :close-on-click-modal="false" :title="$t('api_test.api_import.title')" width="30%"
|
||||
:visible.sync="visible" class="api-import" v-loading="result.loading" @close="close">
|
||||
|
||||
<div class="header-bar">
|
||||
<div>{{ $t('api_test.api_import.data_format') }}</div>
|
||||
<el-radio-group v-model="selectedPlatformValue">
|
||||
<el-radio v-for="(item, index) in platforms" :key="index" :label="item.value">{{ item.name }}</el-radio>
|
||||
</el-radio-group>
|
||||
|
||||
<div class="operate-button">
|
||||
<el-button class="save-button" type="primary" plain @click="save">
|
||||
{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
<el-button class="cancel-button" type="warning" plain @click="visible = false">
|
||||
{{ $t('commons.cancel') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-form :model="formData" :rules="rules" label-width="100px" v-loading="result.loading" ref="form">
|
||||
<el-row>
|
||||
<el-col :span="11">
|
||||
<el-form-item :label="$t('commons.import_module')">
|
||||
<el-select size="small" v-model="formData.moduleId" class="project-select" clearable>
|
||||
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.import_mode')">
|
||||
<el-select size="small" v-model="formData.modeId" class="project-select" clearable>
|
||||
<el-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<el-divider direction="vertical"/>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<div class="format-tip">
|
||||
<div>
|
||||
<span>{{ $t('api_test.api_import.tip') }}:{{ selectedPlatform.tip }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ $t('api_test.api_import.export_tip') }}:{{ selectedPlatform.exportTip }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsDialogFooter from "../../../../common/components/MsDialogFooter";
|
||||
import {listenGoBack, removeGoBackListener, getCurrentProjectID} from "@/common/js/utils";
|
||||
import {buildNodePath} from "@/business/components/api/definition/model/NodeTree";
|
||||
|
||||
export default {
|
||||
name: "ScenarioImport",
|
||||
components: {MsDialogFooter},
|
||||
props: {
|
||||
saved: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
moduleOptions: {}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
swaggerUrlEable: false,
|
||||
swaggerSynchronization: false,
|
||||
showEnvironmentSelect: true,
|
||||
modeOptions: [{
|
||||
id: 'fullCoverage',
|
||||
name: this.$t('commons.cover')
|
||||
},
|
||||
{
|
||||
id: 'incrementalMerge',
|
||||
name: this.$t('commons.not_cover')
|
||||
}],
|
||||
protocol: "",
|
||||
platforms: [
|
||||
{
|
||||
name: 'Metersphere',
|
||||
value: 'Metersphere',
|
||||
tip: this.$t('api_test.api_import.ms_tip'),
|
||||
exportTip: this.$t('api_test.api_import.ms_export_tip'),
|
||||
suffixes: new Set(['json'])
|
||||
},
|
||||
{
|
||||
name: 'Postman',
|
||||
value: 'Postman',
|
||||
tip: this.$t('api_test.api_import.postman_tip'),
|
||||
exportTip: this.$t('api_test.api_import.post_export_tip'),
|
||||
suffixes: new Set(['json'])
|
||||
},
|
||||
{
|
||||
name: 'Jmeter',
|
||||
value: 'Jmeter',
|
||||
tip: this.$t('api_test.api_import.jmeter_tip'),
|
||||
exportTip: this.$t('api_test.api_import.jmeter_export_tip'),
|
||||
suffixes: new Set(['json'])
|
||||
}
|
||||
],
|
||||
selectedPlatform: {},
|
||||
selectedPlatformValue: 'Metersphere',
|
||||
result: {},
|
||||
projects: [],
|
||||
environments: [],
|
||||
useEnvironment: false,
|
||||
formData: {
|
||||
file: undefined,
|
||||
swaggerUrl: '',
|
||||
modeId: this.$t('commons.not_cover'),
|
||||
moduleId: '',
|
||||
},
|
||||
rules: {},
|
||||
currentModule: {},
|
||||
fileList: []
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
this.selectedPlatform = this.platforms[0];
|
||||
},
|
||||
watch: {
|
||||
selectedPlatformValue() {
|
||||
for (let i in this.platforms) {
|
||||
if (this.platforms[i].value === this.selectedPlatformValue) {
|
||||
this.selectedPlatform = this.platforms[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
scheduleEdit() {
|
||||
if (!this.formData.swaggerUrl) {
|
||||
this.$warning(this.$t('commons.please_fill_path'));
|
||||
this.swaggerSynchronization = !this.swaggerSynchronization
|
||||
} else {
|
||||
if (this.swaggerSynchronization) {
|
||||
this.$refs.scheduleEdit.open(this.buildParam());
|
||||
}
|
||||
}
|
||||
},
|
||||
scheduleEditByText() {
|
||||
this.$refs.scheduleEdit.open(this.buildParam());
|
||||
},
|
||||
open(module) {
|
||||
this.currentModule = module;
|
||||
this.visible = true;
|
||||
listenGoBack(this.close);
|
||||
|
||||
},
|
||||
upload(file) {
|
||||
this.formData.file = file.file;
|
||||
},
|
||||
handleExceed(files, fileList) {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_count'));
|
||||
},
|
||||
handleRemove(file, fileList) {
|
||||
this.formData.file = undefined;
|
||||
},
|
||||
uploadValidate(file, fileList) {
|
||||
let suffix = file.name.substring(file.name.lastIndexOf('.') + 1);
|
||||
if (this.selectedPlatform.suffixes && !this.selectedPlatform.suffixes.has(suffix)) {
|
||||
this.$warning(this.$t('api_test.api_import.suffixFormatErr'));
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_size'));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
save() {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
if ((this.selectedPlatformValue != 'Swagger2' || (this.selectedPlatformValue == 'Swagger2' && !this.swaggerUrlEable)) && !this.formData.file) {
|
||||
this.$warning(this.$t('commons.please_upload'));
|
||||
return;
|
||||
}
|
||||
let param = this.buildParam();
|
||||
this.result = this.$fileUpload('/api/definition/import', param.file, null, this.buildParam(), response => {
|
||||
let res = response.data;
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.visible = false;
|
||||
this.$emit('refresh', res);
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
buildParam() {
|
||||
let param = {};
|
||||
Object.assign(param, this.formData);
|
||||
param.platform = this.selectedPlatformValue;
|
||||
param.saved = this.saved;
|
||||
console.log(this.formData.moduleId)
|
||||
if (this.currentModule) {
|
||||
param.moduleId = this.formData.moduleId
|
||||
this.moduleOptions.filter(item => {
|
||||
if (item.id === this.formData.moduleId) {
|
||||
param.modulePath = item.path
|
||||
}
|
||||
})
|
||||
param.modeId = this.formData.modeId
|
||||
}
|
||||
param.projectId = getCurrentProjectID();
|
||||
if (!this.swaggerUrlEable) {
|
||||
param.swaggerUrl = undefined;
|
||||
}
|
||||
return param;
|
||||
},
|
||||
close() {
|
||||
this.formData = {
|
||||
file: undefined,
|
||||
swaggerUrl: ''
|
||||
};
|
||||
this.fileList = [];
|
||||
removeGoBackListener(this.close);
|
||||
this.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.api-import >>> .el-dialog {
|
||||
min-width: 700px;
|
||||
}
|
||||
|
||||
.format-tip {
|
||||
background: #EDEDED;
|
||||
}
|
||||
|
||||
.api-upload {
|
||||
text-align: center;
|
||||
margin: auto 0;
|
||||
}
|
||||
|
||||
.api-upload >>> .el-upload {
|
||||
width: 100%;
|
||||
max-width: 350px;
|
||||
}
|
||||
|
||||
.api-upload >>> .el-upload-dragger {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-radio-group {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.header-bar, .format-tip, .el-form {
|
||||
border: solid #E1E1E1 1px;
|
||||
margin: 10px 0;
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.header-bar {
|
||||
padding: 10px 30px;
|
||||
}
|
||||
|
||||
.api-import >>> .el-dialog__body {
|
||||
padding: 15px 25px;
|
||||
}
|
||||
|
||||
.operate-button {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.save-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.el-form {
|
||||
padding: 30px 10px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.swagger-url-disable {
|
||||
margin-top: 10px;
|
||||
|
||||
margin-left: 80px;
|
||||
}
|
||||
|
||||
.el-divider {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -839,6 +839,8 @@ export default {
|
|||
postman_tip: "Only Postman Collection V2.1 json files are supported",
|
||||
postman_export_tip: "Export the test collection by Postman",
|
||||
swagger_export_tip: "Export jSON-formatted files via Swagger website",
|
||||
jmeter_export_tip: "Generating JMX file through JMeter",
|
||||
jmeter_tip: "JMX files supporting JMeter 5.2",
|
||||
suffixFormatErr: "The file format does not meet the requirements",
|
||||
swagger_url_import: "Import using URL",
|
||||
timing_synchronization: "Timing synchronization",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export default {
|
||||
commons: {
|
||||
cover:'覆盖',
|
||||
not_cover:'不覆盖',
|
||||
cover: '覆盖',
|
||||
not_cover: '不覆盖',
|
||||
import_mode: '导入模式',
|
||||
import_module: '导入模块',
|
||||
please_fill_in_the_template: '请填写模版内容',
|
||||
|
@ -842,6 +842,8 @@ export default {
|
|||
swagger_tip: "支持 Swagger 2.0 与 3.0 版本的 json 文件",
|
||||
post_export_tip: "通过 Postman 导出测试集合",
|
||||
swagger_export_tip: "通过 Swagger 页面导出",
|
||||
jmeter_export_tip: "通过 Jmeter 生成JMX文件",
|
||||
jmeter_tip: "支持 Jmeter 5.2版本的JMX 文件",
|
||||
suffixFormatErr: "文件格式不符合要求",
|
||||
swagger_url_import: "使用URL导入",
|
||||
timing_synchronization: "定时同步",
|
||||
|
|
|
@ -841,6 +841,8 @@ export default {
|
|||
swagger_tip: "支持 Swagger 2.0 與 3.0 版本的 json 文件",
|
||||
post_export_tip: "通過 Postman 導出測試集合",
|
||||
swagger_export_tip: "通過 Swagger 頁面導出",
|
||||
jmeter_export_tip: "通過 Jmeter 生成JMX文件",
|
||||
jmeter_tip: "支持 Jmeter 5.2版本的JMX 文件",
|
||||
suffixFormatErr: "文件格式不符合要求",
|
||||
swagger_url_import: "使用URL導入",
|
||||
timing_synchronization: "定時同步",
|
||||
|
|
Loading…
Reference in New Issue