feat(接口定义): 支持接口定义导出为 swagger 格式 (#1606)
* feat(测试跟踪): 测试用例下载模版增加标签列 * fix(接口定义): 扩大请求头键长度 * feat(接口定义): 支持接口定义导出为 swagger 格式
This commit is contained in:
parent
b8c8d036bf
commit
c25f10050b
|
@ -148,10 +148,10 @@ public class ApiDefinitionController {
|
|||
return apiDefinitionService.apiTestImport(file, request);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/export")
|
||||
@PostMapping(value = "/export/{type}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public ApiExportResult export(@RequestBody ApiBatchRequest request) {
|
||||
return apiDefinitionService.export(request);
|
||||
public ApiExportResult export(@RequestBody ApiBatchRequest request, @PathVariable String type) {
|
||||
return apiDefinitionService.export(request, type);
|
||||
}
|
||||
|
||||
//定时任务创建
|
||||
|
|
|
@ -1,19 +1,10 @@
|
|||
package io.metersphere.api.dto.definition;
|
||||
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ApiExportResult {
|
||||
private String projectName;
|
||||
private String protocol;
|
||||
private String projectId;
|
||||
private String version;
|
||||
private List<ApiDefinitionWithBLOBs> data;
|
||||
private List<ApiTestCaseWithBLOBs> cases;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package io.metersphere.api.dto.definition;
|
||||
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class MsApiExportResult extends ApiExportResult {
|
||||
private String projectName;
|
||||
private String protocol;
|
||||
private String projectId;
|
||||
private String version;
|
||||
private List<ApiDefinitionWithBLOBs> data;
|
||||
private List<ApiTestCaseWithBLOBs> cases;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.api.dto.definition;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.definition.parse.swagger.SwaggerInfo;
|
||||
import io.metersphere.api.dto.definition.parse.swagger.SwaggerTag;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class SwaggerApiExportResult extends ApiExportResult{
|
||||
private String openapi;
|
||||
private SwaggerInfo info;
|
||||
private String externalDocs;
|
||||
private List<String> servers;
|
||||
private List<SwaggerTag> tags;
|
||||
private JSONObject paths; // Map<String, Object>, Object 里放 Operation 对象
|
||||
private List<String> components;
|
||||
}
|
|
@ -30,14 +30,14 @@ public class Swagger2Parser extends SwaggerAbstractParser {
|
|||
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
Swagger swagger;
|
||||
String sourceStr = "";
|
||||
if (StringUtils.isNotBlank(request.getSwaggerUrl())) {
|
||||
if (StringUtils.isNotBlank(request.getSwaggerUrl())) { // 使用 url 导入 swagger
|
||||
swagger = new SwaggerParser().read(request.getSwaggerUrl());
|
||||
} else {
|
||||
sourceStr = getApiTestStr(source);
|
||||
sourceStr = getApiTestStr(source); // 导入的二进制文件转换为 String
|
||||
swagger = new SwaggerParser().readWithInfo(sourceStr).getSwagger();
|
||||
}
|
||||
|
||||
if (swagger == null || swagger.getSwagger() == null) {
|
||||
if (swagger == null || swagger.getSwagger() == null) { // 不是 2.0 版本,则尝试转换 3.0
|
||||
Swagger3Parser swagger3Parser = new Swagger3Parser();
|
||||
return swagger3Parser.parse(sourceStr, request);
|
||||
}
|
||||
|
|
|
@ -4,14 +4,18 @@ import com.alibaba.fastjson.JSON;
|
|||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.SwaggerApiExportResult;
|
||||
import io.metersphere.api.dto.definition.parse.swagger.*;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.definition.response.HttpResponse;
|
||||
import io.metersphere.api.dto.scenario.Body;
|
||||
import io.metersphere.api.dto.scenario.KeyValue;
|
||||
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||
import io.metersphere.api.service.ApiModuleService;
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiModule;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.XMLUtils;
|
||||
import io.swagger.parser.OpenAPIParser;
|
||||
|
@ -362,4 +366,119 @@ public class Swagger3Parser extends SwaggerAbstractParser {
|
|||
QueryParameter queryParameter = (QueryParameter) parameter;
|
||||
arguments.add(new KeyValue(queryParameter.getName(), "", getDefaultStringValue(queryParameter.getDescription()), parameter.getRequired()));
|
||||
}
|
||||
/* 导出的 swagger json描述文件样例
|
||||
{
|
||||
"openapi":"3.0.1",
|
||||
"info":{},
|
||||
"externalDocs":{},
|
||||
"servers":{},
|
||||
"tags":{},
|
||||
"paths":{ // 对应 SwaggerApiExportResult 类的paths
|
||||
"/lzx/test/{ball}":{ // key
|
||||
"get":{ // 对应 SwaggerPath 类的 JSONObject 类型的成员,”get“为key
|
||||
"tags":[
|
||||
"subModule2"
|
||||
],
|
||||
"summary":"API",
|
||||
"parameters":[
|
||||
{
|
||||
"name":"ballName",
|
||||
"in":"query",// path,header,query都可选。
|
||||
"description":"描述param",
|
||||
"required":true // 是否必填参数
|
||||
}
|
||||
],
|
||||
"requestBody":{
|
||||
"content":{
|
||||
"application/octet-stream":{ // type
|
||||
"schema":{
|
||||
"type":null,
|
||||
"format":null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // SwaggerApiInfo类,为 value
|
||||
}
|
||||
},
|
||||
"components":{}
|
||||
} */
|
||||
public SwaggerApiExportResult swagger3Export(List<ApiDefinitionWithBLOBs> apiDefinitionList) {
|
||||
SwaggerApiExportResult result = new SwaggerApiExportResult();
|
||||
|
||||
result.setOpenapi("3.0.1");
|
||||
result.setInfo(new SwaggerInfo());
|
||||
result.setServers(new ArrayList<>());
|
||||
result.setTags(new ArrayList<>());
|
||||
result.setComponents(new ArrayList<>());
|
||||
|
||||
JSONObject paths = new JSONObject();
|
||||
JSONObject swaggerPath = new JSONObject();
|
||||
for(ApiDefinitionWithBLOBs apiDefinition : apiDefinitionList) {
|
||||
SwaggerApiInfo swaggerApiInfo = new SwaggerApiInfo(); // {tags:, summary:, description:, parameters:}
|
||||
swaggerApiInfo.setSummary(apiDefinition.getName());
|
||||
// 设置导入后的模块名 (根据 api 的 moduleID 查库获得所属模块,作为导出的模块名)
|
||||
ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
String moduleName = apiModuleService.getNode(apiDefinition.getModuleId()).getName();
|
||||
swaggerApiInfo.setTags(Arrays.asList(moduleName));
|
||||
// 设置请求体
|
||||
JSONObject requestObject = JSON.parseObject(apiDefinition.getRequest()); // 将api的request属性转换成JSON对象以便获得参数
|
||||
JSONObject requestBody = buildRequestBody(requestObject);
|
||||
swaggerApiInfo.setRequestBody(requestBody);
|
||||
// 设置请求参数列表
|
||||
List<JSONObject> paramsList = buildParameters(requestObject);
|
||||
swaggerApiInfo.setParameters(paramsList);
|
||||
swaggerPath.put(apiDefinition.getMethod().toLowerCase(), JSON.parseObject(JSON.toJSONString(swaggerApiInfo))); // 设置api的请求类型和api定义、参数
|
||||
paths.put(apiDefinition.getPath(), swaggerPath);
|
||||
}
|
||||
result.setPaths(paths);
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<JSONObject> buildParameters(JSONObject request) {
|
||||
List<JSONObject> paramsList = new ArrayList<>();
|
||||
Hashtable<String, String> typeMap = new Hashtable<String, String>() {{
|
||||
put("headers", "header");
|
||||
put("rest", "path");
|
||||
put("arguments", "query");
|
||||
}};
|
||||
Set<String> typeKeys = typeMap.keySet();
|
||||
for(String type : typeKeys) {
|
||||
JSONArray params = request.getJSONArray(type); // 获得请求参数列表
|
||||
if(params != null) {
|
||||
for(int i = 0; i < params.size(); ++i) {
|
||||
JSONObject param = params.getJSONObject(i); // 对于每个参数:
|
||||
SwaggerParams swaggerParam = new SwaggerParams();
|
||||
swaggerParam.setIn(typeMap.get(type)); // 利用 map,根据 request 的 key 设置对应的参数类型
|
||||
swaggerParam.setDescription((String) param.get("description"));
|
||||
swaggerParam.setName((String) param.get("name"));
|
||||
swaggerParam.setRequired((boolean) param.get("required"));
|
||||
paramsList.add(JSON.parseObject(JSON.toJSONString(swaggerParam)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return paramsList;
|
||||
}
|
||||
|
||||
private JSONObject buildRequestBody(JSONObject request) {
|
||||
Hashtable<String, String> typeMap = new Hashtable<String, String>() {{
|
||||
put("XML", org.springframework.http.MediaType.APPLICATION_XML_VALUE);
|
||||
put("JSON", org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
|
||||
put("Raw", "application/urlencoded");
|
||||
put("BINARY", org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
put("Form Data", org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE);
|
||||
put("WWW_FORM", org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
}};
|
||||
String type = request.getJSONObject("body").getString("type");
|
||||
JSONObject requestBody = new JSONObject();
|
||||
JSONObject schema = new JSONObject();
|
||||
JSONObject typeName = new JSONObject();
|
||||
schema.put("type", null);
|
||||
schema.put("format", null);
|
||||
typeName.put("schema", schema);
|
||||
JSONObject content = new JSONObject();
|
||||
content.put(typeMap.get(type), typeName);
|
||||
requestBody.put("content", content);
|
||||
return requestBody;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package io.metersphere.api.dto.definition.parse.swagger;
|
||||
import lombok.*;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
该类表示 swagger3 的 paths 字段下每个请求类型中的 value,即表示一个 api 定义
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class SwaggerApiInfo {
|
||||
private List<String> tags; // 对应一个 API 在MS项目中所在的 module 名称
|
||||
private String summary; // 对应 API 的名字
|
||||
private List<JSONObject> parameters; // 对应 API 的请求参数
|
||||
private JSONObject requestBody;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package io.metersphere.api.dto.definition.parse.swagger;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class SwaggerParams {
|
||||
private String name; // 对应 API 请求参数名
|
||||
private String in; // 参数类型,可选值为 path,header,query 等
|
||||
private String description;
|
||||
private boolean required; // 是否是必填参数
|
||||
}
|
|
@ -10,6 +10,7 @@ import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
|||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImportParserFactory;
|
||||
import io.metersphere.api.dto.definition.parse.Swagger3Parser;
|
||||
import io.metersphere.api.dto.definition.request.ParameterConfig;
|
||||
import io.metersphere.api.dto.definition.request.ScheduleInfoSwaggerUrlRequest;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
|
@ -762,18 +763,27 @@ public class ApiDefinitionService {
|
|||
scheduleService.addOrUpdateCronJob(request, SwaggerUrlImportJob.getJobKey(request.getResourceId()), SwaggerUrlImportJob.getTriggerKey(request.getResourceId()), SwaggerUrlImportJob.class);
|
||||
}
|
||||
|
||||
public ApiExportResult export(ApiBatchRequest request) {
|
||||
public ApiExportResult export(ApiBatchRequest request, String type) {
|
||||
ApiExportResult apiExportResult;
|
||||
ServiceUtils.getSelectAllIds(request, request.getCondition(),
|
||||
(query) -> extApiDefinitionMapper.selectIds(query));
|
||||
ApiDefinitionExample example = new ApiDefinitionExample();
|
||||
example.createCriteria().andIdIn(request.getIds());
|
||||
ApiExportResult apiExportResult = new ApiExportResult();
|
||||
apiExportResult.setData(apiDefinitionMapper.selectByExampleWithBLOBs(example));
|
||||
apiExportResult.setCases(apiTestCaseService.selectCasesBydApiIds(request.getIds()));
|
||||
apiExportResult.setProjectName(request.getProjectId());
|
||||
apiExportResult.setProtocol(request.getProtocol());
|
||||
apiExportResult.setProjectId(request.getProjectId());
|
||||
apiExportResult.setVersion(System.getenv("MS_VERSION"));
|
||||
|
||||
if (StringUtils.equals(type, "MS")) { // 导出为 Metersphere 格式
|
||||
apiExportResult = new MsApiExportResult();
|
||||
((MsApiExportResult) apiExportResult).setData(apiDefinitionMapper.selectByExampleWithBLOBs(example));
|
||||
((MsApiExportResult) apiExportResult).setCases(apiTestCaseService.selectCasesBydApiIds(request.getIds()));
|
||||
((MsApiExportResult) apiExportResult).setProjectName(request.getProjectId());
|
||||
((MsApiExportResult) apiExportResult).setProtocol(request.getProtocol());
|
||||
((MsApiExportResult) apiExportResult).setProjectId(request.getProjectId());
|
||||
((MsApiExportResult) apiExportResult).setVersion(System.getenv("MS_VERSION"));
|
||||
}
|
||||
else { // 导出为 Swagger 格式
|
||||
Swagger3Parser swagger3Parser = new Swagger3Parser();
|
||||
System.out.println(apiDefinitionMapper.selectByExampleWithBLOBs(example));
|
||||
apiExportResult = swagger3Parser.swagger3Export(apiDefinitionMapper.selectByExampleWithBLOBs(example));
|
||||
}
|
||||
return apiExportResult;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -348,12 +348,12 @@ import MsTabButton from "@/business/components/common/components/MsTabButton";
|
|||
apiCaseClose() {
|
||||
this.showCasePage = true;
|
||||
},
|
||||
exportAPI() {
|
||||
exportAPI(type) {
|
||||
if (!this.isApiListEnable) {
|
||||
this.$warning('用例列表暂不支持导出,请切换成接口列表');
|
||||
return;
|
||||
}
|
||||
this.$refs.apiList[0].exportApi();
|
||||
this.$refs.apiList[0].exportApi(type);
|
||||
},
|
||||
refresh(data) {
|
||||
this.$refs.apiList[0].initTable(data);
|
||||
|
|
|
@ -698,18 +698,23 @@ export default {
|
|||
let ids = rowArray.map(s => s.id);
|
||||
return ids;
|
||||
},
|
||||
exportApi() {
|
||||
exportApi(type) {
|
||||
let param = buildBatchParam(this);
|
||||
param.protocol = this.currentProtocol;
|
||||
if (param.ids === undefined || param.ids.length < 1) {
|
||||
this.$warning(this.$t("api_test.definition.check_select"));
|
||||
return;
|
||||
}
|
||||
this.result = this.$post("/api/definition/export", param, response => {
|
||||
this.result = this.$post("/api/definition/export/" + type, param, response => {
|
||||
let obj = response.data;
|
||||
if(type == 'MS') {
|
||||
obj.protocol = this.currentProtocol;
|
||||
this.buildApiPath(obj.data);
|
||||
downloadFile("Metersphere_Api_" + localStorage.getItem(PROJECT_NAME) + ".json", JSON.stringify(obj));
|
||||
}
|
||||
else {
|
||||
downloadFile("Swagger_Api_" + localStorage.getItem(PROJECT_NAME) + ".json", JSON.stringify(obj));
|
||||
}
|
||||
});
|
||||
},
|
||||
buildApiPath(apis) {
|
||||
|
|
|
@ -188,8 +188,8 @@ export default {
|
|||
this.$refs.nodeTree.append({}, dataArr[0]);
|
||||
}
|
||||
},
|
||||
exportAPI() {
|
||||
this.$emit('exportAPI');
|
||||
exportAPI(type) {
|
||||
this.$emit('exportAPI', type);
|
||||
},
|
||||
debug() {
|
||||
this.$emit('debug');
|
||||
|
|
|
@ -14,13 +14,29 @@
|
|||
<template v-slot:append>
|
||||
<el-dropdown v-if="!isReadOnly" size="small" split-button type="primary" class="ms-api-button" @click="handleCommand('add-api')"
|
||||
v-tester
|
||||
@command="handleCommand">
|
||||
@command="handleCommand"
|
||||
:hide-on-click='false'
|
||||
trigger="click">
|
||||
<el-button icon="el-icon-folder-add" @click="addApi"></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="add-api">{{ $t('api_test.definition.request.title') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="debug">{{ $t('api_test.definition.request.fast_debug') }}</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-item command="export">
|
||||
<el-dropdown placement="right-start" @command="chooseExportType">
|
||||
<span>
|
||||
{{ $t('report.export') }} <i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<template>
|
||||
<el-dropdown-item command="export-MS">{{ $t('report.export_to_ms_format') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="export-Swagger" v-show="condition.protocol=='HTTP'">
|
||||
{{ $t('report.export_to_swagger3_format') }}
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
@ -44,10 +60,11 @@ import ApiImport from "../import/ApiImport";
|
|||
import ModuleTrashButton from "./ModuleTrashButton";
|
||||
import {getCurrentProjectID} from "../../../../../../common/js/utils";
|
||||
import {buildNodePath} from "@/business/components/api/definition/model/NodeTree";
|
||||
import TemplateComponent from "../../../../track/plan/view/comonents/report/TemplateComponent/TemplateComponent";
|
||||
|
||||
export default {
|
||||
name: "ApiModuleHeader",
|
||||
components: {ModuleTrashButton, ApiImport, MsAddBasisApi},
|
||||
components: {TemplateComponent, ModuleTrashButton, ApiImport, MsAddBasisApi},
|
||||
data() {
|
||||
return {
|
||||
options: OPTIONS,
|
||||
|
@ -104,12 +121,19 @@ export default {
|
|||
});
|
||||
this.$refs.apiImport.open(this.currentModule);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
},
|
||||
chooseExportType(e) {
|
||||
if (!getCurrentProjectID()) {
|
||||
this.$warning(this.$t('commons.check_project_tip'));
|
||||
return;
|
||||
}
|
||||
this.$emit('exportAPI');
|
||||
switch (e) {
|
||||
case "export-MS":
|
||||
this.$emit('exportAPI', 'MS');
|
||||
break;
|
||||
case "export-Swagger":
|
||||
this.$emit('exportAPI', 'Swagger');
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -427,6 +427,8 @@ export default {
|
|||
downloadJtl: 'Download JTL',
|
||||
test_execute_again: 'Test Execute Again',
|
||||
export: 'Export',
|
||||
export_to_ms_format: 'Export to Metersphere format',
|
||||
export_to_swagger3_format: 'Export to Swagger3.0 format',
|
||||
compare: 'Compare',
|
||||
generation_error: 'Report generation error, unable to view, please check log details!',
|
||||
being_generated: 'Report is being generated...',
|
||||
|
@ -597,7 +599,7 @@ export default {
|
|||
save_as_case: "Save as new use case",
|
||||
update_api: "Update interface",
|
||||
body_form_data: "form-data",
|
||||
body_x_www_from_urlencoded: "x-www-from-urlencoded",
|
||||
body_x_www_from_urlencoded: "x-www-form-urlencoded",
|
||||
body_raw: "raw",
|
||||
body_binary: "binary",
|
||||
body_json: "json",
|
||||
|
|
|
@ -425,6 +425,8 @@ export default {
|
|||
test_execute_again: '再次执行',
|
||||
downloadJtl: '下载JTL',
|
||||
export: '导出',
|
||||
export_to_ms_format: '导出 Metersphere 格式',
|
||||
export_to_swagger3_format: '导出 Swagger3.0 格式',
|
||||
compare: '比较',
|
||||
generation_error: '报告生成错误, 无法查看, 请检查日志详情!',
|
||||
being_generated: '报告正在生成中...',
|
||||
|
@ -598,7 +600,7 @@ export default {
|
|||
save_as_case: "另存为新用例",
|
||||
update_api: "更新接口",
|
||||
body_form_data: "form-data",
|
||||
body_x_www_from_urlencoded: "x-www-from-urlencoded",
|
||||
body_x_www_from_urlencoded: "x-www-form-urlencoded",
|
||||
body_raw: "raw",
|
||||
body_binary: "binary",
|
||||
body_json: "json",
|
||||
|
|
|
@ -425,6 +425,8 @@ export default {
|
|||
test_execute_again: '再次執行',
|
||||
downloadJtl: '下載JTL',
|
||||
export: '導出',
|
||||
export_to_ms_format: '導出 Metersphere 格式',
|
||||
export_to_swagger3_format: '導出 Swagger3.0 格式',
|
||||
compare: '比較',
|
||||
generation_error: '報告生成錯誤, 無法查看, 請檢查日誌詳情!',
|
||||
being_generated: '報告正在生成中...',
|
||||
|
@ -597,7 +599,7 @@ export default {
|
|||
save_as_case: "另存為新用例",
|
||||
update_api: "更新接口",
|
||||
body_form_data: "form-data",
|
||||
body_x_www_from_urlencoded: "x-www-from-urlencoded",
|
||||
body_x_www_from_urlencoded: "x-www-form-urlencoded",
|
||||
body_raw: "raw",
|
||||
body_binary: "binary",
|
||||
body_json: "json",
|
||||
|
|
Loading…
Reference in New Issue