Merge branch 'master' of https://github.com/metersphere/metersphere
Conflicts: backend/src/main/resources/db/migration/V78__v1.8_release.sql
This commit is contained in:
commit
4edddd5e39
|
@ -0,0 +1,150 @@
|
||||||
|
package io.metersphere.api.dto.automation.parse;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||||
|
import io.metersphere.api.dto.definition.parse.har.HarUtils;
|
||||||
|
import io.metersphere.api.dto.definition.parse.har.model.*;
|
||||||
|
import io.metersphere.api.dto.definition.request.MsScenario;
|
||||||
|
import io.metersphere.api.dto.definition.request.MsTestElement;
|
||||||
|
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||||
|
import io.metersphere.api.dto.scenario.KeyValue;
|
||||||
|
import io.metersphere.api.jmeter.RequestResult;
|
||||||
|
import io.metersphere.api.jmeter.ResponseResult;
|
||||||
|
import io.metersphere.api.parse.HarScenarioAbstractParser;
|
||||||
|
import io.metersphere.api.service.ApiScenarioModuleService;
|
||||||
|
import io.metersphere.base.domain.ApiScenarioModule;
|
||||||
|
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HarScenarioParser extends HarScenarioAbstractParser<ScenarioImport> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScenarioImport parse(InputStream source, ApiTestImportRequest request) {
|
||||||
|
Har har = null;
|
||||||
|
try {
|
||||||
|
String sourceStr = getApiTestStr(source);
|
||||||
|
har = HarUtils.read(sourceStr);
|
||||||
|
} catch (Exception e) {
|
||||||
|
MSException.throwException(e.getMessage());
|
||||||
|
LogUtil.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjectUtils.isEmpty(har)) {
|
||||||
|
MSException.throwException("解析失败,请确认选择的是 Har 格式!");
|
||||||
|
}
|
||||||
|
|
||||||
|
ScenarioImport scenarioImport = new ScenarioImport();
|
||||||
|
|
||||||
|
String harName = request.getFileName();
|
||||||
|
// 场景步骤
|
||||||
|
LinkedList<MsTestElement> apiScenarioWithBLOBs = new LinkedList<>();
|
||||||
|
// ApiScenarioWithBLOBs scenario = new ApiScenarioWithBLOBs();
|
||||||
|
// scenario.setName(harName);
|
||||||
|
|
||||||
|
MsScenario msScenario = new MsScenario();
|
||||||
|
msScenario.setName(harName);
|
||||||
|
this.projectId = request.getProjectId();
|
||||||
|
if (!ObjectUtils.isEmpty(har.log)&&!ObjectUtils.isEmpty(har.log.entries)) {
|
||||||
|
parseItem(har.log.entries, msScenario, apiScenarioWithBLOBs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成场景对象
|
||||||
|
List<ApiScenarioWithBLOBs> scenarioWithBLOBs = new LinkedList<>();
|
||||||
|
parseScenarioWithBLOBs(scenarioWithBLOBs, msScenario, request);
|
||||||
|
scenarioImport.setData(scenarioWithBLOBs);
|
||||||
|
return scenarioImport;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseScenarioWithBLOBs(List<ApiScenarioWithBLOBs> scenarioWithBLOBsList, MsScenario msScenario, ApiTestImportRequest request) {
|
||||||
|
ApiScenarioModule module = ApiScenarioImportUtil.getSelectModule(request.getModuleId());
|
||||||
|
if (module == null) {
|
||||||
|
ApiScenarioModuleService apiModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class);
|
||||||
|
module = apiModuleService.getNewModule(msScenario.getName(), projectId, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiScenarioWithBLOBs scenarioWithBLOBs = parseScenario(msScenario);
|
||||||
|
if (module != null) {
|
||||||
|
scenarioWithBLOBs.setApiScenarioModuleId(module.getId());
|
||||||
|
scenarioWithBLOBs.setModulePath("/" + module.getName());
|
||||||
|
}
|
||||||
|
scenarioWithBLOBsList.add(scenarioWithBLOBs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseItem(List<HarEntry> items, MsScenario scenario, LinkedList<MsTestElement> results) {
|
||||||
|
for (HarEntry item : items) {
|
||||||
|
MsHTTPSamplerProxy request = parseHar(item);
|
||||||
|
if (request != null) {
|
||||||
|
results.add(request);
|
||||||
|
}
|
||||||
|
request.setRequestResult(getRequestResult(request,item));
|
||||||
|
}
|
||||||
|
scenario.setHashTree(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
// private List<ScenarioVariable> parseScenarioVariable(List<PostmanKeyValue> postmanKeyValues) {
|
||||||
|
// if (postmanKeyValues == null) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// List<ScenarioVariable> keyValues = new ArrayList<>();
|
||||||
|
// postmanKeyValues.forEach(item -> keyValues.add(new ScenarioVariable(item.getKey(), item.getValue(), item.getDescription(), VariableTypeConstants.CONSTANT.name())));
|
||||||
|
// return keyValues;
|
||||||
|
// }
|
||||||
|
private RequestResult getRequestResult(MsHTTPSamplerProxy samplerProxy,HarEntry harEntry) {
|
||||||
|
HarRequest request = harEntry.request;
|
||||||
|
HarResponse response = harEntry.response;
|
||||||
|
|
||||||
|
RequestResult requestResult = new RequestResult();
|
||||||
|
requestResult.setName("Response");
|
||||||
|
requestResult.setUrl(request.url);
|
||||||
|
requestResult.setMethod(request.method);
|
||||||
|
if(samplerProxy.getBody()!= null){
|
||||||
|
List<KeyValue> keyValueList = new ArrayList<>();
|
||||||
|
if(!ObjectUtils.isEmpty(request.queryString)){
|
||||||
|
for (HarQueryParm model : request.queryString) {
|
||||||
|
KeyValue keyValue = new KeyValue(model.name,model.value);
|
||||||
|
keyValueList.add(keyValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!ObjectUtils.isEmpty(request.postData)&&!ObjectUtils.isEmpty(request.postData.params)){
|
||||||
|
for (HarPostParam model : request.postData.params) {
|
||||||
|
KeyValue keyValue = new KeyValue(model.name,model.value);
|
||||||
|
keyValueList.add(keyValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requestResult.setBody(JSONArray.toJSONString(keyValueList));
|
||||||
|
}
|
||||||
|
|
||||||
|
requestResult.setHeaders(JSONArray.toJSONString(request.headers));
|
||||||
|
requestResult.setRequestSize(request.bodySize);
|
||||||
|
// requestResult.setStartTime(result.getStartTime());
|
||||||
|
// requestResult.setEndTime(result.getEndTime());
|
||||||
|
// requestResult.setTotalAssertions(result.getAssertionResults().length);
|
||||||
|
// requestResult.setSuccess(result.isSuccessful());
|
||||||
|
// requestResult.setError(result.getErrorCount());
|
||||||
|
if(!ObjectUtils.isEmpty(request.cookies)){
|
||||||
|
requestResult.setCookies(JSONArray.toJSONString(request.cookies));
|
||||||
|
}
|
||||||
|
|
||||||
|
ResponseResult responseResult = requestResult.getResponseResult();
|
||||||
|
responseResult.setHeaders(JSONArray.toJSONString(response.headers));
|
||||||
|
// responseResult.setLatency(result.getLatency());
|
||||||
|
responseResult.setResponseCode(String.valueOf(response.status));
|
||||||
|
responseResult.setResponseSize(response.bodySize);
|
||||||
|
// responseResult.setResponseTime(result.getTime());
|
||||||
|
if(response.content != null && response.content.text != null){
|
||||||
|
responseResult.setBody(response.content.text);
|
||||||
|
responseResult.setResponseMessage(response.content.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestResult;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,8 @@ public class ScenarioImportParserFactory {
|
||||||
return new PostmanScenarioParser();
|
return new PostmanScenarioParser();
|
||||||
} else if (StringUtils.equals(ApiImportPlatform.Jmeter.name(), platform)) {
|
} else if (StringUtils.equals(ApiImportPlatform.Jmeter.name(), platform)) {
|
||||||
return new MsJmeterParser();
|
return new MsJmeterParser();
|
||||||
|
} else if (StringUtils.equals(ApiImportPlatform.Har.name(), platform)) {
|
||||||
|
return new HarScenarioParser();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ public class ApiDefinitionImportParserFactory {
|
||||||
return new PostmanDefinitionParser();
|
return new PostmanDefinitionParser();
|
||||||
} else if (StringUtils.equals(ApiImportPlatform.Swagger2.name(), platform)) {
|
} else if (StringUtils.equals(ApiImportPlatform.Swagger2.name(), platform)) {
|
||||||
return new Swagger2Parser();
|
return new Swagger2Parser();
|
||||||
|
}else if (StringUtils.equals(ApiImportPlatform.Har.name(), platform)) {
|
||||||
|
return new HarParser();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package io.metersphere.api.dto.definition.parse;
|
||||||
|
|
||||||
|
|
||||||
|
import io.metersphere.api.parse.ApiImportAbstractParser;
|
||||||
|
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||||
|
import io.metersphere.base.domain.ApiModule;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author song.tianyang
|
||||||
|
* @Date 2021/3/10 11:15 上午
|
||||||
|
* @Description
|
||||||
|
*/
|
||||||
|
public abstract class HarAbstractParser extends ApiImportAbstractParser<ApiDefinitionImport> {
|
||||||
|
|
||||||
|
protected void buildModule(ApiModule parentModule, ApiDefinitionWithBLOBs apiDefinition, List<String> tags) {
|
||||||
|
if (tags != null) {
|
||||||
|
tags.forEach(tag -> {
|
||||||
|
ApiModule module = ApiDefinitionImportUtil.buildModule(parentModule, tag, this.projectId);
|
||||||
|
apiDefinition.setModuleId(module.getId());
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
apiDefinition.setModuleId(parentModule.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,218 @@
|
||||||
|
package io.metersphere.api.dto.definition.parse;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||||
|
import io.metersphere.api.dto.definition.parse.har.HarUtils;
|
||||||
|
import io.metersphere.api.dto.definition.parse.har.model.*;
|
||||||
|
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.base.domain.ApiDefinitionWithBLOBs;
|
||||||
|
import io.metersphere.base.domain.ApiModule;
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.commons.utils.XMLUtils;
|
||||||
|
import io.swagger.models.Model;
|
||||||
|
import io.swagger.v3.oas.models.media.Schema;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author song.tianyang
|
||||||
|
* @Date 2021/3/10 11:14 上午
|
||||||
|
* @Description
|
||||||
|
*/
|
||||||
|
public class HarParser extends HarAbstractParser {
|
||||||
|
|
||||||
|
private Map<String, Model> definitions = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
||||||
|
Har har = null;
|
||||||
|
try {
|
||||||
|
String sourceStr = getApiTestStr(source);
|
||||||
|
har = HarUtils.read(sourceStr);
|
||||||
|
} catch (Exception e) {
|
||||||
|
MSException.throwException(e.getMessage());
|
||||||
|
LogUtil.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjectUtils.isEmpty(har)) {
|
||||||
|
MSException.throwException("解析失败,请确认选择的是 Har 格式!");
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiDefinitionImport definitionImport = new ApiDefinitionImport();
|
||||||
|
this.projectId = request.getProjectId();
|
||||||
|
definitionImport.setData(parseRequests(har, request));
|
||||||
|
return definitionImport;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List<ApiDefinitionWithBLOBs> parseRequests(Har har, ApiTestImportRequest importRequest) {
|
||||||
|
List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
|
||||||
|
|
||||||
|
ApiModule parentNode = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId());
|
||||||
|
|
||||||
|
List<HarEntry> harEntryList = new ArrayList<>();
|
||||||
|
if (har.log != null && har.log.entries != null) {
|
||||||
|
harEntryList = har.log.entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (HarEntry entry : harEntryList) {
|
||||||
|
HarRequest harRequest = entry.request;
|
||||||
|
|
||||||
|
//默认取路径的最后一块
|
||||||
|
String reqName = "";
|
||||||
|
if (harRequest.url != null) {
|
||||||
|
String[] nameArr = harRequest.url.split("/");
|
||||||
|
reqName = nameArr[nameArr.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (harRequest != null) {
|
||||||
|
MsHTTPSamplerProxy request = super.buildRequest(reqName, harRequest.url, harRequest.method);
|
||||||
|
ApiDefinitionWithBLOBs apiDefinition = super.buildApiDefinition(request.getId(), reqName, harRequest.url, harRequest.method, importRequest);
|
||||||
|
parseParameters(harRequest, request);
|
||||||
|
parseRequestBody(harRequest, request.getBody());
|
||||||
|
addBodyHeader(request);
|
||||||
|
apiDefinition.setRequest(JSON.toJSONString(request));
|
||||||
|
apiDefinition.setResponse(JSON.toJSONString(parseResponse(entry.response)));
|
||||||
|
buildModule(parentNode, apiDefinition, null);
|
||||||
|
results.add(apiDefinition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseParameters(HarRequest harRequest, MsHTTPSamplerProxy request) {
|
||||||
|
List<HarQueryParm> queryStringList = harRequest.queryString;
|
||||||
|
queryStringList.forEach(harQueryParm -> {
|
||||||
|
parseQueryParameters(harQueryParm, request.getArguments());
|
||||||
|
});
|
||||||
|
List<HarHeader> harHeaderList = harRequest.headers;
|
||||||
|
harHeaderList.forEach(harHeader -> {
|
||||||
|
parseHeaderParameters(harHeader, request.getHeaders());
|
||||||
|
});
|
||||||
|
List<HarCookie> harCookieList = harRequest.cookies;
|
||||||
|
harCookieList.forEach(harCookie -> {
|
||||||
|
parseCookieParameters(harCookie, request.getHeaders());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String getDefaultStringValue(String val) {
|
||||||
|
return StringUtils.isBlank(val) ? "" : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseCookieParameters(HarCookie harCookie, List<KeyValue> headers) {
|
||||||
|
addCookie(headers, harCookie.name, harCookie.value, harCookie.comment, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseHeaderParameters(HarHeader harHeader, List<KeyValue> headers) {
|
||||||
|
addHeader(headers, harHeader.name, harHeader.value,harHeader.comment, "", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpResponse parseResponse(HarResponse response) {
|
||||||
|
HttpResponse msResponse = new HttpResponse();
|
||||||
|
msResponse.setBody(new Body());
|
||||||
|
msResponse.setHeaders(new ArrayList<>());
|
||||||
|
msResponse.setType(RequestType.HTTP);
|
||||||
|
// todo 状态码要调整?
|
||||||
|
msResponse.setStatusCode(new ArrayList<>());
|
||||||
|
if (response != null) {
|
||||||
|
String responseCode = String.valueOf(response.status);
|
||||||
|
msResponse.getStatusCode().add(new KeyValue(responseCode, responseCode));
|
||||||
|
parseResponseHeader(response, msResponse.getHeaders());
|
||||||
|
parseResponseBody(response, msResponse.getBody());
|
||||||
|
}
|
||||||
|
return msResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseResponseHeader(HarResponse response, List<KeyValue> msHeaders) {
|
||||||
|
List<HarHeader> harHeaders = response.headers;
|
||||||
|
if (harHeaders != null) {
|
||||||
|
for (HarHeader header : harHeaders) {
|
||||||
|
msHeaders.add(new KeyValue(header.name, header.value, header.comment));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseResponseBody(HarResponse response, Body body) {
|
||||||
|
parseResponseBody(response.content, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseRequestBody(HarRequest requestBody, Body body) {
|
||||||
|
if (requestBody == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HarPostData content = requestBody.postData;
|
||||||
|
if (!StringUtils.equalsIgnoreCase("GET", requestBody.method) || requestBody.postData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String contentType = content.mimeType;
|
||||||
|
if (StringUtils.isEmpty(contentType)) {
|
||||||
|
body.setRaw(content.text);
|
||||||
|
} else {
|
||||||
|
Map<String, Schema> infoMap = new HashMap();
|
||||||
|
|
||||||
|
if (contentType.startsWith(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
|
||||||
|
contentType = org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
|
||||||
|
List<HarPostParam> postParams = content.params;
|
||||||
|
for (HarPostParam postParam : postParams) {
|
||||||
|
KeyValue kv = new KeyValue(postParam.name,postParam.value);
|
||||||
|
body.getKvs().add(kv);
|
||||||
|
}
|
||||||
|
} else if (contentType.startsWith(org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE)) {
|
||||||
|
contentType = org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE;
|
||||||
|
List<HarPostParam> postParams = content.params;
|
||||||
|
for (HarPostParam postParam : postParams) {
|
||||||
|
KeyValue kv = new KeyValue(postParam.name,postParam.value);
|
||||||
|
body.getKvs().add(kv);
|
||||||
|
}
|
||||||
|
} else if (contentType.startsWith(org.springframework.http.MediaType.APPLICATION_JSON_VALUE)) {
|
||||||
|
contentType = org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||||
|
body.setRaw(content.text);
|
||||||
|
} else if (contentType.startsWith(org.springframework.http.MediaType.APPLICATION_XML_VALUE)) {
|
||||||
|
contentType = org.springframework.http.MediaType.APPLICATION_XML_VALUE;
|
||||||
|
body.setRaw(parseXmlBody(content.text));
|
||||||
|
} else if (contentType.startsWith(org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE)) {
|
||||||
|
contentType = org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE;
|
||||||
|
List<HarPostParam> postParams = content.params;
|
||||||
|
for (HarPostParam postParam : postParams) {
|
||||||
|
KeyValue kv = new KeyValue(postParam.name,postParam.value);
|
||||||
|
body.getKvs().add(kv);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
body.setRaw(content.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body.setType(getBodyType(contentType));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseResponseBody(HarContent content, Body body) {
|
||||||
|
if (content == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String contentType = content.mimeType;
|
||||||
|
body.setType(getBodyType(contentType));
|
||||||
|
body.setRaw(content.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseXmlBody(String xmlString) {
|
||||||
|
JSONObject object = JSONObject.parseObject(getDefaultStringValue(xmlString));
|
||||||
|
return XMLUtils.jsonToXmlStr(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseQueryParameters(HarQueryParm harQueryParm, List<KeyValue> arguments) {
|
||||||
|
arguments.add(new KeyValue(harQueryParm.name, harQueryParm.value, harQueryParm.comment, false));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
import io.metersphere.api.dto.definition.parse.har.model.Har;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for working with HAR files.
|
||||||
|
*
|
||||||
|
* @author sangupta
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class HarUtils {
|
||||||
|
|
||||||
|
public static Har read(File file) throws JsonSyntaxException, IOException {
|
||||||
|
Har har = JSONObject.parseObject(FileUtils.readFileToString(file), Har.class);
|
||||||
|
return har;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Har read(String harJson) throws JsonSyntaxException, IOException {
|
||||||
|
if(StringUtils.isEmpty(harJson)) {
|
||||||
|
throw new IllegalArgumentException("HAR Json cannot be null/empty");
|
||||||
|
}
|
||||||
|
Har har = JSONObject.parseObject(harJson, Har.class);
|
||||||
|
return har;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
///**
|
||||||
|
// *
|
||||||
|
// * har - HAR file reader, writer and viewer
|
||||||
|
// * Copyright (c) 2014, Sandeep Gupta
|
||||||
|
// *
|
||||||
|
// * http://sangupta.com/projects/har
|
||||||
|
// *
|
||||||
|
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// * you may not use this file except in compliance with the License.
|
||||||
|
// * You may obtain a copy of the License at
|
||||||
|
// *
|
||||||
|
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// *
|
||||||
|
// * Unless required by applicable law or agreed to in writing, software
|
||||||
|
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// * See the License for the specific language governing permissions and
|
||||||
|
// * limitations under the License.
|
||||||
|
// *
|
||||||
|
// */
|
||||||
|
//
|
||||||
|
//package io.metersphere.api.dto.definition.parse.har.command;
|
||||||
|
//
|
||||||
|
//import java.io.File;
|
||||||
|
//
|
||||||
|
//import com.sangupta.har.HarUtils;
|
||||||
|
//import com.sangupta.har.model.Har;
|
||||||
|
//import com.sangupta.har.model.HarEntry;
|
||||||
|
//import com.sangupta.har.model.HarPage;
|
||||||
|
//import com.sangupta.jerry.util.AssertUtils;
|
||||||
|
//
|
||||||
|
//import io.airlift.command.Arguments;
|
||||||
|
//import io.airlift.command.Command;
|
||||||
|
//
|
||||||
|
//@Command(name = "view", description = "View HAR file")
|
||||||
|
//public class ViewHar implements Runnable {
|
||||||
|
//
|
||||||
|
// @Arguments
|
||||||
|
// private String file;
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void run() {
|
||||||
|
// Har har = null;
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// har = HarUtils.read(new File(this.file));
|
||||||
|
// } catch(Exception e) {
|
||||||
|
// System.out.println("Error reading HAR file: " + e.getMessage());
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(har.log == null || AssertUtils.isEmpty(har.log.pages)) {
|
||||||
|
// System.out.println("HAR file has no pages!");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // connect references
|
||||||
|
// HarUtils.connectReferences(har);
|
||||||
|
//
|
||||||
|
// // start displaying
|
||||||
|
// System.out.println("Number of pages viewed: " + har.log.pages.size());
|
||||||
|
// System.out.println();
|
||||||
|
//
|
||||||
|
// for(HarPage page : har.log.pages) {
|
||||||
|
// System.out.println(page);
|
||||||
|
//
|
||||||
|
// // output the calls for this page
|
||||||
|
// for(HarEntry entry : page.entries) {
|
||||||
|
// System.out.println("\t" + entry);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class Har {
|
||||||
|
|
||||||
|
public HarLog log;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Har [log=" + log + "]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class HarCache {
|
||||||
|
|
||||||
|
public HarCacheDetails beforeRequest;
|
||||||
|
|
||||||
|
public HarCacheDetails afterRequest;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class HarCacheDetails {
|
||||||
|
|
||||||
|
public String expires;
|
||||||
|
|
||||||
|
public String lastAccess;
|
||||||
|
|
||||||
|
public String etag;
|
||||||
|
|
||||||
|
public String hitCount;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class HarContent {
|
||||||
|
|
||||||
|
public long size;
|
||||||
|
|
||||||
|
public String mimeType;
|
||||||
|
|
||||||
|
public long compression;
|
||||||
|
|
||||||
|
public String text;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
public String encoding;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class HarCookie {
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public String value;
|
||||||
|
|
||||||
|
public String path;
|
||||||
|
|
||||||
|
public String expires;
|
||||||
|
|
||||||
|
public boolean httpOnly;
|
||||||
|
|
||||||
|
public boolean secure;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[Cookie: " + this.name + "=" + this.value + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if(this.name == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.name.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if(!(obj instanceof HarCookie)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.name == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HarCookie harCookie = (HarCookie) obj;
|
||||||
|
return this.name.equals(harCookie.name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class HarCreator {
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public String version;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HarCreator [name=" + name + ", version=" + version + ", comment=" + comment + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class HarEntry implements Comparable<HarEntry> {
|
||||||
|
|
||||||
|
public String pageref;
|
||||||
|
|
||||||
|
public String startedDateTime;
|
||||||
|
|
||||||
|
public double time;
|
||||||
|
|
||||||
|
public HarRequest request;
|
||||||
|
|
||||||
|
public HarResponse response;
|
||||||
|
|
||||||
|
public HarCache cache;
|
||||||
|
|
||||||
|
public HarTiming timings;
|
||||||
|
|
||||||
|
public String serverIPAddress;
|
||||||
|
|
||||||
|
public String connection;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HarEntry [pageref=" + pageref + ", startedDateTime=" + startedDateTime + ", time=" + time + ", request="
|
||||||
|
+ request + ", response=" + response + ", cache=" + cache + ", timings=" + timings
|
||||||
|
+ ", serverIPAddress=" + serverIPAddress + ", connection=" + connection + ", comment=" + comment + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(HarEntry o) {
|
||||||
|
if(o == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// parse the time and then return
|
||||||
|
return this.startedDateTime.compareTo(o.startedDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class HarHeader {
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public String value;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[Header: " + this.name + "=" + this.value + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if(this.name == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.name.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if(!(obj instanceof HarHeader)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.name == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HarHeader harHeader = (HarHeader) obj;
|
||||||
|
return this.name.equals(harHeader.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HarLog {
|
||||||
|
|
||||||
|
public static final String DEFAULT_HAR_VERSION = "1.2";
|
||||||
|
|
||||||
|
public String version = DEFAULT_HAR_VERSION;
|
||||||
|
|
||||||
|
public HarCreator creator;
|
||||||
|
|
||||||
|
public HarCreator browser;
|
||||||
|
|
||||||
|
public List<HarPage> pages;
|
||||||
|
|
||||||
|
public List<HarEntry> entries;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HarLog [version=" + version + ", creator=" + creator + ", browser=" + browser + ", pages=" + pages
|
||||||
|
+ ", entries=" + entries + ", comment=" + comment + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HarPage {
|
||||||
|
|
||||||
|
public String startedDateTime;
|
||||||
|
|
||||||
|
public String id;
|
||||||
|
|
||||||
|
public String title;
|
||||||
|
|
||||||
|
public HarPageTiming pageTimings;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
public transient List<HarEntry> entries;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HarPage [startedDateTime=" + startedDateTime + ", id=" + id + ", title=" + title + ", pageTimings="
|
||||||
|
+ pageTimings + ", comment=" + comment + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if(this.id == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.id.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if(!(obj instanceof HarPage)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.id == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HarPage harPage = (HarPage) obj;
|
||||||
|
return this.id.equals(harPage.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class HarPageTiming {
|
||||||
|
|
||||||
|
public double onContentLoad;
|
||||||
|
|
||||||
|
public double onLoad;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HarPageTiming [onContentLoad=" + onContentLoad + ", onLoad=" + onLoad + ", comment=" + comment + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HarPostData {
|
||||||
|
|
||||||
|
public String mimeType;
|
||||||
|
|
||||||
|
public List<HarPostParam> params;
|
||||||
|
|
||||||
|
public String text;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class HarPostParam {
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public String value;
|
||||||
|
|
||||||
|
public String fileName;
|
||||||
|
|
||||||
|
public String contentType;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[Post Param: " + this.name + "=" + this.value + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if(this.name == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.name.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if(!(obj instanceof HarPostParam)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.name == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HarPostParam harPostParam = (HarPostParam) obj;
|
||||||
|
return this.name.equals(harPostParam.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class HarQueryParm {
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public String value;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[Query Param: " + this.name + "=" + this.value + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if(this.name == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.name.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if(!(obj instanceof HarQueryParm)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.name == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HarQueryParm harQueryParm = (HarQueryParm) obj;
|
||||||
|
return this.name.equals(harQueryParm.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HarRequest {
|
||||||
|
|
||||||
|
public String method;
|
||||||
|
|
||||||
|
public String url;
|
||||||
|
|
||||||
|
public String httpVersion;
|
||||||
|
|
||||||
|
public List<HarCookie> cookies;
|
||||||
|
|
||||||
|
public List<HarHeader> headers;
|
||||||
|
|
||||||
|
public List<HarQueryParm> queryString;
|
||||||
|
|
||||||
|
public HarPostData postData;
|
||||||
|
|
||||||
|
public long headersSize;
|
||||||
|
|
||||||
|
public long bodySize;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.method + " " + this.url + " " + this.httpVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HarResponse {
|
||||||
|
|
||||||
|
public int status;
|
||||||
|
|
||||||
|
public String statusText;
|
||||||
|
|
||||||
|
public String httpVersion;
|
||||||
|
|
||||||
|
public List<HarHeader> headers;
|
||||||
|
|
||||||
|
public List<HarCookie> cookies;
|
||||||
|
|
||||||
|
public HarContent content;
|
||||||
|
|
||||||
|
public String redirectURL;
|
||||||
|
|
||||||
|
public long headersSize;
|
||||||
|
|
||||||
|
public long bodySize;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HTTP " + this.status + " (" + this.statusText + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* har - HAR file reader, writer and viewer
|
||||||
|
* Copyright (c) 2014, Sandeep Gupta
|
||||||
|
*
|
||||||
|
* http://sangupta.com/projects/har
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.metersphere.api.dto.definition.parse.har.model;
|
||||||
|
|
||||||
|
public class HarTiming {
|
||||||
|
|
||||||
|
public double blocked;
|
||||||
|
|
||||||
|
public double dns;
|
||||||
|
|
||||||
|
public double connect;
|
||||||
|
|
||||||
|
public double send;
|
||||||
|
|
||||||
|
public double wait;
|
||||||
|
|
||||||
|
public double receive;
|
||||||
|
|
||||||
|
public double ssl;
|
||||||
|
|
||||||
|
public String comment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HarTiming [blocked=" + blocked + ", dns=" + dns + ", connect=" + connect + ", send=" + send + ", wait="
|
||||||
|
+ wait + ", receive=" + receive + ", ssl=" + ssl + ", comment=" + comment + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -85,8 +85,8 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
||||||
@JSONField(ordinal = 34)
|
@JSONField(ordinal = 34)
|
||||||
private List<KeyValue> arguments;
|
private List<KeyValue> arguments;
|
||||||
|
|
||||||
// @JSONField(ordinal = 35)
|
@JSONField(ordinal = 35)
|
||||||
// private Object requestResult;
|
private Object requestResult;
|
||||||
|
|
||||||
@JSONField(ordinal = 36)
|
@JSONField(ordinal = 36)
|
||||||
private MsAuthManager authManager;
|
private MsAuthManager authManager;
|
||||||
|
|
|
@ -0,0 +1,217 @@
|
||||||
|
package io.metersphere.api.parse;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.metersphere.api.dto.definition.parse.har.model.*;
|
||||||
|
import io.metersphere.api.dto.definition.request.MsTestElement;
|
||||||
|
import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor;
|
||||||
|
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||||
|
import io.metersphere.api.dto.parse.postman.PostmanEvent;
|
||||||
|
import io.metersphere.api.dto.parse.postman.PostmanKeyValue;
|
||||||
|
import io.metersphere.api.dto.parse.postman.PostmanRequest;
|
||||||
|
import io.metersphere.api.dto.parse.postman.PostmanScript;
|
||||||
|
import io.metersphere.api.dto.scenario.Body;
|
||||||
|
import io.metersphere.api.dto.scenario.KeyValue;
|
||||||
|
import io.metersphere.commons.constants.MsRequestBodyType;
|
||||||
|
import io.metersphere.commons.constants.PostmanRequestBodyMode;
|
||||||
|
import io.metersphere.commons.utils.XMLUtils;
|
||||||
|
import io.swagger.v3.oas.models.media.Schema;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public abstract class HarScenarioAbstractParser<T> extends ApiImportAbstractParser<T> {
|
||||||
|
|
||||||
|
protected MsHTTPSamplerProxy parseHar(HarEntry harEntry) {
|
||||||
|
HarRequest harRequest = harEntry.request;
|
||||||
|
if (harRequest == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
MsHTTPSamplerProxy request = buildRequest(harRequest.url, harRequest.url,harRequest.method);
|
||||||
|
if (StringUtils.isNotBlank(request.getPath())) {
|
||||||
|
String path = request.getPath().split("\\?")[0];
|
||||||
|
path = path.replace("{{", "${");
|
||||||
|
path = path.replace("}}", "}");
|
||||||
|
request.setPath(path);
|
||||||
|
} else {
|
||||||
|
request.setPath("/");
|
||||||
|
}
|
||||||
|
parseParameters(harRequest, request);
|
||||||
|
parseRequestBody(harRequest, request.getBody());
|
||||||
|
addBodyHeader(request);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseParameters(HarRequest harRequest, MsHTTPSamplerProxy request) {
|
||||||
|
List<HarQueryParm> queryStringList = harRequest.queryString;
|
||||||
|
queryStringList.forEach(harQueryParm -> {
|
||||||
|
parseQueryParameters(harQueryParm, request.getArguments());
|
||||||
|
});
|
||||||
|
List<HarHeader> harHeaderList = harRequest.headers;
|
||||||
|
harHeaderList.forEach(harHeader -> {
|
||||||
|
parseHeaderParameters(harHeader, request.getHeaders());
|
||||||
|
});
|
||||||
|
List<HarCookie> harCookieList = harRequest.cookies;
|
||||||
|
harCookieList.forEach(harCookie -> {
|
||||||
|
parseCookieParameters(harCookie, request.getHeaders());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void parseRequestBody(HarRequest requestBody, Body body) {
|
||||||
|
if (requestBody == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HarPostData content = requestBody.postData;
|
||||||
|
if (!StringUtils.equalsIgnoreCase("GET", requestBody.method) || requestBody.postData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String contentType = content.mimeType;
|
||||||
|
if (StringUtils.isEmpty(contentType)) {
|
||||||
|
body.setRaw(content.text);
|
||||||
|
} else {
|
||||||
|
Map<String, Schema> infoMap = new HashMap();
|
||||||
|
|
||||||
|
if (contentType.startsWith(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
|
||||||
|
contentType = org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
|
||||||
|
List<HarPostParam> postParams = content.params;
|
||||||
|
for (HarPostParam postParam : postParams) {
|
||||||
|
KeyValue kv = new KeyValue(postParam.name,postParam.value);
|
||||||
|
body.getKvs().add(kv);
|
||||||
|
}
|
||||||
|
} else if (contentType.startsWith(org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE)) {
|
||||||
|
contentType = org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE;
|
||||||
|
List<HarPostParam> postParams = content.params;
|
||||||
|
for (HarPostParam postParam : postParams) {
|
||||||
|
KeyValue kv = new KeyValue(postParam.name,postParam.value);
|
||||||
|
body.getKvs().add(kv);
|
||||||
|
}
|
||||||
|
} else if (contentType.startsWith(org.springframework.http.MediaType.APPLICATION_JSON_VALUE)) {
|
||||||
|
contentType = org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||||
|
body.setRaw(content.text);
|
||||||
|
} else if (contentType.startsWith(org.springframework.http.MediaType.APPLICATION_XML_VALUE)) {
|
||||||
|
contentType = org.springframework.http.MediaType.APPLICATION_XML_VALUE;
|
||||||
|
body.setRaw(parseXmlBody(content.text));
|
||||||
|
} else if (contentType.startsWith(org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE)) {
|
||||||
|
contentType = org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE;
|
||||||
|
List<HarPostParam> postParams = content.params;
|
||||||
|
for (HarPostParam postParam : postParams) {
|
||||||
|
KeyValue kv = new KeyValue(postParam.name,postParam.value);
|
||||||
|
body.getKvs().add(kv);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
body.setRaw(content.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body.setType(getBodyType(contentType));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void parseQueryParameters(HarQueryParm harQueryParm, List<KeyValue> arguments) {
|
||||||
|
arguments.add(new KeyValue(harQueryParm.name, harQueryParm.value, harQueryParm.comment, false));
|
||||||
|
}
|
||||||
|
private void parseCookieParameters(HarCookie harCookie, List<KeyValue> headers) {
|
||||||
|
addCookie(headers, harCookie.name, harCookie.value, harCookie.comment, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseHeaderParameters(HarHeader harHeader, List<KeyValue> headers) {
|
||||||
|
addHeader(headers, harHeader.name, harHeader.value,harHeader.comment, "", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPreScript(MsHTTPSamplerProxy request, List<PostmanEvent> event) {
|
||||||
|
if (request != null && CollectionUtils.isNotEmpty(event)) {
|
||||||
|
StringBuilder scriptStr = new StringBuilder();
|
||||||
|
event = event.stream()
|
||||||
|
.filter(item -> item.getScript() != null)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
event.forEach(item -> {
|
||||||
|
PostmanScript script = item.getScript();
|
||||||
|
if (script != null && item.getListen().contains("prerequest")) {
|
||||||
|
List<String> exec = script.getExec();
|
||||||
|
if (CollectionUtils.isNotEmpty(exec)) {
|
||||||
|
exec.forEach(col -> {
|
||||||
|
if (StringUtils.isNotEmpty(col)) {
|
||||||
|
scriptStr.append(col + "\n");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (StringUtils.isNotBlank(scriptStr)) {
|
||||||
|
MsJSR223PreProcessor jsr223PreProcessor = new MsJSR223PreProcessor();
|
||||||
|
jsr223PreProcessor.setName("JSR223PreProcessor");
|
||||||
|
jsr223PreProcessor.setScriptLanguage("javascript");
|
||||||
|
jsr223PreProcessor.setScript(scriptStr.toString());
|
||||||
|
LinkedList<MsTestElement> hashTree = new LinkedList<>();
|
||||||
|
hashTree.add(jsr223PreProcessor);
|
||||||
|
request.setHashTree(hashTree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<KeyValue> parseKeyValue(List<PostmanKeyValue> postmanKeyValues) {
|
||||||
|
if (postmanKeyValues == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<KeyValue> keyValues = new ArrayList<>();
|
||||||
|
postmanKeyValues.forEach(item -> keyValues.add(new KeyValue(item.getKey(), item.getValue(), item.getDescription(), item.getContentType())));
|
||||||
|
return keyValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseBody(Body body, PostmanRequest requestDesc) {
|
||||||
|
JSONObject postmanBody = requestDesc.getBody();
|
||||||
|
if (postmanBody == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String bodyMode = postmanBody.getString("mode");
|
||||||
|
if (StringUtils.isBlank(bodyMode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) {
|
||||||
|
parseRawBody(body, postmanBody, bodyMode);
|
||||||
|
} else if (StringUtils.equalsAny(bodyMode, PostmanRequestBodyMode.FORM_DATA.value(), PostmanRequestBodyMode.URLENCODED.value())) {
|
||||||
|
List<PostmanKeyValue> postmanKeyValues = JSON.parseArray(postmanBody.getString(bodyMode), PostmanKeyValue.class);
|
||||||
|
body.setKvs(parseKeyValue(postmanKeyValues));
|
||||||
|
if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FORM_DATA.value())) {
|
||||||
|
body.setType(Body.FORM_DATA);
|
||||||
|
} else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.URLENCODED.value())) {
|
||||||
|
body.setType(Body.WWW_FROM);
|
||||||
|
}
|
||||||
|
} else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FILE.value())) {
|
||||||
|
body.setType(Body.BINARY);
|
||||||
|
body.setKvs(new ArrayList<>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseXmlBody(String xmlString) {
|
||||||
|
JSONObject object = JSONObject.parseObject(getDefaultStringValue(xmlString));
|
||||||
|
return XMLUtils.jsonToXmlStr(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseRawBody(Body body, JSONObject postmanBody, String bodyMode) {
|
||||||
|
body.setRaw(postmanBody.getString(bodyMode));
|
||||||
|
body.setType(MsRequestBodyType.RAW.value());
|
||||||
|
JSONObject options = postmanBody.getJSONObject("options");
|
||||||
|
if (options != null) {
|
||||||
|
JSONObject raw = options.getJSONObject(PostmanRequestBodyMode.RAW.value());
|
||||||
|
if (raw != null) {
|
||||||
|
String bodyType = "";
|
||||||
|
switch (raw.getString("language")) {
|
||||||
|
case "json":
|
||||||
|
bodyType = Body.JSON;
|
||||||
|
break;
|
||||||
|
case "xml":
|
||||||
|
bodyType = Body.XML;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bodyType = Body.RAW;
|
||||||
|
}
|
||||||
|
body.setType(bodyType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDefaultStringValue(String val) {
|
||||||
|
return StringUtils.isBlank(val) ? "" : val;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
package io.metersphere.base.domain;
|
package io.metersphere.base.domain;
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class ApiDefinition implements Serializable {
|
public class ApiDefinition implements Serializable {
|
||||||
|
@ -38,5 +37,7 @@ public class ApiDefinition implements Serializable {
|
||||||
|
|
||||||
private String tags;
|
private String tags;
|
||||||
|
|
||||||
|
private String originalState;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
}
|
}
|
|
@ -1193,6 +1193,76 @@ public class ApiDefinitionExample {
|
||||||
addCriterion("tags not between", value1, value2, "tags");
|
addCriterion("tags not between", value1, value2, "tags");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateIsNull() {
|
||||||
|
addCriterion("original_state is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateIsNotNull() {
|
||||||
|
addCriterion("original_state is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateEqualTo(String value) {
|
||||||
|
addCriterion("original_state =", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateNotEqualTo(String value) {
|
||||||
|
addCriterion("original_state <>", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateGreaterThan(String value) {
|
||||||
|
addCriterion("original_state >", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("original_state >=", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateLessThan(String value) {
|
||||||
|
addCriterion("original_state <", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("original_state <=", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateLike(String value) {
|
||||||
|
addCriterion("original_state like", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateNotLike(String value) {
|
||||||
|
addCriterion("original_state not like", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateIn(List<String> values) {
|
||||||
|
addCriterion("original_state in", values, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateNotIn(List<String> values) {
|
||||||
|
addCriterion("original_state not in", values, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateBetween(String value1, String value2) {
|
||||||
|
addCriterion("original_state between", value1, value2, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("original_state not between", value1, value2, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Criteria extends GeneratedCriteria {
|
public static class Criteria extends GeneratedCriteria {
|
||||||
|
|
|
@ -43,5 +43,7 @@ public class ApiScenario implements Serializable {
|
||||||
|
|
||||||
private Integer num;
|
private Integer num;
|
||||||
|
|
||||||
|
private String originalState;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
}
|
}
|
|
@ -1393,6 +1393,76 @@ public class ApiScenarioExample {
|
||||||
addCriterion("num not between", value1, value2, "num");
|
addCriterion("num not between", value1, value2, "num");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateIsNull() {
|
||||||
|
addCriterion("original_state is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateIsNotNull() {
|
||||||
|
addCriterion("original_state is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateEqualTo(String value) {
|
||||||
|
addCriterion("original_state =", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateNotEqualTo(String value) {
|
||||||
|
addCriterion("original_state <>", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateGreaterThan(String value) {
|
||||||
|
addCriterion("original_state >", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("original_state >=", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateLessThan(String value) {
|
||||||
|
addCriterion("original_state <", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("original_state <=", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateLike(String value) {
|
||||||
|
addCriterion("original_state like", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateNotLike(String value) {
|
||||||
|
addCriterion("original_state not like", value, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateIn(List<String> values) {
|
||||||
|
addCriterion("original_state in", values, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateNotIn(List<String> values) {
|
||||||
|
addCriterion("original_state not in", values, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateBetween(String value1, String value2) {
|
||||||
|
addCriterion("original_state between", value1, value2, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andOriginalStateNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("original_state not between", value1, value2, "originalState");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Criteria extends GeneratedCriteria {
|
public static class Criteria extends GeneratedCriteria {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
<result column="path" jdbcType="VARCHAR" property="path" />
|
<result column="path" jdbcType="VARCHAR" property="path" />
|
||||||
<result column="num" jdbcType="INTEGER" property="num" />
|
<result column="num" jdbcType="INTEGER" property="num" />
|
||||||
<result column="tags" jdbcType="VARCHAR" property="tags" />
|
<result column="tags" jdbcType="VARCHAR" property="tags" />
|
||||||
|
<result column="original_state" jdbcType="VARCHAR" property="originalState" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.ApiDefinitionWithBLOBs">
|
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.ApiDefinitionWithBLOBs">
|
||||||
<result column="description" jdbcType="LONGVARCHAR" property="description" />
|
<result column="description" jdbcType="LONGVARCHAR" property="description" />
|
||||||
|
@ -84,7 +85,7 @@
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, project_id, `name`, `method`, module_path, environment_id, schedule, `status`,
|
id, project_id, `name`, `method`, module_path, environment_id, schedule, `status`,
|
||||||
module_id, user_id, create_time, update_time, protocol, `path`, num, tags
|
module_id, user_id, create_time, update_time, protocol, `path`, num, tags, original_state
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Blob_Column_List">
|
<sql id="Blob_Column_List">
|
||||||
description, request, response
|
description, request, response
|
||||||
|
@ -143,15 +144,15 @@
|
||||||
schedule, `status`, module_id,
|
schedule, `status`, module_id,
|
||||||
user_id, create_time, update_time,
|
user_id, create_time, update_time,
|
||||||
protocol, `path`, num,
|
protocol, `path`, num,
|
||||||
tags, description, request,
|
tags, original_state, description,
|
||||||
response)
|
request, response)
|
||||||
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
|
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
|
||||||
#{method,jdbcType=VARCHAR}, #{modulePath,jdbcType=VARCHAR}, #{environmentId,jdbcType=VARCHAR},
|
#{method,jdbcType=VARCHAR}, #{modulePath,jdbcType=VARCHAR}, #{environmentId,jdbcType=VARCHAR},
|
||||||
#{schedule,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, #{moduleId,jdbcType=VARCHAR},
|
#{schedule,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, #{moduleId,jdbcType=VARCHAR},
|
||||||
#{userId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
#{userId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
||||||
#{protocol,jdbcType=VARCHAR}, #{path,jdbcType=VARCHAR}, #{num,jdbcType=INTEGER},
|
#{protocol,jdbcType=VARCHAR}, #{path,jdbcType=VARCHAR}, #{num,jdbcType=INTEGER},
|
||||||
#{tags,jdbcType=VARCHAR}, #{description,jdbcType=LONGVARCHAR}, #{request,jdbcType=LONGVARCHAR},
|
#{tags,jdbcType=VARCHAR}, #{originalState,jdbcType=VARCHAR}, #{description,jdbcType=LONGVARCHAR},
|
||||||
#{response,jdbcType=LONGVARCHAR})
|
#{request,jdbcType=LONGVARCHAR}, #{response,jdbcType=LONGVARCHAR})
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiDefinitionWithBLOBs">
|
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiDefinitionWithBLOBs">
|
||||||
insert into api_definition
|
insert into api_definition
|
||||||
|
@ -204,6 +205,9 @@
|
||||||
<if test="tags != null">
|
<if test="tags != null">
|
||||||
tags,
|
tags,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="originalState != null">
|
||||||
|
original_state,
|
||||||
|
</if>
|
||||||
<if test="description != null">
|
<if test="description != null">
|
||||||
description,
|
description,
|
||||||
</if>
|
</if>
|
||||||
|
@ -263,6 +267,9 @@
|
||||||
<if test="tags != null">
|
<if test="tags != null">
|
||||||
#{tags,jdbcType=VARCHAR},
|
#{tags,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="originalState != null">
|
||||||
|
#{originalState,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="description != null">
|
<if test="description != null">
|
||||||
#{description,jdbcType=LONGVARCHAR},
|
#{description,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
@ -331,6 +338,9 @@
|
||||||
<if test="record.tags != null">
|
<if test="record.tags != null">
|
||||||
tags = #{record.tags,jdbcType=VARCHAR},
|
tags = #{record.tags,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="record.originalState != null">
|
||||||
|
original_state = #{record.originalState,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="record.description != null">
|
<if test="record.description != null">
|
||||||
description = #{record.description,jdbcType=LONGVARCHAR},
|
description = #{record.description,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
@ -363,6 +373,7 @@
|
||||||
`path` = #{record.path,jdbcType=VARCHAR},
|
`path` = #{record.path,jdbcType=VARCHAR},
|
||||||
num = #{record.num,jdbcType=INTEGER},
|
num = #{record.num,jdbcType=INTEGER},
|
||||||
tags = #{record.tags,jdbcType=VARCHAR},
|
tags = #{record.tags,jdbcType=VARCHAR},
|
||||||
|
original_state = #{record.originalState,jdbcType=VARCHAR},
|
||||||
description = #{record.description,jdbcType=LONGVARCHAR},
|
description = #{record.description,jdbcType=LONGVARCHAR},
|
||||||
request = #{record.request,jdbcType=LONGVARCHAR},
|
request = #{record.request,jdbcType=LONGVARCHAR},
|
||||||
response = #{record.response,jdbcType=LONGVARCHAR}
|
response = #{record.response,jdbcType=LONGVARCHAR}
|
||||||
|
@ -387,7 +398,8 @@
|
||||||
protocol = #{record.protocol,jdbcType=VARCHAR},
|
protocol = #{record.protocol,jdbcType=VARCHAR},
|
||||||
`path` = #{record.path,jdbcType=VARCHAR},
|
`path` = #{record.path,jdbcType=VARCHAR},
|
||||||
num = #{record.num,jdbcType=INTEGER},
|
num = #{record.num,jdbcType=INTEGER},
|
||||||
tags = #{record.tags,jdbcType=VARCHAR}
|
tags = #{record.tags,jdbcType=VARCHAR},
|
||||||
|
original_state = #{record.originalState,jdbcType=VARCHAR}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
</if>
|
</if>
|
||||||
|
@ -440,6 +452,9 @@
|
||||||
<if test="tags != null">
|
<if test="tags != null">
|
||||||
tags = #{tags,jdbcType=VARCHAR},
|
tags = #{tags,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="originalState != null">
|
||||||
|
original_state = #{originalState,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="description != null">
|
<if test="description != null">
|
||||||
description = #{description,jdbcType=LONGVARCHAR},
|
description = #{description,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
@ -469,6 +484,7 @@
|
||||||
`path` = #{path,jdbcType=VARCHAR},
|
`path` = #{path,jdbcType=VARCHAR},
|
||||||
num = #{num,jdbcType=INTEGER},
|
num = #{num,jdbcType=INTEGER},
|
||||||
tags = #{tags,jdbcType=VARCHAR},
|
tags = #{tags,jdbcType=VARCHAR},
|
||||||
|
original_state = #{originalState,jdbcType=VARCHAR},
|
||||||
description = #{description,jdbcType=LONGVARCHAR},
|
description = #{description,jdbcType=LONGVARCHAR},
|
||||||
request = #{request,jdbcType=LONGVARCHAR},
|
request = #{request,jdbcType=LONGVARCHAR},
|
||||||
response = #{response,jdbcType=LONGVARCHAR}
|
response = #{response,jdbcType=LONGVARCHAR}
|
||||||
|
@ -490,7 +506,8 @@
|
||||||
protocol = #{protocol,jdbcType=VARCHAR},
|
protocol = #{protocol,jdbcType=VARCHAR},
|
||||||
`path` = #{path,jdbcType=VARCHAR},
|
`path` = #{path,jdbcType=VARCHAR},
|
||||||
num = #{num,jdbcType=INTEGER},
|
num = #{num,jdbcType=INTEGER},
|
||||||
tags = #{tags,jdbcType=VARCHAR}
|
tags = #{tags,jdbcType=VARCHAR},
|
||||||
|
original_state = #{originalState,jdbcType=VARCHAR}
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
</mapper>
|
</mapper>
|
|
@ -21,6 +21,7 @@
|
||||||
<result column="last_result" jdbcType="VARCHAR" property="lastResult" />
|
<result column="last_result" jdbcType="VARCHAR" property="lastResult" />
|
||||||
<result column="report_id" jdbcType="VARCHAR" property="reportId" />
|
<result column="report_id" jdbcType="VARCHAR" property="reportId" />
|
||||||
<result column="num" jdbcType="INTEGER" property="num" />
|
<result column="num" jdbcType="INTEGER" property="num" />
|
||||||
|
<result column="original_state" jdbcType="VARCHAR" property="originalState" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.ApiScenarioWithBLOBs">
|
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.ApiScenarioWithBLOBs">
|
||||||
<result column="scenario_definition" jdbcType="LONGVARCHAR" property="scenarioDefinition" />
|
<result column="scenario_definition" jdbcType="LONGVARCHAR" property="scenarioDefinition" />
|
||||||
|
@ -87,7 +88,7 @@
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, project_id, tags, user_id, api_scenario_module_id, module_path, `name`, `level`,
|
id, project_id, tags, user_id, api_scenario_module_id, module_path, `name`, `level`,
|
||||||
`status`, principal, step_total, follow_people, schedule, create_time, update_time,
|
`status`, principal, step_total, follow_people, schedule, create_time, update_time,
|
||||||
pass_rate, last_result, report_id, num
|
pass_rate, last_result, report_id, num, original_state
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Blob_Column_List">
|
<sql id="Blob_Column_List">
|
||||||
scenario_definition, description
|
scenario_definition, description
|
||||||
|
@ -147,16 +148,16 @@
|
||||||
principal, step_total, follow_people,
|
principal, step_total, follow_people,
|
||||||
schedule, create_time, update_time,
|
schedule, create_time, update_time,
|
||||||
pass_rate, last_result, report_id,
|
pass_rate, last_result, report_id,
|
||||||
num, scenario_definition, description
|
num, original_state, scenario_definition,
|
||||||
)
|
description)
|
||||||
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{tags,jdbcType=VARCHAR},
|
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{tags,jdbcType=VARCHAR},
|
||||||
#{userId,jdbcType=VARCHAR}, #{apiScenarioModuleId,jdbcType=VARCHAR}, #{modulePath,jdbcType=VARCHAR},
|
#{userId,jdbcType=VARCHAR}, #{apiScenarioModuleId,jdbcType=VARCHAR}, #{modulePath,jdbcType=VARCHAR},
|
||||||
#{name,jdbcType=VARCHAR}, #{level,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
|
#{name,jdbcType=VARCHAR}, #{level,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
|
||||||
#{principal,jdbcType=VARCHAR}, #{stepTotal,jdbcType=INTEGER}, #{followPeople,jdbcType=VARCHAR},
|
#{principal,jdbcType=VARCHAR}, #{stepTotal,jdbcType=INTEGER}, #{followPeople,jdbcType=VARCHAR},
|
||||||
#{schedule,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
#{schedule,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
||||||
#{passRate,jdbcType=VARCHAR}, #{lastResult,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR},
|
#{passRate,jdbcType=VARCHAR}, #{lastResult,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR},
|
||||||
#{num,jdbcType=INTEGER}, #{scenarioDefinition,jdbcType=LONGVARCHAR}, #{description,jdbcType=LONGVARCHAR}
|
#{num,jdbcType=INTEGER}, #{originalState,jdbcType=VARCHAR}, #{scenarioDefinition,jdbcType=LONGVARCHAR},
|
||||||
)
|
#{description,jdbcType=LONGVARCHAR})
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
|
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
|
||||||
insert into api_scenario
|
insert into api_scenario
|
||||||
|
@ -218,6 +219,9 @@
|
||||||
<if test="num != null">
|
<if test="num != null">
|
||||||
num,
|
num,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="originalState != null">
|
||||||
|
original_state,
|
||||||
|
</if>
|
||||||
<if test="scenarioDefinition != null">
|
<if test="scenarioDefinition != null">
|
||||||
scenario_definition,
|
scenario_definition,
|
||||||
</if>
|
</if>
|
||||||
|
@ -283,6 +287,9 @@
|
||||||
<if test="num != null">
|
<if test="num != null">
|
||||||
#{num,jdbcType=INTEGER},
|
#{num,jdbcType=INTEGER},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="originalState != null">
|
||||||
|
#{originalState,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="scenarioDefinition != null">
|
<if test="scenarioDefinition != null">
|
||||||
#{scenarioDefinition,jdbcType=LONGVARCHAR},
|
#{scenarioDefinition,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
@ -357,6 +364,9 @@
|
||||||
<if test="record.num != null">
|
<if test="record.num != null">
|
||||||
num = #{record.num,jdbcType=INTEGER},
|
num = #{record.num,jdbcType=INTEGER},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="record.originalState != null">
|
||||||
|
original_state = #{record.originalState,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="record.scenarioDefinition != null">
|
<if test="record.scenarioDefinition != null">
|
||||||
scenario_definition = #{record.scenarioDefinition,jdbcType=LONGVARCHAR},
|
scenario_definition = #{record.scenarioDefinition,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
@ -389,6 +399,7 @@
|
||||||
last_result = #{record.lastResult,jdbcType=VARCHAR},
|
last_result = #{record.lastResult,jdbcType=VARCHAR},
|
||||||
report_id = #{record.reportId,jdbcType=VARCHAR},
|
report_id = #{record.reportId,jdbcType=VARCHAR},
|
||||||
num = #{record.num,jdbcType=INTEGER},
|
num = #{record.num,jdbcType=INTEGER},
|
||||||
|
original_state = #{record.originalState,jdbcType=VARCHAR},
|
||||||
scenario_definition = #{record.scenarioDefinition,jdbcType=LONGVARCHAR},
|
scenario_definition = #{record.scenarioDefinition,jdbcType=LONGVARCHAR},
|
||||||
description = #{record.description,jdbcType=LONGVARCHAR}
|
description = #{record.description,jdbcType=LONGVARCHAR}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
|
@ -415,7 +426,8 @@
|
||||||
pass_rate = #{record.passRate,jdbcType=VARCHAR},
|
pass_rate = #{record.passRate,jdbcType=VARCHAR},
|
||||||
last_result = #{record.lastResult,jdbcType=VARCHAR},
|
last_result = #{record.lastResult,jdbcType=VARCHAR},
|
||||||
report_id = #{record.reportId,jdbcType=VARCHAR},
|
report_id = #{record.reportId,jdbcType=VARCHAR},
|
||||||
num = #{record.num,jdbcType=INTEGER}
|
num = #{record.num,jdbcType=INTEGER},
|
||||||
|
original_state = #{record.originalState,jdbcType=VARCHAR}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
</if>
|
</if>
|
||||||
|
@ -477,6 +489,9 @@
|
||||||
<if test="num != null">
|
<if test="num != null">
|
||||||
num = #{num,jdbcType=INTEGER},
|
num = #{num,jdbcType=INTEGER},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="originalState != null">
|
||||||
|
original_state = #{originalState,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="scenarioDefinition != null">
|
<if test="scenarioDefinition != null">
|
||||||
scenario_definition = #{scenarioDefinition,jdbcType=LONGVARCHAR},
|
scenario_definition = #{scenarioDefinition,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
@ -506,6 +521,7 @@
|
||||||
last_result = #{lastResult,jdbcType=VARCHAR},
|
last_result = #{lastResult,jdbcType=VARCHAR},
|
||||||
report_id = #{reportId,jdbcType=VARCHAR},
|
report_id = #{reportId,jdbcType=VARCHAR},
|
||||||
num = #{num,jdbcType=INTEGER},
|
num = #{num,jdbcType=INTEGER},
|
||||||
|
original_state = #{originalState,jdbcType=VARCHAR},
|
||||||
scenario_definition = #{scenarioDefinition,jdbcType=LONGVARCHAR},
|
scenario_definition = #{scenarioDefinition,jdbcType=LONGVARCHAR},
|
||||||
description = #{description,jdbcType=LONGVARCHAR}
|
description = #{description,jdbcType=LONGVARCHAR}
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
@ -529,7 +545,8 @@
|
||||||
pass_rate = #{passRate,jdbcType=VARCHAR},
|
pass_rate = #{passRate,jdbcType=VARCHAR},
|
||||||
last_result = #{lastResult,jdbcType=VARCHAR},
|
last_result = #{lastResult,jdbcType=VARCHAR},
|
||||||
report_id = #{reportId,jdbcType=VARCHAR},
|
report_id = #{reportId,jdbcType=VARCHAR},
|
||||||
num = #{num,jdbcType=INTEGER}
|
num = #{num,jdbcType=INTEGER},
|
||||||
|
original_state = #{originalState,jdbcType=VARCHAR}
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
</mapper>
|
</mapper>
|
|
@ -235,7 +235,7 @@
|
||||||
|
|
||||||
<update id="removeToGc">
|
<update id="removeToGc">
|
||||||
update api_definition
|
update api_definition
|
||||||
set
|
set original_state=status,
|
||||||
status = 'Trash'
|
status = 'Trash'
|
||||||
where id in
|
where id in
|
||||||
<foreach collection="ids" item="v" separator="," open="(" close=")">
|
<foreach collection="ids" item="v" separator="," open="(" close=")">
|
||||||
|
@ -245,7 +245,7 @@
|
||||||
|
|
||||||
<update id="removeToGcByExample" parameterType="io.metersphere.base.domain.ApiDefinitionExample">
|
<update id="removeToGcByExample" parameterType="io.metersphere.base.domain.ApiDefinitionExample">
|
||||||
update api_definition
|
update api_definition
|
||||||
set
|
set original_state=status,
|
||||||
status = 'Trash', module_path = null, module_id = null
|
status = 'Trash', module_path = null, module_id = null
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Example_Where_Clause" />
|
<include refid="Example_Where_Clause" />
|
||||||
|
@ -255,7 +255,7 @@
|
||||||
<update id="reduction">
|
<update id="reduction">
|
||||||
update api_definition
|
update api_definition
|
||||||
set
|
set
|
||||||
status = 'Underway'
|
status = original_state
|
||||||
where id in
|
where id in
|
||||||
<foreach collection="ids" item="v" separator="," open="(" close=")">
|
<foreach collection="ids" item="v" separator="," open="(" close=")">
|
||||||
#{v}
|
#{v}
|
||||||
|
|
|
@ -275,7 +275,7 @@
|
||||||
|
|
||||||
<update id="removeToGc">
|
<update id="removeToGc">
|
||||||
update api_scenario
|
update api_scenario
|
||||||
set
|
set original_state=status,
|
||||||
status = 'Trash'
|
status = 'Trash'
|
||||||
where id in
|
where id in
|
||||||
<foreach collection="ids" item="v" separator="," open="(" close=")">
|
<foreach collection="ids" item="v" separator="," open="(" close=")">
|
||||||
|
@ -285,7 +285,7 @@
|
||||||
|
|
||||||
<update id="removeToGcByExample" parameterType="io.metersphere.base.domain.ApiScenarioExample">
|
<update id="removeToGcByExample" parameterType="io.metersphere.base.domain.ApiScenarioExample">
|
||||||
update api_scenario
|
update api_scenario
|
||||||
set
|
set original_state=status,
|
||||||
status = 'Trash', module_path = null, api_scenario_module_id = null
|
status = 'Trash', module_path = null, api_scenario_module_id = null
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Example_Where_Clause" />
|
<include refid="Example_Where_Clause" />
|
||||||
|
@ -295,7 +295,7 @@
|
||||||
<update id="reduction">
|
<update id="reduction">
|
||||||
update api_scenario
|
update api_scenario
|
||||||
set
|
set
|
||||||
status = 'Underway'
|
status = original_state
|
||||||
where id in
|
where id in
|
||||||
<foreach collection="ids" item="v" separator="," open="(" close=")">
|
<foreach collection="ids" item="v" separator="," open="(" close=")">
|
||||||
#{v}
|
#{v}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package io.metersphere.commons.constants;
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
public enum ApiImportPlatform {
|
public enum ApiImportPlatform {
|
||||||
Metersphere, Postman, Swagger2, Plugin, Jmeter
|
Metersphere, Postman, Swagger2, Plugin, Jmeter, Har
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,11 @@ public class SystemParameterController {
|
||||||
return SystemParameterService.getVersion();
|
return SystemParameterService.getVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/theme")
|
||||||
|
public String getTheme() {
|
||||||
|
return SystemParameterService.getValue("ui.theme");
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/mail/info")
|
@GetMapping("/mail/info")
|
||||||
@RequiresRoles(value = {RoleConstants.ADMIN})
|
@RequiresRoles(value = {RoleConstants.ADMIN})
|
||||||
public MailInfo mailInfo() {
|
public MailInfo mailInfo() {
|
||||||
|
|
|
@ -52,14 +52,11 @@ create table test_case_review_load
|
||||||
) ENGINE = InnoDB
|
) ENGINE = InnoDB
|
||||||
DEFAULT CHARSET = utf8mb4;
|
DEFAULT CHARSET = utf8mb4;
|
||||||
-- test_resource_pool add column
|
-- test_resource_pool add column
|
||||||
ALTER TABLE test_resource_pool
|
ALTER TABLE test_resource_pool ADD heap VARCHAR(200) NULL;
|
||||||
ADD heap VARCHAR(200) NULL;
|
ALTER TABLE test_resource_pool ADD gc_algo VARCHAR(200) NULL;
|
||||||
ALTER TABLE test_resource_pool
|
|
||||||
ADD gc_algo VARCHAR(200) NULL;
|
|
||||||
|
|
||||||
-- create tale api_document_share
|
-- create tale api_document_share
|
||||||
CREATE TABLE IF NOT EXISTS `api_document_share`
|
CREATE TABLE IF NOT EXISTS `api_document_share` (
|
||||||
(
|
|
||||||
`id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Api Document Share Info ID',
|
`id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Api Document Share Info ID',
|
||||||
`create_time` BIGINT ( 13 ) NOT NULL COMMENT 'Create timestamp',
|
`create_time` BIGINT ( 13 ) NOT NULL COMMENT 'Create timestamp',
|
||||||
`create_user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
|
`create_user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
|
||||||
|
@ -69,10 +66,7 @@ CREATE TABLE IF NOT EXISTS `api_document_share`
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `share_type`(`share_type`) USING BTREE,
|
INDEX `share_type`(`share_type`) USING BTREE,
|
||||||
INDEX `share_api_id`(`share_api_id`(125)) USING BTREE
|
INDEX `share_api_id`(`share_api_id`(125)) USING BTREE
|
||||||
) ENGINE = InnoDB
|
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||||
CHARACTER SET = utf8mb4
|
|
||||||
COLLATE = utf8mb4_general_ci
|
|
||||||
ROW_FORMAT = Dynamic;
|
|
||||||
|
|
||||||
-- swagger_url_project
|
-- swagger_url_project
|
||||||
alter table swagger_url_project
|
alter table swagger_url_project
|
||||||
|
@ -85,19 +79,16 @@ alter table test_case
|
||||||
alter table test_case
|
alter table test_case
|
||||||
add demand_name varchar(999) null;
|
add demand_name varchar(999) null;
|
||||||
-- test_case_review add column
|
-- test_case_review add column
|
||||||
ALTER TABLE test_case_review
|
ALTER TABLE test_case_review ADD tags VARCHAR(2000) NULL;
|
||||||
ADD tags VARCHAR(2000) NULL;
|
|
||||||
|
|
||||||
-- alter test_plan_api_scenario
|
-- alter test_plan_api_scenario
|
||||||
alter table test_plan_api_scenario
|
alter table test_plan_api_scenario change environment_id environment longtext null comment 'Relevance environment';
|
||||||
change environment_id environment longtext null comment 'Relevance environment';
|
|
||||||
|
|
||||||
-- file add sort column
|
-- file add sort column
|
||||||
alter table file_metadata
|
alter table file_metadata add sort int default 0;
|
||||||
add sort int default 0;
|
|
||||||
|
|
||||||
-- add test_case column
|
-- add Original state
|
||||||
ALTER TABLE test_case
|
alter table api_definition add original_state varchar(64);
|
||||||
ADD follow_people VARCHAR(100) NULL;
|
alter table api_scenario add original_state varchar(64);
|
||||||
ALTER TABLE test_case
|
update api_definition set original_state='Underway';
|
||||||
ADD status VARCHAR(25) NULL;
|
update api_scenario set original_state='Underway';
|
|
@ -17,7 +17,6 @@
|
||||||
"@fortawesome/vue-fontawesome": "^0.1.9",
|
"@fortawesome/vue-fontawesome": "^0.1.9",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"core-js": "^3.4.3",
|
"core-js": "^3.4.3",
|
||||||
"default-passive-events": "^2.0.0",
|
|
||||||
"diffable-html": "^4.0.0",
|
"diffable-html": "^4.0.0",
|
||||||
"echarts": "^4.6.0",
|
"echarts": "^4.6.0",
|
||||||
"el-table-infinite-scroll": "^1.0.10",
|
"el-table-infinite-scroll": "^1.0.10",
|
||||||
|
@ -49,7 +48,8 @@
|
||||||
"vuex": "^3.1.2",
|
"vuex": "^3.1.2",
|
||||||
"xml-js": "^1.6.11",
|
"xml-js": "^1.6.11",
|
||||||
"yan-progress": "^1.0.3",
|
"yan-progress": "^1.0.3",
|
||||||
"jsonpath": "^1.1.0"
|
"jsonpath": "^1.1.0",
|
||||||
|
"vue-minder-editor-plus": "^1.0.14"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "^4.1.0",
|
"@vue/cli-plugin-babel": "^4.1.0",
|
||||||
|
|
|
@ -8,18 +8,20 @@
|
||||||
<el-row id="header-top" type="flex" justify="space-between" align="middle">
|
<el-row id="header-top" type="flex" justify="space-between" align="middle">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<img :src="'/display/file/logo'" class="logo" alt="">
|
<img :src="'/display/file/logo'" class="logo" alt="">
|
||||||
<ms-top-menus/>
|
<ms-top-menus :color="color"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="align-right">
|
<el-col :span="12" class="align-right">
|
||||||
<!-- float right -->
|
<!-- float right -->
|
||||||
<ms-user/>
|
<ms-user/>
|
||||||
<ms-language-switch/>
|
<ms-language-switch :color="color"/>
|
||||||
<ms-header-org-ws/>
|
<ms-header-org-ws :color="color"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<ms-view/>
|
<ms-view/>
|
||||||
|
|
||||||
|
<theme/>
|
||||||
</el-col>
|
</el-col>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -29,12 +31,14 @@ import MsView from "./components/common/router/View";
|
||||||
import MsUser from "./components/common/head/HeaderUser";
|
import MsUser from "./components/common/head/HeaderUser";
|
||||||
import MsHeaderOrgWs from "./components/common/head/HeaderOrgWs";
|
import MsHeaderOrgWs from "./components/common/head/HeaderOrgWs";
|
||||||
import MsLanguageSwitch from "./components/common/head/LanguageSwitch";
|
import MsLanguageSwitch from "./components/common/head/LanguageSwitch";
|
||||||
import {saveLocalStorage} from "@/common/js/utils";
|
import {hasLicense, saveLocalStorage, setColor, setOriginColor} from "@/common/js/utils";
|
||||||
import {registerRequestHeaders} from "@/common/js/ajax";
|
import {registerRequestHeaders} from "@/common/js/ajax";
|
||||||
|
import {ORIGIN_COLOR} from "@/common/js/constants";
|
||||||
|
|
||||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||||
const header = requireComponent.keys().length > 0 ? requireComponent("./license/LicenseMessage.vue") : {};
|
const header = requireComponent.keys().length > 0 ? requireComponent("./license/LicenseMessage.vue") : {};
|
||||||
const display = requireComponent.keys().length > 0 ? requireComponent("./display/Display.vue") : {};
|
const display = requireComponent.keys().length > 0 ? requireComponent("./display/Display.vue") : {};
|
||||||
|
const theme = requireComponent.keys().length > 0 ? requireComponent("./display/Theme.vue") : {};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
|
@ -45,16 +49,27 @@ export default {
|
||||||
auth: false,
|
auth: false,
|
||||||
header: {},
|
header: {},
|
||||||
logoId: '_blank',
|
logoId: '_blank',
|
||||||
|
color: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
registerRequestHeaders();
|
||||||
|
if (!hasLicense()) {
|
||||||
|
setOriginColor()
|
||||||
|
this.color = ORIGIN_COLOR;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
this.$get('/system/theme', res => {
|
||||||
|
this.color = res.data ? res.data : ORIGIN_COLOR;
|
||||||
|
setColor(this.color, this.color, this.color, this.color);
|
||||||
|
})
|
||||||
|
}
|
||||||
if (localStorage.getItem("store")) {
|
if (localStorage.getItem("store")) {
|
||||||
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(localStorage.getItem("store"))))
|
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(localStorage.getItem("store"))))
|
||||||
}
|
}
|
||||||
window.addEventListener("beforeunload", () => {
|
window.addEventListener("beforeunload", () => {
|
||||||
localStorage.setItem("store", JSON.stringify(this.$store.state))
|
localStorage.setItem("store", JSON.stringify(this.$store.state))
|
||||||
})
|
})
|
||||||
registerRequestHeaders();
|
|
||||||
},
|
},
|
||||||
beforeCreate() {
|
beforeCreate() {
|
||||||
this.$get("/isLogin").then(response => {
|
this.$get("/isLogin").then(response => {
|
||||||
|
@ -83,7 +98,8 @@ export default {
|
||||||
MsView,
|
MsView,
|
||||||
MsTopMenus,
|
MsTopMenus,
|
||||||
MsHeaderOrgWs,
|
MsHeaderOrgWs,
|
||||||
"LicenseMessage": header.default
|
"LicenseMessage": header.default,
|
||||||
|
"Theme": theme.default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -93,7 +109,7 @@ export default {
|
||||||
#header-top {
|
#header-top {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
background-color: rgb(44, 42, 72);
|
background-color: var(--color);
|
||||||
color: rgb(245, 245, 245);
|
color: rgb(245, 245, 245);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
|
|
@ -276,7 +276,9 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: this.$t('test_track.case.batch_move_case'), handleClick: this.handleBatchMove
|
name: this.$t('test_track.case.batch_move_case'), handleClick: this.handleBatchMove
|
||||||
}
|
},
|
||||||
|
{name: this.$t('api_test.definition.request.batch_delete'), handleClick: this.handleDeleteBatch},
|
||||||
|
|
||||||
],
|
],
|
||||||
isSelectAllDate: false,
|
isSelectAllDate: false,
|
||||||
selectRows: new Set(),
|
selectRows: new Set(),
|
||||||
|
@ -596,6 +598,29 @@
|
||||||
this.search();
|
this.search();
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleDeleteBatch(row) {
|
||||||
|
if (this.trashEnable) {
|
||||||
|
let ids = Array.from(this.selectRows).map(row => row.id);
|
||||||
|
this.$post('/api/automation/deleteBatch/', ids, () => {
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
this.search();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$alert(this.$t('api_test.definition.request.delete_confirm') + " ?", '', {
|
||||||
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
|
callback: (action) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
let ids = Array.from(this.selectRows).map(row => row.id);
|
||||||
|
this.$post('/api/automation/removeToGc/', ids, () => {
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
this.search();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
execute(row) {
|
execute(row) {
|
||||||
this.infoDb = false;
|
this.infoDb = false;
|
||||||
let url = "/api/automation/run";
|
let url = "/api/automation/run";
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
|
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('commons.import_mode')">
|
<el-form-item v-if="!isHar" :label="$t('commons.import_mode')">
|
||||||
<el-select size="small" v-model="formData.modeId" class="project-select" clearable>
|
<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-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
@ -118,6 +118,13 @@
|
||||||
tip: this.$t('api_test.api_import.jmeter_tip'),
|
tip: this.$t('api_test.api_import.jmeter_tip'),
|
||||||
exportTip: this.$t('api_test.api_import.jmeter_export_tip'),
|
exportTip: this.$t('api_test.api_import.jmeter_export_tip'),
|
||||||
suffixes: new Set(['jmx'])
|
suffixes: new Set(['jmx'])
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Har',
|
||||||
|
value: 'Har',
|
||||||
|
tip: this.$t('api_test.api_import.har_tip'),
|
||||||
|
exportTip: this.$t('api_test.api_import.har_export_tip'),
|
||||||
|
suffixes: new Set(['har'])
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
selectedPlatform: {},
|
selectedPlatform: {},
|
||||||
|
@ -150,6 +157,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
isHar() {
|
||||||
|
return this.selectedPlatformValue === 'Har';
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
scheduleEdit() {
|
scheduleEdit() {
|
||||||
if (!this.formData.swaggerUrl) {
|
if (!this.formData.swaggerUrl) {
|
||||||
|
|
|
@ -24,9 +24,18 @@
|
||||||
:label="item.title"
|
:label="item.title"
|
||||||
:closable="item.closable"
|
:closable="item.closable"
|
||||||
:name="item.name">
|
:name="item.name">
|
||||||
|
<ms-tab-button
|
||||||
|
v-if="item.type === 'list'"
|
||||||
|
:active-dom.sync="activeDom"
|
||||||
|
:left-tip="$t('api_test.definition.api_title')"
|
||||||
|
:right-tip="$t('api_test.definition.doc_title')"
|
||||||
|
:middle-tip="$t('api_test.definition.case_title')"
|
||||||
|
left-content="API"
|
||||||
|
middle-content="CASE"
|
||||||
|
:right-content="$t('api_test.definition.doc_title')">
|
||||||
<!-- 列表集合 -->
|
<!-- 列表集合 -->
|
||||||
<ms-api-list
|
<ms-api-list
|
||||||
v-if="item.type === 'list' && activeDom==='api' "
|
v-if="activeDom==='left'"
|
||||||
@runTest="runTest"
|
@runTest="runTest"
|
||||||
:module-tree="nodeTree"
|
:module-tree="nodeTree"
|
||||||
:module-options="moduleOptions"
|
:module-options="moduleOptions"
|
||||||
|
@ -35,46 +44,33 @@
|
||||||
:currentRow="currentRow"
|
:currentRow="currentRow"
|
||||||
:select-node-ids="selectNodeIds"
|
:select-node-ids="selectNodeIds"
|
||||||
:trash-enable="trashEnable"
|
:trash-enable="trashEnable"
|
||||||
:is-api-list-enable="isApiListEnable"
|
|
||||||
:active-dom="activeDom"
|
|
||||||
:queryDataType="queryDataType"
|
:queryDataType="queryDataType"
|
||||||
:selectDataRange="selectDataRange"
|
:selectDataRange="selectDataRange"
|
||||||
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
||||||
@editApi="editApi"
|
@editApi="editApi"
|
||||||
@handleCase="handleCase"
|
@handleCase="handleCase"
|
||||||
@showExecResult="showExecResult"
|
@showExecResult="showExecResult"
|
||||||
@activeDomChange="activeDomChange"
|
|
||||||
@isApiListEnableChange="isApiListEnableChange"
|
|
||||||
ref="apiList"/>
|
ref="apiList"/>
|
||||||
<!--测试用例列表-->
|
<!--测试用例列表-->
|
||||||
<api-case-simple-list
|
<api-case-simple-list
|
||||||
v-if="item.type === 'list' && activeDom==='testCase' "
|
v-if="activeDom==='middle'"
|
||||||
:current-protocol="currentProtocol"
|
:current-protocol="currentProtocol"
|
||||||
:visible="visible"
|
:visible="visible"
|
||||||
:currentRow="currentRow"
|
:currentRow="currentRow"
|
||||||
:select-node-ids="selectNodeIds"
|
:select-node-ids="selectNodeIds"
|
||||||
:trash-enable="trashEnable"
|
:trash-enable="trashEnable"
|
||||||
:is-api-list-enable="isApiListEnable"
|
|
||||||
:active-dom="activeDom"
|
|
||||||
:queryDataType="queryDataType"
|
:queryDataType="queryDataType"
|
||||||
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
||||||
@isApiListEnableChange="isApiListEnableChange"
|
|
||||||
@activeDomChange="activeDomChange"
|
|
||||||
@handleCase="handleCase"
|
@handleCase="handleCase"
|
||||||
@showExecResult="showExecResult"
|
@showExecResult="showExecResult"
|
||||||
ref="apiList"/>
|
ref="apiList"/>
|
||||||
<api-documents-page class="api-doc-page"
|
<api-documents-page class="api-doc-page"
|
||||||
v-if="item.type === 'list' && activeDom==='doc' "
|
v-if="activeDom==='right'"
|
||||||
:is-api-list-enable="isApiListEnable"
|
|
||||||
:active-dom="activeDom"
|
|
||||||
:project-id="projectId"
|
:project-id="projectId"
|
||||||
:module-ids="selectNodeIds"
|
:module-ids="selectNodeIds"/>
|
||||||
@activeDomChange="activeDomChange"
|
</ms-tab-button>
|
||||||
@isApiListEnableChange="isApiListEnableChange"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 添加/编辑测试窗口-->
|
<!-- 添加/编辑测试窗口-->
|
||||||
<div v-else-if="item.type=== 'ADD'" class="ms-api-div">
|
<div v-if="item.type=== 'ADD'" class="ms-api-div">
|
||||||
<ms-api-config :syncTabs="syncTabs" @runTest="runTest" @saveApi="saveApi" @createRootModel="createRootModel" ref="apiConfig"
|
<ms-api-config :syncTabs="syncTabs" @runTest="runTest" @saveApi="saveApi" @createRootModel="createRootModel" ref="apiConfig"
|
||||||
:current-api="item.api"
|
:current-api="item.api"
|
||||||
:project-id="projectId"
|
:project-id="projectId"
|
||||||
|
@ -147,6 +143,8 @@ import MsApiModule from "./components/module/ApiModule";
|
||||||
import ApiCaseSimpleList from "./components/list/ApiCaseSimpleList";
|
import ApiCaseSimpleList from "./components/list/ApiCaseSimpleList";
|
||||||
|
|
||||||
import ApiDocumentsPage from "@/business/components/api/definition/components/list/ApiDocumentsPage";
|
import ApiDocumentsPage from "@/business/components/api/definition/components/list/ApiDocumentsPage";
|
||||||
|
import MsTableButton from "@/business/components/common/components/MsTableButton";
|
||||||
|
import MsTabButton from "@/business/components/common/components/MsTabButton";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ApiDefinition",
|
name: "ApiDefinition",
|
||||||
|
@ -155,17 +153,12 @@ import ApiCaseSimpleList from "./components/list/ApiCaseSimpleList";
|
||||||
let routeParam = this.$route.params.dataType;
|
let routeParam = this.$route.params.dataType;
|
||||||
let redirectIDParam = this.$route.params.redirectID;
|
let redirectIDParam = this.$route.params.redirectID;
|
||||||
this.changeRedirectParam(redirectIDParam);
|
this.changeRedirectParam(redirectIDParam);
|
||||||
if (routeParam === 'apiTestCase') {
|
|
||||||
this.isApiListEnableChange(false);
|
|
||||||
this.activeDomChange("testCase");
|
|
||||||
} else {
|
|
||||||
this.isApiListEnableChange(true);
|
|
||||||
this.activeDomChange("api");
|
|
||||||
}
|
|
||||||
return routeParam;
|
return routeParam;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
MsTabButton,
|
||||||
|
MsTableButton,
|
||||||
ApiCaseSimpleList,
|
ApiCaseSimpleList,
|
||||||
MsApiModule,
|
MsApiModule,
|
||||||
MsApiList,
|
MsApiList,
|
||||||
|
@ -211,8 +204,7 @@ import ApiCaseSimpleList from "./components/list/ApiCaseSimpleList";
|
||||||
type: "list",
|
type: "list",
|
||||||
closable: false
|
closable: false
|
||||||
}],
|
}],
|
||||||
isApiListEnable: true,
|
activeDom: "left",
|
||||||
activeDom: "testCase",
|
|
||||||
syncTabs: [],
|
syncTabs: [],
|
||||||
projectId: "",
|
projectId: "",
|
||||||
nodeTree: []
|
nodeTree: []
|
||||||
|
@ -247,12 +239,6 @@ import ApiCaseSimpleList from "./components/list/ApiCaseSimpleList";
|
||||||
changeRedirectParam(redirectIDParam) {
|
changeRedirectParam(redirectIDParam) {
|
||||||
this.redirectID = redirectIDParam;
|
this.redirectID = redirectIDParam;
|
||||||
},
|
},
|
||||||
isApiListEnableChange(data) {
|
|
||||||
this.isApiListEnable = data;
|
|
||||||
},
|
|
||||||
activeDomChange(tabType){
|
|
||||||
this.activeDom = tabType;
|
|
||||||
},
|
|
||||||
addTab(tab) {
|
addTab(tab) {
|
||||||
if (tab.name === 'add') {
|
if (tab.name === 'add') {
|
||||||
this.handleTabsEdit(this.$t('api_test.definition.request.fast_debug'), "debug");
|
this.handleTabsEdit(this.$t('api_test.definition.request.fast_debug'), "debug");
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
|
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="!isScenarioModel" :label="$t('commons.import_mode')">
|
<el-form-item v-if="!isScenarioModel&&!isHar" :label="$t('commons.import_mode')">
|
||||||
<el-select size="small" v-model="formData.modeId" class="project-select" clearable>
|
<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-option v-for="item in modeOptions" :key="item.id" :label="item.name" :value="item.id"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
@ -146,7 +146,14 @@ export default {
|
||||||
tip: this.$t('api_test.api_import.swagger_tip'),
|
tip: this.$t('api_test.api_import.swagger_tip'),
|
||||||
exportTip: this.$t('api_test.api_import.swagger_export_tip'),
|
exportTip: this.$t('api_test.api_import.swagger_export_tip'),
|
||||||
suffixes: new Set(['json'])
|
suffixes: new Set(['json'])
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
name: 'Har',
|
||||||
|
value: 'Har',
|
||||||
|
tip: this.$t('api_test.api_import.har_tip'),
|
||||||
|
exportTip: this.$t('api_test.api_import.har_export_tip'),
|
||||||
|
suffixes: new Set(['har'])
|
||||||
|
},
|
||||||
],
|
],
|
||||||
selectedPlatform: {},
|
selectedPlatform: {},
|
||||||
selectedPlatformValue: 'Metersphere',
|
selectedPlatformValue: 'Metersphere',
|
||||||
|
@ -182,6 +189,9 @@ export default {
|
||||||
isSwagger2() {
|
isSwagger2() {
|
||||||
return this.selectedPlatformValue === 'Swagger2';
|
return this.selectedPlatformValue === 'Swagger2';
|
||||||
},
|
},
|
||||||
|
isHar() {
|
||||||
|
return this.selectedPlatformValue === 'Har';
|
||||||
|
},
|
||||||
isScenarioModel() {
|
isScenarioModel() {
|
||||||
return this.model === 'scenario';
|
return this.model === 'scenario';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<api-list-container-with-doc
|
<div>
|
||||||
:is-api-list-enable="isApiListEnable"
|
|
||||||
:active-dom="activeDom"
|
|
||||||
@activeDomChange="activeDomChange"
|
|
||||||
@isApiListEnableChange="isApiListEnableChange">
|
|
||||||
<el-link type="primary" style="float:right;margin-top: 5px" @click="open">{{$t('commons.adv_search.title')}}</el-link>
|
<el-link type="primary" style="float:right;margin-top: 5px" @click="open">{{$t('commons.adv_search.title')}}</el-link>
|
||||||
|
|
||||||
<el-input :placeholder="$t('commons.search_by_id_name_tag')" @blur="search" @keyup.enter.native="search" class="search-input" size="small"
|
<el-input :placeholder="$t('commons.search_by_id_name_tag')" @blur="search" @keyup.enter.native="search" class="search-input" size="small"
|
||||||
|
@ -114,7 +110,7 @@
|
||||||
:type=type></header-custom>
|
:type=type></header-custom>
|
||||||
<ms-table-pagination :change="initTable" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
<ms-table-pagination :change="initTable" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||||
:total="total"/>
|
:total="total"/>
|
||||||
</api-list-container-with-doc>
|
</div>
|
||||||
|
|
||||||
<api-case-list @showExecResult="showExecResult" @refresh="initTable" :currentApi="selectCase" ref="caseList"/>
|
<api-case-list @showExecResult="showExecResult" @refresh="initTable" :currentApi="selectCase" ref="caseList"/>
|
||||||
<!--批量编辑-->
|
<!--批量编辑-->
|
||||||
|
@ -145,9 +141,6 @@ import MsBatchEdit from "../basis/BatchEdit";
|
||||||
import {API_METHOD_COLOUR, CASE_PRIORITY, DUBBO_METHOD, REQ_METHOD, SQL_METHOD, TCP_METHOD} from "../../model/JsonData";
|
import {API_METHOD_COLOUR, CASE_PRIORITY, DUBBO_METHOD, REQ_METHOD, SQL_METHOD, TCP_METHOD} from "../../model/JsonData";
|
||||||
|
|
||||||
import {getBodyUploadFiles, getCurrentProjectID, getCurrentUser} from "@/common/js/utils";
|
import {getBodyUploadFiles, getCurrentProjectID, getCurrentUser} from "@/common/js/utils";
|
||||||
import ApiListContainer from "./ApiListContainer";
|
|
||||||
// import ApiListContainer from "./ApiListContainer";
|
|
||||||
import ApiListContainerWithDoc from "@/business/components/api/definition/components/list/ApiListContainerWithDoc";
|
|
||||||
import PriorityTableItem from "../../../../track/common/tableItems/planview/PriorityTableItem";
|
import PriorityTableItem from "../../../../track/common/tableItems/planview/PriorityTableItem";
|
||||||
import MsApiCaseTableExtendBtns from "../reference/ApiCaseTableExtendBtns";
|
import MsApiCaseTableExtendBtns from "../reference/ApiCaseTableExtendBtns";
|
||||||
import MsReferenceView from "../reference/ReferenceView";
|
import MsReferenceView from "../reference/ReferenceView";
|
||||||
|
@ -159,8 +152,8 @@ import MsTableHeaderSelectPopover from "@/business/components/common/components/
|
||||||
import MsTableAdvSearchBar from "@/business/components/common/components/search/MsTableAdvSearchBar";
|
import MsTableAdvSearchBar from "@/business/components/common/components/search/MsTableAdvSearchBar";
|
||||||
import {API_CASE_CONFIGS} from "@/business/components/common/components/search/search-components";
|
import {API_CASE_CONFIGS} from "@/business/components/common/components/search/search-components";
|
||||||
import {_filter, _handleSelect, _handleSelectAll, _sort, getLabel,} from "@/common/js/tableUtils";
|
import {_filter, _handleSelect, _handleSelectAll, _sort, getLabel,} from "@/common/js/tableUtils";
|
||||||
import {API_CASE_LIST, API_LIST, API_SCENARIO_LIST, TEST_CASE_LIST} from "@/common/js/constants";
|
import {API_CASE_LIST} from "@/common/js/constants";
|
||||||
import {Api_Case_List, Api_List, Track_Test_Case} from "@/business/components/common/model/JsonData";
|
import {Api_Case_List} from "@/business/components/common/model/JsonData";
|
||||||
import HeaderCustom from "@/business/components/common/head/HeaderCustom";
|
import HeaderCustom from "@/business/components/common/head/HeaderCustom";
|
||||||
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
|
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
|
||||||
|
|
||||||
|
@ -168,13 +161,11 @@ export default {
|
||||||
name: "ApiCaseSimpleList",
|
name: "ApiCaseSimpleList",
|
||||||
components: {
|
components: {
|
||||||
HeaderLabelOperate,
|
HeaderLabelOperate,
|
||||||
ApiListContainerWithDoc,
|
|
||||||
HeaderCustom,
|
HeaderCustom,
|
||||||
MsTableHeaderSelectPopover,
|
MsTableHeaderSelectPopover,
|
||||||
MsSetEnvironment,
|
MsSetEnvironment,
|
||||||
ApiCaseList,
|
ApiCaseList,
|
||||||
PriorityTableItem,
|
PriorityTableItem,
|
||||||
ApiListContainer,
|
|
||||||
MsTableOperatorButton,
|
MsTableOperatorButton,
|
||||||
MsTableOperator,
|
MsTableOperator,
|
||||||
MsTablePagination,
|
MsTablePagination,
|
||||||
|
@ -247,10 +238,6 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
isApiListEnable: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
isReadOnly: {
|
isReadOnly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
@ -298,12 +285,6 @@ export default {
|
||||||
customHeader() {
|
customHeader() {
|
||||||
this.$refs.headerCustom.open(this.tableLabel)
|
this.$refs.headerCustom.open(this.tableLabel)
|
||||||
},
|
},
|
||||||
isApiListEnableChange(data) {
|
|
||||||
this.$emit('isApiListEnableChange', data);
|
|
||||||
},
|
|
||||||
activeDomChange(tabType) {
|
|
||||||
this.$emit("activeDomChange", tabType);
|
|
||||||
},
|
|
||||||
initTable() {
|
initTable() {
|
||||||
getLabel(this, API_CASE_LIST);
|
getLabel(this, API_CASE_LIST);
|
||||||
this.selectRows = new Set();
|
this.selectRows = new Set();
|
||||||
|
|
|
@ -1,27 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<api-list-container-with-doc
|
|
||||||
:is-api-list-enable="isApiListEnable"
|
|
||||||
:active-dom="activeDom"
|
|
||||||
@activeDomChange="activeDomChange"
|
|
||||||
@isApiListEnableChange="isApiListEnableChange">
|
|
||||||
|
|
||||||
<api-document-item :project-id="projectId" :module-ids="moduleIds"/>
|
<api-document-item :project-id="projectId" :module-ids="moduleIds"/>
|
||||||
|
|
||||||
</api-list-container-with-doc>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import ApiListContainerWithDoc from "@/business/components/api/definition/components/list/ApiListContainerWithDoc";
|
|
||||||
import ApiDocumentItem from "@/business/components/api/definition/components/document/ApiDocumentItem";
|
import ApiDocumentItem from "@/business/components/api/definition/components/document/ApiDocumentItem";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ApiDocumentsPage",
|
name: "ApiDocumentsPage",
|
||||||
components: {
|
components: {
|
||||||
ApiListContainerWithDoc,
|
|
||||||
ApiDocumentItem,
|
ApiDocumentItem,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -32,10 +21,6 @@ export default {
|
||||||
projectId:String,
|
projectId:String,
|
||||||
moduleIds:Array,
|
moduleIds:Array,
|
||||||
activeDom:String,
|
activeDom:String,
|
||||||
isApiListEnable: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
},
|
},
|
||||||
|
@ -45,12 +30,6 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
isApiListEnableChange(data){
|
|
||||||
this.$emit("isApiListEnableChange",data);
|
|
||||||
},
|
|
||||||
activeDomChange(data){
|
|
||||||
this.$emit("activeDomChange",data);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<api-list-container-with-doc
|
<div>
|
||||||
:is-api-list-enable="isApiListEnable"
|
|
||||||
:active-dom="activeDom"
|
|
||||||
@activeDomChange="activeDomChange"
|
|
||||||
@isApiListEnableChange="isApiListEnableChange">
|
|
||||||
|
|
||||||
<el-link type="primary" @click="open" style="float: right;margin-top: 5px">{{ $t('commons.adv_search.title') }}
|
<el-link type="primary" @click="open" style="float: right;margin-top: 5px">{{ $t('commons.adv_search.title') }}
|
||||||
</el-link>
|
</el-link>
|
||||||
|
@ -197,7 +193,7 @@
|
||||||
</el-table>
|
</el-table>
|
||||||
<ms-table-pagination :change="initTable" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
<ms-table-pagination :change="initTable" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||||
:total="total"/>
|
:total="total"/>
|
||||||
</api-list-container-with-doc>
|
</div>
|
||||||
<ms-api-case-list @refresh="initTable" @showExecResult="showExecResult" :currentApi="selectApi" ref="caseList"/>
|
<ms-api-case-list @refresh="initTable" @showExecResult="showExecResult" :currentApi="selectApi" ref="caseList"/>
|
||||||
<!--批量编辑-->
|
<!--批量编辑-->
|
||||||
<ms-batch-edit ref="batchEdit" @batchEdit="batchEdit" :typeArr="typeArr" :value-arr="valueArr"/>
|
<ms-batch-edit ref="batchEdit" @batchEdit="batchEdit" :typeArr="typeArr" :value-arr="valueArr"/>
|
||||||
|
@ -226,14 +222,12 @@ import {downloadFile, getUUID} from "@/common/js/utils";
|
||||||
import {PROJECT_NAME} from '@/common/js/constants';
|
import {PROJECT_NAME} from '@/common/js/constants';
|
||||||
import {getCurrentProjectID, getCurrentUser} from "@/common/js/utils";
|
import {getCurrentProjectID, getCurrentUser} from "@/common/js/utils";
|
||||||
import {API_LIST, TEST_CASE_LIST, WORKSPACE_ID} from '@/common/js/constants';
|
import {API_LIST, TEST_CASE_LIST, WORKSPACE_ID} from '@/common/js/constants';
|
||||||
import ApiListContainer from "./ApiListContainer";
|
|
||||||
import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover";
|
import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover";
|
||||||
import ApiStatus from "@/business/components/api/definition/components/list/ApiStatus";
|
import ApiStatus from "@/business/components/api/definition/components/list/ApiStatus";
|
||||||
import MsTableAdvSearchBar from "@/business/components/common/components/search/MsTableAdvSearchBar";
|
import MsTableAdvSearchBar from "@/business/components/common/components/search/MsTableAdvSearchBar";
|
||||||
import {API_DEFINITION_CONFIGS} from "@/business/components/common/components/search/search-components";
|
import {API_DEFINITION_CONFIGS} from "@/business/components/common/components/search/search-components";
|
||||||
import MsTipButton from "@/business/components/common/components/MsTipButton";
|
import MsTipButton from "@/business/components/common/components/MsTipButton";
|
||||||
import CaseBatchMove from "@/business/components/api/definition/components/basis/BatchMove";
|
import CaseBatchMove from "@/business/components/api/definition/components/basis/BatchMove";
|
||||||
import ApiListContainerWithDoc from "@/business/components/api/definition/components/list/ApiListContainerWithDoc";
|
|
||||||
import {
|
import {
|
||||||
_handleSelect,
|
_handleSelect,
|
||||||
_handleSelectAll, buildBatchParam, getLabel,
|
_handleSelectAll, buildBatchParam, getLabel,
|
||||||
|
@ -241,7 +235,7 @@ import {
|
||||||
setUnSelectIds, toggleAllSelection
|
setUnSelectIds, toggleAllSelection
|
||||||
} from "@/common/js/tableUtils";
|
} from "@/common/js/tableUtils";
|
||||||
import {_filter, _sort} from "@/common/js/tableUtils";
|
import {_filter, _sort} from "@/common/js/tableUtils";
|
||||||
import {Api_List, Track_Test_Case} from "@/business/components/common/model/JsonData";
|
import {Api_List} from "@/business/components/common/model/JsonData";
|
||||||
import HeaderCustom from "@/business/components/common/head/HeaderCustom";
|
import HeaderCustom from "@/business/components/common/head/HeaderCustom";
|
||||||
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
|
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
|
||||||
import {Body} from "@/business/components/api/definition/model/ApiTestModel";
|
import {Body} from "@/business/components/api/definition/model/ApiTestModel";
|
||||||
|
@ -255,7 +249,6 @@ export default {
|
||||||
CaseBatchMove,
|
CaseBatchMove,
|
||||||
ApiStatus,
|
ApiStatus,
|
||||||
MsTableHeaderSelectPopover,
|
MsTableHeaderSelectPopover,
|
||||||
ApiListContainerWithDoc,
|
|
||||||
MsTableButton,
|
MsTableButton,
|
||||||
MsTableOperatorButton,
|
MsTableOperatorButton,
|
||||||
MsTableOperator,
|
MsTableOperator,
|
||||||
|
@ -349,7 +342,6 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
isApiListEnable: Boolean,
|
|
||||||
isReadOnly: {
|
isReadOnly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
@ -400,12 +392,6 @@ export default {
|
||||||
handleBatchMove() {
|
handleBatchMove() {
|
||||||
this.$refs.testCaseBatchMove.open(this.moduleTree, [], this.moduleOptions);
|
this.$refs.testCaseBatchMove.open(this.moduleTree, [], this.moduleOptions);
|
||||||
},
|
},
|
||||||
isApiListEnableChange(data) {
|
|
||||||
this.$emit('isApiListEnableChange', data);
|
|
||||||
},
|
|
||||||
activeDomChange(tabType){
|
|
||||||
this.$emit("activeDomChange",tabType);
|
|
||||||
},
|
|
||||||
initTable() {
|
initTable() {
|
||||||
getLabel(this, API_LIST);
|
getLabel(this, API_LIST);
|
||||||
this.selectRows = new Set();
|
this.selectRows = new Set();
|
||||||
|
|
|
@ -74,16 +74,16 @@ export default {
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
border: solid 1px #6d317c;
|
border: solid 1px #6d317c;
|
||||||
background-color: #7C3985;
|
background-color: var(--color);
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
.case-button {
|
.case-button {
|
||||||
border-left: solid 1px #6d317c;
|
border-left: solid 1px var(--color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.item{
|
.item{
|
||||||
border: solid 1px #6d317c;
|
border: solid 1px var(--color);
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -151,7 +151,7 @@
|
||||||
}
|
}
|
||||||
this.reqMessages = this.$t('api_test.request.address') + ":\n" + this.response.url + "\n" +
|
this.reqMessages = this.$t('api_test.request.address') + ":\n" + this.response.url + "\n" +
|
||||||
this.$t('api_test.scenario.headers') + ":\n" + this.response.headers + "\n" + "Cookies :\n" +
|
this.$t('api_test.scenario.headers') + ":\n" + this.response.headers + "\n" + "Cookies :\n" +
|
||||||
this.response.cookies + "\n" + "Bpdy:" + "\n" + this.response.body;
|
this.response.cookies + "\n" + "Body:" + "\n" + this.response.body;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -147,7 +147,7 @@ export default {
|
||||||
.count-number{
|
.count-number{
|
||||||
font-family:'ArialMT', 'Arial', sans-serif;
|
font-family:'ArialMT', 'Arial', sans-serif;
|
||||||
font-size:33px;
|
font-size:33px;
|
||||||
color: #6C317C;
|
color: var(--count_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-number-show {
|
.main-number-show {
|
||||||
|
@ -155,7 +155,7 @@ export default {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 7px;
|
border-width: 7px;
|
||||||
border-color: #CDB9D2;
|
border-color: var(--count_number_shallow);
|
||||||
border-radius:50%;
|
border-radius:50%;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,7 @@ export default {
|
||||||
.count-number{
|
.count-number{
|
||||||
font-family:'ArialMT', 'Arial', sans-serif;
|
font-family:'ArialMT', 'Arial', sans-serif;
|
||||||
font-size:33px;
|
font-size:33px;
|
||||||
color: #6C317C;
|
color: var(--count_number);
|
||||||
margin:20px auto;
|
margin:20px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ export default {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 7px;
|
border-width: 7px;
|
||||||
border-color: #CDB9D2;
|
border-color: var(--count_number_shallow);
|
||||||
border-radius:50%;
|
border-radius:50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ export default {
|
||||||
.count-number{
|
.count-number{
|
||||||
font-family:'ArialMT', 'Arial', sans-serif;
|
font-family:'ArialMT', 'Arial', sans-serif;
|
||||||
font-size:33px;
|
font-size:33px;
|
||||||
color: #6C317C;
|
color: var(--count_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-number-show {
|
.main-number-show {
|
||||||
|
@ -132,7 +132,7 @@ export default {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 7px;
|
border-width: 7px;
|
||||||
border-color: #CDB9D2;
|
border-color: var(--count_number_shallow);
|
||||||
border-radius:50%;
|
border-radius:50%;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ export default {
|
||||||
.count-number{
|
.count-number{
|
||||||
font-family:'ArialMT', 'Arial', sans-serif;
|
font-family:'ArialMT', 'Arial', sans-serif;
|
||||||
font-size:33px;
|
font-size:33px;
|
||||||
color: #6C317C;
|
color: var(--count_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-number-show {
|
.main-number-show {
|
||||||
|
@ -181,7 +181,7 @@ export default {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 7px;
|
border-width: 7px;
|
||||||
border-color: #CDB9D2;
|
border-color: var(--count_number_shallow);
|
||||||
border-radius:50%;
|
border-radius:50%;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
<template>
|
||||||
|
<el-card class="card-content" v-if="isShow">
|
||||||
|
|
||||||
|
<el-button-group v-if="isShowChangeButton">
|
||||||
|
|
||||||
|
<el-tooltip v-if="leftButtonEnable" class="item" effect="dark" :content="leftTip" placement="left">
|
||||||
|
<el-button plain style="width: 44px;height: 32px;padding: 5px 8px;" :class="{active: leftActive}" @click="changeTab('left')">{{leftContent}}</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
|
||||||
|
<el-tooltip v-if="middleButtonEnable" class="item" effect="dark" :content="middleTip" placement="top">
|
||||||
|
<el-button plain style="width: 44px;height: 32px;padding: 1px;" :class="{active: middleActive}" @click="changeTab('middle')">{{middleContent}}</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
|
||||||
|
<el-tooltip v-if="rightButtonEnable" class="item" effect="dark" :content="rightTip" placement="right">
|
||||||
|
<el-button plain style="width: 44px;height: 32px;padding: 1px;" :class="{active: rightActive}" @click="changeTab('right')">
|
||||||
|
{{rightContent}}
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
|
||||||
|
</el-button-group>
|
||||||
|
|
||||||
|
<template v-slot:header>
|
||||||
|
<slot name="header"></slot>
|
||||||
|
</template>
|
||||||
|
<slot></slot>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "MsTabButton",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isShow: true,
|
||||||
|
showApiList:false,
|
||||||
|
showTestCaseList:false,
|
||||||
|
showDocList:true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
activeDom: String,
|
||||||
|
isShowChangeButton: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
leftButtonEnable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
middleButtonEnable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
rightButtonEnable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
leftContent: {
|
||||||
|
type: String,
|
||||||
|
default: 'left'
|
||||||
|
},
|
||||||
|
middleContent: {
|
||||||
|
type: String,
|
||||||
|
default: 'middle'
|
||||||
|
},
|
||||||
|
rightContent: {
|
||||||
|
type: String,
|
||||||
|
default: 'right'
|
||||||
|
},
|
||||||
|
leftTip: {
|
||||||
|
type: String,
|
||||||
|
default: 'left'
|
||||||
|
},
|
||||||
|
middleTip: {
|
||||||
|
type: String,
|
||||||
|
default: 'middle'
|
||||||
|
},
|
||||||
|
rightTip: {
|
||||||
|
type: String,
|
||||||
|
default: 'right'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
leftActive() {
|
||||||
|
return this.activeDom === 'left';
|
||||||
|
},
|
||||||
|
middleActive() {
|
||||||
|
return this.activeDom === 'middle';
|
||||||
|
},
|
||||||
|
rightActive() {
|
||||||
|
return this.activeDom === 'right';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeTab(tabType){
|
||||||
|
this.$emit("update:activeDom", tabType);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.active {
|
||||||
|
border: solid 1px #6d317c;
|
||||||
|
background-color: var(--color);
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.case-button {
|
||||||
|
border-left: solid 1px var(--color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item{
|
||||||
|
border: solid 1px var(--color);
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<el-menu :unique-opened="true" mode="horizontal" router
|
<el-menu :unique-opened="true" mode="horizontal" router
|
||||||
class="header-user-menu align-right"
|
class="header-user-menu align-right"
|
||||||
background-color="#2c2a48"
|
:background-color="color"
|
||||||
active-text-color="#fff"
|
active-text-color="#fff"
|
||||||
default-active="1"
|
default-active="1"
|
||||||
text-color="#fff">
|
text-color="#fff">
|
||||||
|
@ -80,7 +80,10 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
currentUser: () => {
|
currentUser: () => {
|
||||||
return getCurrentUser();
|
return getCurrentUser();
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
color: String
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
searchOrg(val) {
|
searchOrg(val) {
|
||||||
|
@ -189,7 +192,7 @@ export default {
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
background-color: #595591;
|
background-color: var(--color_shallow);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,12 +210,12 @@ export default {
|
||||||
.search-input {
|
.search-input {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-top: -4px;
|
margin-top: -4px;
|
||||||
background-color: #595591;
|
background-color: var(--color_shallow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input >>> .el-input__inner {
|
.search-input >>> .el-input__inner {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background-color: #2d2a49;
|
background-color: var(--color);
|
||||||
color: #d2ced8;
|
color: #d2ced8;
|
||||||
border-color: #b4aebe;
|
border-color: #b4aebe;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<el-menu mode="horizontal" menu-trigger="click"
|
<el-menu mode="horizontal" menu-trigger="click"
|
||||||
background-color="#2c2a48"
|
:background-color="color"
|
||||||
class="header-top-menus"
|
class="header-top-menus"
|
||||||
text-color="#F2F2F2"
|
text-color="#F2F2F2"
|
||||||
active-text-color="#fff"
|
active-text-color="#fff"
|
||||||
|
@ -40,6 +40,9 @@
|
||||||
isReport: isReport
|
isReport: isReport
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
color: String
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route'(to) {
|
'$route'(to) {
|
||||||
if (to.matched.length > 0) {
|
if (to.matched.length > 0) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<el-menu :unique-opened="true" class="header-user-menu align-right"
|
<el-menu :unique-opened="true" class="header-user-menu align-right"
|
||||||
mode="horizontal"
|
mode="horizontal"
|
||||||
background-color="#2c2a48"
|
:background-color="color"
|
||||||
text-color="#fff"
|
text-color="#fff"
|
||||||
active-text-color="#fff"
|
active-text-color="#fff"
|
||||||
>
|
>
|
||||||
|
@ -34,6 +34,9 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
color: String
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
let lang = this.currentUser().language;
|
let lang = this.currentUser().language;
|
||||||
this.currentUserInfo = this.currentUser();
|
this.currentUserInfo = this.currentUser();
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<br>
|
<br>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-radio-group v-model="threadGroup.threadType">
|
<el-radio-group v-model="threadGroup.threadType" :disabled="true">
|
||||||
<el-radio label="DURATION">{{ $t('load_test.by_duration') }}</el-radio>
|
<el-radio label="DURATION">{{ $t('load_test.by_duration') }}</el-radio>
|
||||||
<el-radio label="ITERATION">{{ $t('load_test.by_iteration') }}</el-radio>
|
<el-radio label="ITERATION">{{ $t('load_test.by_iteration') }}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
|
@ -348,7 +348,27 @@ export default {
|
||||||
let threadInc2 = Math.ceil(tg.threadNumber / tg.step);
|
let threadInc2 = Math.ceil(tg.threadNumber / tg.step);
|
||||||
let inc2count = tg.threadNumber - tg.step * threadInc1;
|
let inc2count = tg.threadNumber - tg.step * threadInc1;
|
||||||
for (let j = 0; j <= tg.duration; j++) {
|
for (let j = 0; j <= tg.duration; j++) {
|
||||||
|
// x 轴
|
||||||
|
let xAxis = handler.options.xAxis.data;
|
||||||
|
if (xAxis.indexOf(j) < 0) {
|
||||||
|
xAxis.push(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tg.tgType === 'ThreadGroup') {
|
||||||
|
seriesData.step = undefined;
|
||||||
|
|
||||||
|
if (j === 0) {
|
||||||
|
seriesData.data.push([0, 0]);
|
||||||
|
}
|
||||||
|
if (j > tg.rampUpTime) {
|
||||||
|
xAxis.push(tg.duration);
|
||||||
|
|
||||||
|
seriesData.data.push([j, tg.threadNumber]);
|
||||||
|
seriesData.data.push([tg.duration, tg.threadNumber]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
seriesData.step = 'start';
|
||||||
if (j > timePeriod) {
|
if (j > timePeriod) {
|
||||||
timePeriod += timeInc;
|
timePeriod += timeInc;
|
||||||
if (inc2count > 0) {
|
if (inc2count > 0) {
|
||||||
|
@ -359,14 +379,14 @@ export default {
|
||||||
}
|
}
|
||||||
if (threadPeriod > tg.threadNumber) {
|
if (threadPeriod > tg.threadNumber) {
|
||||||
threadPeriod = tg.threadNumber;
|
threadPeriod = tg.threadNumber;
|
||||||
|
// 预热结束
|
||||||
|
xAxis.push(tg.duration);
|
||||||
|
seriesData.data.push([tg.duration, threadPeriod]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// x 轴
|
seriesData.data.push([j, threadPeriod]);
|
||||||
let xAxis = handler.options.xAxis.data;
|
|
||||||
if (xAxis.indexOf(j) < 0) {
|
|
||||||
xAxis.push(j);
|
|
||||||
}
|
}
|
||||||
seriesData.data.push(threadPeriod);
|
|
||||||
}
|
}
|
||||||
handler.options.series.push(seriesData);
|
handler.options.series.push(seriesData);
|
||||||
}
|
}
|
||||||
|
@ -445,6 +465,21 @@ export default {
|
||||||
for (let i = 0; i <= handler.duration; i++) {
|
for (let i = 0; i <= handler.duration; i++) {
|
||||||
// x 轴
|
// x 轴
|
||||||
handler.options.xAxis.data.push(i);
|
handler.options.xAxis.data.push(i);
|
||||||
|
if (handler.tgType === 'ThreadGroup') {
|
||||||
|
handler.options.series[0].step = undefined;
|
||||||
|
|
||||||
|
if (i === 0) {
|
||||||
|
handler.options.series[0].data.push([0, 0]);
|
||||||
|
}
|
||||||
|
if (i > handler.rampUpTime) {
|
||||||
|
handler.options.xAxis.data.push(handler.duration);
|
||||||
|
|
||||||
|
handler.options.series[0].data.push([i, handler.threadNumber]);
|
||||||
|
handler.options.series[0].data.push([handler.duration, handler.threadNumber]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
handler.options.series[0].step = 'start';
|
||||||
if (i > timePeriod) {
|
if (i > timePeriod) {
|
||||||
timePeriod += timeInc;
|
timePeriod += timeInc;
|
||||||
if (inc2count > 0) {
|
if (inc2count > 0) {
|
||||||
|
@ -455,10 +490,14 @@ export default {
|
||||||
}
|
}
|
||||||
if (threadPeriod > handler.threadNumber) {
|
if (threadPeriod > handler.threadNumber) {
|
||||||
threadPeriod = handler.threadNumber;
|
threadPeriod = handler.threadNumber;
|
||||||
|
handler.options.xAxis.data.push(handler.duration);
|
||||||
|
handler.options.series[0].data.push([handler.duration, handler.threadNumber]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
handler.options.series[0].data.push(threadPeriod);
|
handler.options.series[0].data.push([i, threadPeriod]);
|
||||||
} else {
|
} else {
|
||||||
handler.options.series[0].data.push(threadPeriod);
|
handler.options.series[0].data.push([i, threadPeriod]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.calculateTotalChart();
|
this.calculateTotalChart();
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
<el-tabs class="testplan-config" v-model="active" type="border-card" :stretch="true">
|
<el-tabs class="testplan-config" v-model="active" type="border-card" :stretch="true">
|
||||||
<el-tab-pane :label="$t('load_test.basic_config')">
|
<el-tab-pane :label="$t('load_test.basic_config')">
|
||||||
<performance-basic-config :is-read-only="isReadOnly" :test="test" ref="basicConfig"
|
<performance-basic-config :is-read-only="isReadOnly" :test="test" ref="basicConfig"
|
||||||
|
@tgTypeChange="tgTypeChange"
|
||||||
@fileChange="fileChange"/>
|
@fileChange="fileChange"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('load_test.pressure_config')">
|
<el-tab-pane :label="$t('load_test.pressure_config')">
|
||||||
|
@ -347,6 +348,10 @@ export default {
|
||||||
threadGroups.forEach(tg => {
|
threadGroups.forEach(tg => {
|
||||||
handler.calculateChart(tg);
|
handler.calculateChart(tg);
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
tgTypeChange(threadGroup) {
|
||||||
|
let handler = this.$refs.pressureConfig;
|
||||||
|
handler.calculateChart(threadGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="ThreadGroup">
|
label="ThreadGroup">
|
||||||
<template v-slot:default="{row}">
|
<template v-slot:default="{row}">
|
||||||
<el-select v-model="row.tgType" :placeholder="$t('commons.please_select')" size="small">
|
<el-select v-model="row.tgType" :placeholder="$t('commons.please_select')" size="small" @change="tgTypeChange(row)">
|
||||||
<el-option v-for="tg in threadGroupForSelect" :key="tg.tagName" :label="tg.name"
|
<el-option v-for="tg in threadGroupForSelect" :key="tg.tagName" :label="tg.name"
|
||||||
:value="tg.testclass"></el-option>
|
:value="tg.testclass"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
@ -377,6 +377,9 @@ export default {
|
||||||
threadGroupDisable(row) {
|
threadGroupDisable(row) {
|
||||||
return this.threadGroups.filter(tg => tg.enabled == 'true').length === 1 && row.enabled == 'true';
|
return this.threadGroups.filter(tg => tg.enabled == 'true').length === 1 && row.enabled == 'true';
|
||||||
},
|
},
|
||||||
|
tgTypeChange(row) {
|
||||||
|
this.$emit("tgTypeChange", row);
|
||||||
|
},
|
||||||
handleExceed() {
|
handleExceed() {
|
||||||
this.$error(this.$t('load_test.file_size_limit'));
|
this.$error(this.$t('load_test.file_size_limit'));
|
||||||
},
|
},
|
||||||
|
|
|
@ -42,10 +42,12 @@
|
||||||
<br>
|
<br>
|
||||||
<div v-if="threadGroup.threadType === 'DURATION'">
|
<div v-if="threadGroup.threadType === 'DURATION'">
|
||||||
<el-form-item :label="$t('load_test.duration')">
|
<el-form-item :label="$t('load_test.duration')">
|
||||||
|
<!-- 最多两天的测试时长 -->
|
||||||
<el-input-number
|
<el-input-number
|
||||||
:disabled="isReadOnly"
|
:disabled="isReadOnly"
|
||||||
v-model="threadGroup.duration"
|
v-model="threadGroup.duration"
|
||||||
:min="1"
|
:min="1"
|
||||||
|
:max="172800"
|
||||||
@change="calculateChart(threadGroup)"
|
@change="calculateChart(threadGroup)"
|
||||||
size="mini"/>
|
size="mini"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
@ -349,7 +351,6 @@ export default {
|
||||||
name: handler.threadGroups[i].attributes.testname,
|
name: handler.threadGroups[i].attributes.testname,
|
||||||
data: [],
|
data: [],
|
||||||
type: 'line',
|
type: 'line',
|
||||||
step: 'start',
|
|
||||||
smooth: false,
|
smooth: false,
|
||||||
symbolSize: 5,
|
symbolSize: 5,
|
||||||
showSymbol: false,
|
showSymbol: false,
|
||||||
|
@ -390,7 +391,26 @@ export default {
|
||||||
let threadInc2 = Math.ceil(tg.threadNumber / tg.step);
|
let threadInc2 = Math.ceil(tg.threadNumber / tg.step);
|
||||||
let inc2count = tg.threadNumber - tg.step * threadInc1;
|
let inc2count = tg.threadNumber - tg.step * threadInc1;
|
||||||
for (let j = 0; j <= tg.duration; j++) {
|
for (let j = 0; j <= tg.duration; j++) {
|
||||||
|
// x 轴
|
||||||
|
let xAxis = handler.options.xAxis.data;
|
||||||
|
if (xAxis.indexOf(j) < 0) {
|
||||||
|
xAxis.push(j);
|
||||||
|
}
|
||||||
|
if (tg.tgType === 'ThreadGroup') {
|
||||||
|
seriesData.step = undefined;
|
||||||
|
|
||||||
|
if (j === 0) {
|
||||||
|
seriesData.data.push([0, 0]);
|
||||||
|
}
|
||||||
|
if (j > tg.rampUpTime) {
|
||||||
|
xAxis.push(tg.duration);
|
||||||
|
|
||||||
|
seriesData.data.push([j, tg.threadNumber]);
|
||||||
|
seriesData.data.push([tg.duration, tg.threadNumber]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
seriesData.step = 'start';
|
||||||
if (j > timePeriod) {
|
if (j > timePeriod) {
|
||||||
timePeriod += timeInc;
|
timePeriod += timeInc;
|
||||||
if (inc2count > 0) {
|
if (inc2count > 0) {
|
||||||
|
@ -401,14 +421,14 @@ export default {
|
||||||
}
|
}
|
||||||
if (threadPeriod > tg.threadNumber) {
|
if (threadPeriod > tg.threadNumber) {
|
||||||
threadPeriod = tg.threadNumber;
|
threadPeriod = tg.threadNumber;
|
||||||
|
// 预热结束
|
||||||
|
xAxis.push(tg.duration);
|
||||||
|
seriesData.data.push([tg.duration, threadPeriod]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// x 轴
|
seriesData.data.push([j, threadPeriod]);
|
||||||
let xAxis = handler.options.xAxis.data;
|
|
||||||
if (xAxis.indexOf(j) < 0) {
|
|
||||||
xAxis.push(j);
|
|
||||||
}
|
}
|
||||||
seriesData.data.push(threadPeriod);
|
|
||||||
}
|
}
|
||||||
handler.options.series.push(seriesData);
|
handler.options.series.push(seriesData);
|
||||||
}
|
}
|
||||||
|
@ -492,6 +512,22 @@ export default {
|
||||||
for (let i = 0; i <= handler.duration; i++) {
|
for (let i = 0; i <= handler.duration; i++) {
|
||||||
// x 轴
|
// x 轴
|
||||||
handler.options.xAxis.data.push(i);
|
handler.options.xAxis.data.push(i);
|
||||||
|
|
||||||
|
if (handler.tgType === 'ThreadGroup') {
|
||||||
|
handler.options.series[0].step = undefined;
|
||||||
|
|
||||||
|
if (i === 0) {
|
||||||
|
handler.options.series[0].data.push([0, 0]);
|
||||||
|
}
|
||||||
|
if (i > handler.rampUpTime) {
|
||||||
|
handler.options.xAxis.data.push(handler.duration);
|
||||||
|
|
||||||
|
handler.options.series[0].data.push([i, handler.threadNumber]);
|
||||||
|
handler.options.series[0].data.push([handler.duration, handler.threadNumber]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
handler.options.series[0].step = 'start';
|
||||||
if (i > timePeriod) {
|
if (i > timePeriod) {
|
||||||
timePeriod += timeInc;
|
timePeriod += timeInc;
|
||||||
if (inc2count > 0) {
|
if (inc2count > 0) {
|
||||||
|
@ -502,10 +538,14 @@ export default {
|
||||||
}
|
}
|
||||||
if (threadPeriod > handler.threadNumber) {
|
if (threadPeriod > handler.threadNumber) {
|
||||||
threadPeriod = handler.threadNumber;
|
threadPeriod = handler.threadNumber;
|
||||||
|
handler.options.xAxis.data.push(handler.duration);
|
||||||
|
handler.options.series[0].data.push([handler.duration, handler.threadNumber]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
handler.options.series[0].data.push(threadPeriod);
|
handler.options.series[0].data.push([i, threadPeriod]);
|
||||||
} else {
|
} else {
|
||||||
handler.options.series[0].data.push(threadPeriod);
|
handler.options.series[0].data.push([i, threadPeriod]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.calculateTotalChart();
|
this.calculateTotalChart();
|
||||||
|
|
|
@ -16,7 +16,15 @@
|
||||||
<ms-main-container>
|
<ms-main-container>
|
||||||
<el-tabs v-model="activeName" @tab-click="addTab" @tab-remove="removeTab">
|
<el-tabs v-model="activeName" @tab-click="addTab" @tab-remove="removeTab">
|
||||||
<el-tab-pane name="default" :label="$t('api_test.definition.case_title')">
|
<el-tab-pane name="default" :label="$t('api_test.definition.case_title')">
|
||||||
|
<ms-tab-button
|
||||||
|
:active-dom.sync="activeDom"
|
||||||
|
:left-tip="'用例列表'"
|
||||||
|
:left-content="'CAS'"
|
||||||
|
:right-tip="'E脑图'"
|
||||||
|
:right-content="'脑图'"
|
||||||
|
:middle-button-enable="false">
|
||||||
<test-case-list
|
<test-case-list
|
||||||
|
v-if="activeDom === 'left'"
|
||||||
:checkRedirectID="checkRedirectID"
|
:checkRedirectID="checkRedirectID"
|
||||||
:module-options="moduleOptions"
|
:module-options="moduleOptions"
|
||||||
:select-node-ids="selectNodeIds"
|
:select-node-ids="selectNodeIds"
|
||||||
|
@ -31,6 +39,10 @@
|
||||||
@setCondition="setCondition"
|
@setCondition="setCondition"
|
||||||
ref="testCaseList">
|
ref="testCaseList">
|
||||||
</test-case-list>
|
</test-case-list>
|
||||||
|
<testcase-minder
|
||||||
|
v-if="activeDom === 'right'"
|
||||||
|
ref="testCaseList"/>
|
||||||
|
</ms-tab-button>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
:key="item.name"
|
:key="item.name"
|
||||||
|
@ -87,10 +99,14 @@ import MsMainContainer from "../../common/components/MsMainContainer";
|
||||||
import {checkoutTestManagerOrTestUser, getCurrentProjectID, getUUID, hasRoles} from "../../../../common/js/utils";
|
import {checkoutTestManagerOrTestUser, getCurrentProjectID, getUUID, hasRoles} from "../../../../common/js/utils";
|
||||||
import TestCaseNodeTree from "../common/TestCaseNodeTree";
|
import TestCaseNodeTree from "../common/TestCaseNodeTree";
|
||||||
import {TrackEvent,LIST_CHANGE} from "@/business/components/common/head/ListEvent";
|
import {TrackEvent,LIST_CHANGE} from "@/business/components/common/head/ListEvent";
|
||||||
|
import TestcaseMinder from "@/business/components/track/case/components/minder/TestcaseMinder";
|
||||||
|
import MsTabButton from "@/business/components/common/components/MsTabButton";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "TestCase",
|
name: "TestCase",
|
||||||
components: {
|
components: {
|
||||||
|
MsTabButton,
|
||||||
|
TestcaseMinder,
|
||||||
TestCaseNodeTree,
|
TestCaseNodeTree,
|
||||||
MsMainContainer,
|
MsMainContainer,
|
||||||
MsAsideContainer, MsContainer, TestCaseList, NodeTree, TestCaseEdit, SelectMenu
|
MsAsideContainer, MsContainer, TestCaseList, NodeTree, TestCaseEdit, SelectMenu
|
||||||
|
@ -111,8 +127,8 @@ export default {
|
||||||
tabs: [],
|
tabs: [],
|
||||||
renderComponent:true,
|
renderComponent:true,
|
||||||
loading: false,
|
loading: false,
|
||||||
type:''
|
type:'',
|
||||||
|
activeDom: 'left'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div class="card-container">
|
<div class="card-container" v-loading="result.loading">
|
||||||
<el-card class="card-content" v-loading="result.loading">
|
|
||||||
<template v-slot:header>
|
|
||||||
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="initTableData"
|
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="initTableData"
|
||||||
:tip="$t('commons.search_by_name_or_id')" title="" :show-create="false"
|
:tip="$t('commons.search_by_name_or_id')" title="" :show-create="false"/>
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<el-table
|
<el-table
|
||||||
border
|
border
|
||||||
:data="tableData"
|
:data="tableData"
|
||||||
|
@ -168,7 +165,6 @@
|
||||||
|
|
||||||
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||||
:total="total"/>
|
:total="total"/>
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<batch-edit ref="batchEdit" @batchEdit="batchEdit"
|
<batch-edit ref="batchEdit" @batchEdit="batchEdit"
|
||||||
:typeArr="typeArr" :value-arr="valueArr" :dialog-title="$t('test_track.case.batch_edit_case')"/>
|
:typeArr="typeArr" :value-arr="valueArr" :dialog-title="$t('test_track.case.batch_edit_case')"/>
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<template>
|
||||||
|
<div class="minder">
|
||||||
|
<minder-editor class="minder-container" :import-json="importJson"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TestcaseMinder",
|
||||||
|
components: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
importJson: {
|
||||||
|
"root": {
|
||||||
|
"data": {
|
||||||
|
"text": "test111"
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{ "data": { "text": "新闻"}},
|
||||||
|
{ "data": { "text": "网页"} },
|
||||||
|
{ "data": { "text": "贴吧"} },
|
||||||
|
{ "data": { "text": "知道"} },
|
||||||
|
{ "data": { "text": "音乐" } },
|
||||||
|
{ "data": { "text": "图片"} },
|
||||||
|
{ "data": { "text": "视频"} },
|
||||||
|
{ "data": { "text": "地图" } },
|
||||||
|
{ "data": { "text": "百科","expandState":"collapse"}}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"template":"default"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
|
@ -1 +1 @@
|
||||||
Subproject commit 290ffd9eb52b1a42243adb35ac3ee61f8295bb8f
|
Subproject commit 17404980aab725889843ce8c65f5f5c00113ae21
|
|
@ -22,6 +22,9 @@ import {left2RightDrag, bottom2TopDrag, right2LeftDrag} from "../common/js/direc
|
||||||
import JsonSchemaEditor from './components/common/json-schema/schema/index';
|
import JsonSchemaEditor from './components/common/json-schema/schema/index';
|
||||||
import JSONPathPicker from 'vue-jsonpath-picker';
|
import JSONPathPicker from 'vue-jsonpath-picker';
|
||||||
import VueClipboard from 'vue-clipboard2'
|
import VueClipboard from 'vue-clipboard2'
|
||||||
|
import vueMinderEditor from 'vue-minder-editor-plus'
|
||||||
|
Vue.use(vueMinderEditor)
|
||||||
|
|
||||||
Vue.use(JsonSchemaEditor);
|
Vue.use(JsonSchemaEditor);
|
||||||
import VuePapaParse from 'vue-papa-parse'
|
import VuePapaParse from 'vue-papa-parse'
|
||||||
Vue.use(VuePapaParse)
|
Vue.use(VuePapaParse)
|
||||||
|
|
|
@ -14,6 +14,12 @@ body {
|
||||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
|
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
/*--color: #2c2a48;*/
|
||||||
|
/*--color_shallow: #595591;*/
|
||||||
|
--color: '';
|
||||||
|
--color_shallow: '';
|
||||||
|
--count_number: '';
|
||||||
|
--count_number_shallow: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 解决 document.body.clientHeight 为0 */
|
/* 解决 document.body.clientHeight 为0 */
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.header-top-menus.el-menu--horizontal > li {
|
.header-top-menus.el-menu--horizontal > li {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
|
@ -30,9 +29,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-top-menus.el-menu--horizontal > li.is-active {
|
.header-top-menus.el-menu--horizontal > li.is-active {
|
||||||
background: #595591 !important;
|
background: var(--color_shallow) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-menu.el-menu--horizontal {
|
.el-menu.el-menu--horizontal {
|
||||||
border-bottom: none;
|
border-bottom: none !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,3 +168,8 @@ export const JMETER_FUNC = [
|
||||||
{type: "String", name: "${__escapeHtml}", description: "Encode strings using HTML encoding"},
|
{type: "String", name: "${__escapeHtml}", description: "Encode strings using HTML encoding"},
|
||||||
{type: "String", name: "${__TestPlanName}", description: "Return name of current test plan"},
|
{type: "String", name: "${__TestPlanName}", description: "Return name of current test plan"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export const ORIGIN_COLOR = '#2c2a48';
|
||||||
|
export const ORIGIN_COLOR_SHALLOW = '#595591';
|
||||||
|
export const COUNT_NUMBER = '#6C317C';
|
||||||
|
export const COUNT_NUMBER_SHALLOW = '#CDB9D2';
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {
|
import {
|
||||||
LicenseKey,
|
COUNT_NUMBER, COUNT_NUMBER_SHALLOW,
|
||||||
|
LicenseKey, ORIGIN_COLOR, ORIGIN_COLOR_SHALLOW,
|
||||||
PROJECT_ID,
|
PROJECT_ID,
|
||||||
REFRESH_SESSION_USER_URL,
|
REFRESH_SESSION_USER_URL,
|
||||||
ROLE_ADMIN,
|
ROLE_ADMIN,
|
||||||
|
@ -348,3 +349,18 @@ export function objToStrMap(obj) {
|
||||||
}
|
}
|
||||||
return strMap;
|
return strMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getColor() {
|
||||||
|
return localStorage.getItem('color');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setColor(a, b, c, d) {
|
||||||
|
document.body.style.setProperty('--color', a);
|
||||||
|
document.body.style.setProperty('--color_shallow', b);
|
||||||
|
document.body.style.setProperty('--count_number', c);
|
||||||
|
document.body.style.setProperty('--count_number_shallow', d);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setOriginColor() {
|
||||||
|
setColor(ORIGIN_COLOR, ORIGIN_COLOR_SHALLOW, COUNT_NUMBER, COUNT_NUMBER_SHALLOW);
|
||||||
|
}
|
||||||
|
|
|
@ -914,7 +914,9 @@ export default {
|
||||||
export_tip: "Export Tip",
|
export_tip: "Export Tip",
|
||||||
ms_tip: "Support for MeterSphere JSON format",
|
ms_tip: "Support for MeterSphere JSON format",
|
||||||
ms_export_tip: "Export jSON-formatted files via MeterSphere website or browser plug-ins",
|
ms_export_tip: "Export jSON-formatted files via MeterSphere website or browser plug-ins",
|
||||||
|
har_export_tip: "Export Har files by browser dev-tool",
|
||||||
swagger_tip: "Swagger 2.0 and 3.0 json files are supported",
|
swagger_tip: "Swagger 2.0 and 3.0 json files are supported",
|
||||||
|
har_tip: "Only Har files are supported",
|
||||||
postman_tip: "Only Postman Collection V2.1 json files are supported",
|
postman_tip: "Only Postman Collection V2.1 json files are supported",
|
||||||
postman_export_tip: "Export the test collection by Postman",
|
postman_export_tip: "Export the test collection by Postman",
|
||||||
swagger_export_tip: "Export jSON-formatted files via Swagger website",
|
swagger_export_tip: "Export jSON-formatted files via Swagger website",
|
||||||
|
|
|
@ -917,8 +917,10 @@ export default {
|
||||||
export_tip: "导出方法",
|
export_tip: "导出方法",
|
||||||
ms_tip: "支持 Metersphere json 格式",
|
ms_tip: "支持 Metersphere json 格式",
|
||||||
ms_export_tip: "通过 Metersphere 接口测试页面或者浏览器插件导出 json 格式文件",
|
ms_export_tip: "通过 Metersphere 接口测试页面或者浏览器插件导出 json 格式文件",
|
||||||
|
har_export_tip: "通过 浏览器的开发者工具 导出 Har 格式文件",
|
||||||
postman_tip: "只支持 Postman Collection v2.1 格式的 json 文件",
|
postman_tip: "只支持 Postman Collection v2.1 格式的 json 文件",
|
||||||
swagger_tip: "支持 Swagger 2.0 与 3.0 版本的 json 文件",
|
swagger_tip: "支持 Swagger 2.0 与 3.0 版本的 json 文件",
|
||||||
|
har_tip: "只支持 Har 文件",
|
||||||
post_export_tip: "通过 Postman 导出测试集合",
|
post_export_tip: "通过 Postman 导出测试集合",
|
||||||
swagger_export_tip: "通过 Swagger 页面导出",
|
swagger_export_tip: "通过 Swagger 页面导出",
|
||||||
jmeter_export_tip: "通过 Jmeter 生成JMX文件",
|
jmeter_export_tip: "通过 Jmeter 生成JMX文件",
|
||||||
|
|
|
@ -916,8 +916,10 @@ export default {
|
||||||
export_tip: "導出方法",
|
export_tip: "導出方法",
|
||||||
ms_tip: "支持 Metersphere json 格式",
|
ms_tip: "支持 Metersphere json 格式",
|
||||||
ms_export_tip: "通過 Metersphere 接口測試頁面或者瀏覽器插件導出 json 格式文件",
|
ms_export_tip: "通過 Metersphere 接口測試頁面或者瀏覽器插件導出 json 格式文件",
|
||||||
|
har_export_tip: "通过 瀏覽器到開發者工具 导出 Har 格式文件",
|
||||||
postman_tip: "只支持 Postman Collection v2.1 格式的 json 文件",
|
postman_tip: "只支持 Postman Collection v2.1 格式的 json 文件",
|
||||||
swagger_tip: "支持 Swagger 2.0 與 3.0 版本的 json 文件",
|
swagger_tip: "支持 Swagger 2.0 與 3.0 版本的 json 文件",
|
||||||
|
har_tip: "只支持 Har 文件",
|
||||||
post_export_tip: "通過 Postman 導出測試集合",
|
post_export_tip: "通過 Postman 導出測試集合",
|
||||||
swagger_export_tip: "通過 Swagger 頁面導出",
|
swagger_export_tip: "通過 Swagger 頁面導出",
|
||||||
jmeter_export_tip: "通過 Jmeter 生成JMX文件",
|
jmeter_export_tip: "通過 Jmeter 生成JMX文件",
|
||||||
|
|
Loading…
Reference in New Issue