Merge branch 'master' of github.com:metersphere/metersphere
This commit is contained in:
commit
8cb054df86
|
@ -6,11 +6,11 @@ ARG MS_VERSION=dev
|
||||||
|
|
||||||
RUN mkdir -p /opt/apps && mkdir -p /opt/jmeter/lib/junit
|
RUN mkdir -p /opt/apps && mkdir -p /opt/jmeter/lib/junit
|
||||||
|
|
||||||
COPY backend/target/backend-1.7.jar /opt/apps
|
COPY backend/target/backend-1.8.jar /opt/apps
|
||||||
|
|
||||||
COPY backend/target/classes/jmeter/ /opt/jmeter/
|
COPY backend/target/classes/jmeter/ /opt/jmeter/
|
||||||
|
|
||||||
ENV JAVA_APP_JAR=/opt/apps/backend-1.7.jar
|
ENV JAVA_APP_JAR=/opt/apps/backend-1.8.jar
|
||||||
|
|
||||||
ENV AB_OFF=true
|
ENV AB_OFF=true
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>metersphere-server</artifactId>
|
<artifactId>metersphere-server</artifactId>
|
||||||
<groupId>io.metersphere</groupId>
|
<groupId>io.metersphere</groupId>
|
||||||
<version>1.7</version>
|
<version>1.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -46,8 +46,6 @@ public class HarScenarioParser extends HarScenarioAbstractParser<ScenarioImport>
|
||||||
String harName = request.getFileName();
|
String harName = request.getFileName();
|
||||||
// 场景步骤
|
// 场景步骤
|
||||||
LinkedList<MsTestElement> apiScenarioWithBLOBs = new LinkedList<>();
|
LinkedList<MsTestElement> apiScenarioWithBLOBs = new LinkedList<>();
|
||||||
// ApiScenarioWithBLOBs scenario = new ApiScenarioWithBLOBs();
|
|
||||||
// scenario.setName(harName);
|
|
||||||
|
|
||||||
MsScenario msScenario = new MsScenario();
|
MsScenario msScenario = new MsScenario();
|
||||||
msScenario.setName(harName);
|
msScenario.setName(harName);
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package io.metersphere.api.dto.definition;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class ApiTestCaseInfo extends ApiTestCaseWithBLOBs {
|
||||||
|
private String apiMethod;
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ public class ApiTestCaseResult extends ApiTestCaseWithBLOBs {
|
||||||
private String createUser;
|
private String createUser;
|
||||||
private String updateUser;
|
private String updateUser;
|
||||||
private String execResult;
|
private String execResult;
|
||||||
|
private String apiMethod;
|
||||||
private Long execTime;
|
private Long execTime;
|
||||||
private boolean active = false;
|
private boolean active = false;
|
||||||
private boolean responseActive = false;
|
private boolean responseActive = false;
|
||||||
|
|
|
@ -14,9 +14,9 @@ import java.util.List;
|
||||||
public class SwaggerApiExportResult extends ApiExportResult{
|
public class SwaggerApiExportResult extends ApiExportResult{
|
||||||
private String openapi;
|
private String openapi;
|
||||||
private SwaggerInfo info;
|
private SwaggerInfo info;
|
||||||
private String externalDocs;
|
private JSONObject externalDocs;
|
||||||
private List<String> servers;
|
private List<String> servers;
|
||||||
private List<SwaggerTag> tags;
|
private List<SwaggerTag> tags;
|
||||||
private JSONObject paths; // Map<String, Object>, Object 里放 Operation 对象
|
private JSONObject paths; // Map<String, Object>, Object 里放 Operation 对象
|
||||||
private List<String> components;
|
private JSONObject components;
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ public class HarParser extends HarAbstractParser {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HarPostData content = requestBody.postData;
|
HarPostData content = requestBody.postData;
|
||||||
if (!StringUtils.equalsIgnoreCase("GET", requestBody.method) || requestBody.postData == null) {
|
if (StringUtils.equalsIgnoreCase("GET", requestBody.method) || requestBody.postData == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String contentType = content.mimeType;
|
String contentType = content.mimeType;
|
||||||
|
|
|
@ -231,6 +231,9 @@ public class Swagger3Parser extends SwaggerAbstractParser {
|
||||||
MediaType mediaType = content.get(contentType);
|
MediaType mediaType = content.get(contentType);
|
||||||
if (mediaType == null) {
|
if (mediaType == null) {
|
||||||
Set<String> contentTypes = content.keySet();
|
Set<String> contentTypes = content.keySet();
|
||||||
|
if(contentTypes.size() == 0) { // 防止空指针
|
||||||
|
return;
|
||||||
|
}
|
||||||
contentType = contentTypes.iterator().next();
|
contentType = contentTypes.iterator().next();
|
||||||
if (StringUtils.isBlank(contentType)) {
|
if (StringUtils.isBlank(contentType)) {
|
||||||
return;
|
return;
|
||||||
|
@ -410,26 +413,34 @@ public class Swagger3Parser extends SwaggerAbstractParser {
|
||||||
result.setInfo(new SwaggerInfo());
|
result.setInfo(new SwaggerInfo());
|
||||||
result.setServers(new ArrayList<>());
|
result.setServers(new ArrayList<>());
|
||||||
result.setTags(new ArrayList<>());
|
result.setTags(new ArrayList<>());
|
||||||
result.setComponents(new ArrayList<>());
|
result.setComponents(new JSONObject());
|
||||||
|
result.setExternalDocs(new JSONObject());
|
||||||
|
|
||||||
JSONObject paths = new JSONObject();
|
JSONObject paths = new JSONObject();
|
||||||
JSONObject swaggerPath = new JSONObject();
|
|
||||||
for(ApiDefinitionWithBLOBs apiDefinition : apiDefinitionList) {
|
for(ApiDefinitionWithBLOBs apiDefinition : apiDefinitionList) {
|
||||||
SwaggerApiInfo swaggerApiInfo = new SwaggerApiInfo(); // {tags:, summary:, description:, parameters:}
|
SwaggerApiInfo swaggerApiInfo = new SwaggerApiInfo(); // {tags:, summary:, description:, parameters:}
|
||||||
swaggerApiInfo.setSummary(apiDefinition.getName());
|
swaggerApiInfo.setSummary(apiDefinition.getName());
|
||||||
// 设置导入后的模块名 (根据 api 的 moduleID 查库获得所属模块,作为导出的模块名)
|
// 设置导入后的模块名 (根据 api 的 moduleID 查库获得所属模块,作为导出的模块名)
|
||||||
ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||||
String moduleName = apiModuleService.getNode(apiDefinition.getModuleId()).getName();
|
String moduleName = "";
|
||||||
|
if(apiDefinition.getModuleId() != null) { // module_id 可能为空
|
||||||
|
moduleName = apiModuleService.getNode(apiDefinition.getModuleId()).getName();
|
||||||
|
}
|
||||||
swaggerApiInfo.setTags(Arrays.asList(moduleName));
|
swaggerApiInfo.setTags(Arrays.asList(moduleName));
|
||||||
// 设置请求体
|
// 设置请求体
|
||||||
JSONObject requestObject = JSON.parseObject(apiDefinition.getRequest()); // 将api的request属性转换成JSON对象以便获得参数
|
JSONObject requestObject = JSON.parseObject(apiDefinition.getRequest()); // 将api的request属性转换成JSON对象以便获得参数
|
||||||
JSONObject requestBody = buildRequestBody(requestObject);
|
JSONObject requestBody = buildRequestBody(requestObject);
|
||||||
swaggerApiInfo.setRequestBody(requestBody);
|
swaggerApiInfo.setRequestBody(requestBody);
|
||||||
|
// 设置响应体
|
||||||
|
swaggerApiInfo.setResponses(new JSONObject());
|
||||||
// 设置请求参数列表
|
// 设置请求参数列表
|
||||||
List<JSONObject> paramsList = buildParameters(requestObject);
|
List<JSONObject> paramsList = buildParameters(requestObject);
|
||||||
swaggerApiInfo.setParameters(paramsList);
|
swaggerApiInfo.setParameters(paramsList);
|
||||||
swaggerPath.put(apiDefinition.getMethod().toLowerCase(), JSON.parseObject(JSON.toJSONString(swaggerApiInfo))); // 设置api的请求类型和api定义、参数
|
JSONObject methodDetail = JSON.parseObject(JSON.toJSONString(swaggerApiInfo));
|
||||||
paths.put(apiDefinition.getPath(), swaggerPath);
|
if(paths.getJSONObject(apiDefinition.getPath()) == null) {
|
||||||
|
paths.put(apiDefinition.getPath(), new JSONObject());
|
||||||
|
} // 一个路径下有多个发方法,如post,get,因此是一个 JSONObject 类型
|
||||||
|
paths.getJSONObject(apiDefinition.getPath()).put(apiDefinition.getMethod().toLowerCase(), methodDetail);
|
||||||
}
|
}
|
||||||
result.setPaths(paths);
|
result.setPaths(paths);
|
||||||
return result;
|
return result;
|
||||||
|
@ -477,7 +488,9 @@ public class Swagger3Parser extends SwaggerAbstractParser {
|
||||||
schema.put("format", null);
|
schema.put("format", null);
|
||||||
typeName.put("schema", schema);
|
typeName.put("schema", schema);
|
||||||
JSONObject content = new JSONObject();
|
JSONObject content = new JSONObject();
|
||||||
|
if (type != null && StringUtils.isNotBlank(type)) {
|
||||||
content.put(typeMap.get(type), typeName);
|
content.put(typeMap.get(type), typeName);
|
||||||
|
}
|
||||||
requestBody.put("content", content);
|
requestBody.put("content", content);
|
||||||
return requestBody;
|
return requestBody;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,4 +14,5 @@ public class SwaggerApiInfo {
|
||||||
private String summary; // 对应 API 的名字
|
private String summary; // 对应 API 的名字
|
||||||
private List<JSONObject> parameters; // 对应 API 的请求参数
|
private List<JSONObject> parameters; // 对应 API 的请求参数
|
||||||
private JSONObject requestBody;
|
private JSONObject requestBody;
|
||||||
|
private JSONObject responses;
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class MsScenario extends MsTestElement {
|
||||||
if (arguments != null) {
|
if (arguments != null) {
|
||||||
tree.add(config.valueSupposeMock(arguments));
|
tree.add(config.valueSupposeMock(arguments));
|
||||||
}
|
}
|
||||||
this.addCsvDataSet(tree, variables);
|
this.addCsvDataSet(tree, variables,config);
|
||||||
this.addCounter(tree, variables);
|
this.addCounter(tree, variables);
|
||||||
this.addRandom(tree, variables);
|
this.addRandom(tree, variables);
|
||||||
if (CollectionUtils.isNotEmpty(this.headers)) {
|
if (CollectionUtils.isNotEmpty(this.headers)) {
|
||||||
|
|
|
@ -201,7 +201,7 @@ public abstract class MsTestElement {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addCsvDataSet(HashTree tree, List<ScenarioVariable> variables) {
|
protected void addCsvDataSet(HashTree tree, List<ScenarioVariable> variables,ParameterConfig config) {
|
||||||
if (CollectionUtils.isNotEmpty(variables)) {
|
if (CollectionUtils.isNotEmpty(variables)) {
|
||||||
List<ScenarioVariable> list = variables.stream().filter(ScenarioVariable::isCSVValid).collect(Collectors.toList());
|
List<ScenarioVariable> list = variables.stream().filter(ScenarioVariable::isCSVValid).collect(Collectors.toList());
|
||||||
if (CollectionUtils.isNotEmpty(list)) {
|
if (CollectionUtils.isNotEmpty(list)) {
|
||||||
|
@ -213,7 +213,7 @@ public abstract class MsTestElement {
|
||||||
csvDataSet.setName(StringUtils.isEmpty(item.getName()) ? "CSVDataSet" : item.getName());
|
csvDataSet.setName(StringUtils.isEmpty(item.getName()) ? "CSVDataSet" : item.getName());
|
||||||
csvDataSet.setProperty("fileEncoding", StringUtils.isEmpty(item.getEncoding()) ? "UTF-8" : item.getEncoding());
|
csvDataSet.setProperty("fileEncoding", StringUtils.isEmpty(item.getEncoding()) ? "UTF-8" : item.getEncoding());
|
||||||
if (CollectionUtils.isNotEmpty(item.getFiles())) {
|
if (CollectionUtils.isNotEmpty(item.getFiles())) {
|
||||||
if (new File(BODY_FILE_DIR + "/" + item.getFiles().get(0).getId() + "_" + item.getFiles().get(0).getName()).exists()) {
|
if (!config.isOperating() && new File(BODY_FILE_DIR + "/" + item.getFiles().get(0).getId() + "_" + item.getFiles().get(0).getName()).exists()) {
|
||||||
MSException.throwException(StringUtils.isEmpty(item.getName()) ? "CSVDataSet" : item.getName() + ":[ CSV文件不存在 ]");
|
MSException.throwException(StringUtils.isEmpty(item.getName()) ? "CSVDataSet" : item.getName() + ":[ CSV文件不存在 ]");
|
||||||
}
|
}
|
||||||
csvDataSet.setProperty("filename", BODY_FILE_DIR + "/" + item.getFiles().get(0).getId() + "_" + item.getFiles().get(0).getName());
|
csvDataSet.setProperty("filename", BODY_FILE_DIR + "/" + item.getFiles().get(0).getId() + "_" + item.getFiles().get(0).getName());
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class MsLoopController extends MsTestElement {
|
||||||
}
|
}
|
||||||
final HashTree groupTree = controller(tree);
|
final HashTree groupTree = controller(tree);
|
||||||
if (CollectionUtils.isNotEmpty(config.getVariables())) {
|
if (CollectionUtils.isNotEmpty(config.getVariables())) {
|
||||||
this.addCsvDataSet(groupTree, config.getVariables());
|
this.addCsvDataSet(groupTree, config.getVariables(),config);
|
||||||
this.addCounter(groupTree, config.getVariables());
|
this.addCounter(groupTree, config.getVariables());
|
||||||
this.addRandom(groupTree, config.getVariables());
|
this.addRandom(groupTree, config.getVariables());
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,9 @@ public class MsTCPSampler extends MsTestElement {
|
||||||
this.setProjectId(config.getProjectId());
|
this.setProjectId(config.getProjectId());
|
||||||
config.setConfig(getEnvironmentConfig(useEnvironment));
|
config.setConfig(getEnvironmentConfig(useEnvironment));
|
||||||
}
|
}
|
||||||
|
if(config.getConfig()!=null){
|
||||||
parseEnvironment(config.getConfig().get(this.projectId));
|
parseEnvironment(config.getConfig().get(this.projectId));
|
||||||
|
}
|
||||||
|
|
||||||
// 添加环境中的公共变量
|
// 添加环境中的公共变量
|
||||||
Arguments arguments = this.addArguments(config);
|
Arguments arguments = this.addArguments(config);
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class MsJmeterElement extends MsTestElement {
|
||||||
LogUtil.info(((ThreadGroup) scriptWrapper).getName() + "是被禁用线程组不加入执行");
|
LogUtil.info(((ThreadGroup) scriptWrapper).getName() + "是被禁用线程组不加入执行");
|
||||||
} else {
|
} else {
|
||||||
// CSV数据检查文件路径是否还存在
|
// CSV数据检查文件路径是否还存在
|
||||||
if (scriptWrapper instanceof CSVDataSet) {
|
if (!config.isOperating() && scriptWrapper instanceof CSVDataSet) {
|
||||||
String path = ((CSVDataSet) scriptWrapper).getPropertyAsString("filename");
|
String path = ((CSVDataSet) scriptWrapper).getPropertyAsString("filename");
|
||||||
if (!new File(path).exists()) {
|
if (!new File(path).exists()) {
|
||||||
MSException.throwException(StringUtils.isEmpty(((CSVDataSet) scriptWrapper).getName()) ? "CSVDataSet" : ((CSVDataSet) scriptWrapper).getName() + ":[ CSV文件不存在 ]");
|
MSException.throwException(StringUtils.isEmpty(((CSVDataSet) scriptWrapper).getName()) ? "CSVDataSet" : ((CSVDataSet) scriptWrapper).getName() + ":[ CSV文件不存在 ]");
|
||||||
|
|
|
@ -20,4 +20,5 @@ public class ApiDocumentRequest {
|
||||||
private String type;
|
private String type;
|
||||||
private String orderCondition;
|
private String orderCondition;
|
||||||
private List<String> apiIdList;
|
private List<String> apiIdList;
|
||||||
|
private boolean trashEnable;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import io.metersphere.api.service.*;
|
||||||
import io.metersphere.base.domain.ApiDefinitionExecResult;
|
import io.metersphere.base.domain.ApiDefinitionExecResult;
|
||||||
import io.metersphere.base.domain.ApiScenarioReport;
|
import io.metersphere.base.domain.ApiScenarioReport;
|
||||||
import io.metersphere.base.domain.ApiTestReport;
|
import io.metersphere.base.domain.ApiTestReport;
|
||||||
import io.metersphere.base.domain.TestPlanReport;
|
|
||||||
import io.metersphere.commons.constants.*;
|
import io.metersphere.commons.constants.*;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
@ -15,7 +14,6 @@ import io.metersphere.notice.sender.NoticeModel;
|
||||||
import io.metersphere.notice.service.NoticeSendService;
|
import io.metersphere.notice.service.NoticeSendService;
|
||||||
import io.metersphere.service.SystemParameterService;
|
import io.metersphere.service.SystemParameterService;
|
||||||
import io.metersphere.track.service.TestPlanReportService;
|
import io.metersphere.track.service.TestPlanReportService;
|
||||||
import io.metersphere.track.service.TestPlanService;
|
|
||||||
import io.metersphere.track.service.TestPlanTestCaseService;
|
import io.metersphere.track.service.TestPlanTestCaseService;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -206,7 +204,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
} else {
|
} else {
|
||||||
apiDefinitionExecResultService.saveApiResult(testResult, ApiRunMode.API_PLAN.name());
|
apiDefinitionExecResultService.saveApiResult(testResult, ApiRunMode.API_PLAN.name());
|
||||||
}
|
}
|
||||||
} else if (StringUtils.equalsAny(this.runMode, ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name())) {
|
} else if (StringUtils.equalsAny(this.runMode, ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),ApiRunMode.SCHEDULE_SCENARIO.name())) {
|
||||||
// 执行报告不需要存储,由用户确认后在存储
|
// 执行报告不需要存储,由用户确认后在存储
|
||||||
testResult.setTestId(testId);
|
testResult.setTestId(testId);
|
||||||
ApiScenarioReport scenarioReport = apiScenarioReportService.complete(testResult, this.runMode);
|
ApiScenarioReport scenarioReport = apiScenarioReportService.complete(testResult, this.runMode);
|
||||||
|
|
|
@ -269,6 +269,9 @@ public class ApiAutomationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteApiScenarioReport(List<String> scenarioIds) {
|
private void deleteApiScenarioReport(List<String> scenarioIds) {
|
||||||
|
if(scenarioIds == null || scenarioIds.isEmpty()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
ApiScenarioReportExample scenarioReportExample = new ApiScenarioReportExample();
|
ApiScenarioReportExample scenarioReportExample = new ApiScenarioReportExample();
|
||||||
scenarioReportExample.createCriteria().andScenarioIdIn(scenarioIds);
|
scenarioReportExample.createCriteria().andScenarioIdIn(scenarioIds);
|
||||||
List<ApiScenarioReport> list = apiScenarioReportMapper.selectByExample(scenarioReportExample);
|
List<ApiScenarioReport> list = apiScenarioReportMapper.selectByExample(scenarioReportExample);
|
||||||
|
|
|
@ -792,7 +792,7 @@ public class ApiDefinitionService {
|
||||||
res.setCaseStatus("-");
|
res.setCaseStatus("-");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.equals("ESB", res.getMethod())) {
|
if (StringUtils.equalsIgnoreCase("esb", res.getMethod())) {
|
||||||
esbApiParamService.handleApiEsbParams(res);
|
esbApiParamService.handleApiEsbParams(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,8 +85,10 @@ public class ApiTestCaseService {
|
||||||
List<ApiTestCaseResult> returnList = extApiTestCaseMapper.list(request);
|
List<ApiTestCaseResult> returnList = extApiTestCaseMapper.list(request);
|
||||||
|
|
||||||
for (ApiTestCaseResult res : returnList) {
|
for (ApiTestCaseResult res : returnList) {
|
||||||
|
if(StringUtils.equalsIgnoreCase(res.getApiMethod(),"esb")){
|
||||||
esbApiParamService.handleApiEsbParams(res);
|
esbApiParamService.handleApiEsbParams(res);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return returnList;
|
return returnList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,9 +147,14 @@ public class ApiTestCaseService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApiTestCaseWithBLOBs get(String id) {
|
public ApiTestCaseWithBLOBs get(String id) {
|
||||||
ApiTestCaseWithBLOBs returnBlobs = apiTestCaseMapper.selectByPrimaryKey(id);
|
// ApiTestCaseWithBLOBs returnBlobs = apiTestCaseMapper.selectByPrimaryKey(id);
|
||||||
esbApiParamService.handleApiEsbParams(returnBlobs);
|
ApiTestCaseInfo model = extApiTestCaseMapper.selectApiCaseInfoByPrimaryKey(id);
|
||||||
return returnBlobs;
|
if(model != null ){
|
||||||
|
if(StringUtils.equalsIgnoreCase(model.getApiMethod(),"esb")){
|
||||||
|
esbApiParamService.handleApiEsbParams(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApiTestCase create(SaveApiTestCaseRequest request, List<MultipartFile> bodyFiles) {
|
public ApiTestCase create(SaveApiTestCaseRequest request, List<MultipartFile> bodyFiles) {
|
||||||
|
@ -440,10 +447,12 @@ public class ApiTestCaseService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getRequest(ApiTestCaseRequest request) {
|
public Map<String, String> getRequest(ApiTestCaseRequest request) {
|
||||||
List<ApiTestCaseWithBLOBs> list = extApiTestCaseMapper.getRequest(request);
|
List<ApiTestCaseInfo> list = extApiTestCaseMapper.getRequest(request);
|
||||||
for (ApiTestCaseWithBLOBs model : list) {
|
for (ApiTestCaseInfo model : list) {
|
||||||
|
if(StringUtils.equalsIgnoreCase(model.getApiMethod(),"esb")){
|
||||||
esbApiParamService.handleApiEsbParams(model);
|
esbApiParamService.handleApiEsbParams(model);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return list.stream().collect(Collectors.toMap(ApiTestCaseWithBLOBs::getId, ApiTestCaseWithBLOBs::getRequest));
|
return list.stream().collect(Collectors.toMap(ApiTestCaseWithBLOBs::getId, ApiTestCaseWithBLOBs::getRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,9 @@ public class EsbApiParamService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleApiEsbParams(ApiDefinitionResult res) {
|
public void handleApiEsbParams(ApiDefinitionResult res) {
|
||||||
|
if(res == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
EsbApiParamsWithBLOBs esbParamBlobs = this.getEsbParamBLOBsByResourceID(res.getId());
|
EsbApiParamsWithBLOBs esbParamBlobs = this.getEsbParamBLOBsByResourceID(res.getId());
|
||||||
if (esbParamBlobs == null) {
|
if (esbParamBlobs == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -141,6 +144,9 @@ public class EsbApiParamService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleApiEsbParams(ApiTestCaseWithBLOBs res) {
|
public void handleApiEsbParams(ApiTestCaseWithBLOBs res) {
|
||||||
|
if(res==null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
EsbApiParamsWithBLOBs esbParamBlobs = this.getEsbParamBLOBsByResourceID(res.getId());
|
EsbApiParamsWithBLOBs esbParamBlobs = this.getEsbParamBLOBsByResourceID(res.getId());
|
||||||
if (esbParamBlobs == null) {
|
if (esbParamBlobs == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -184,6 +190,9 @@ public class EsbApiParamService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleApiEsbParams(ApiTestCaseResult res) {
|
public void handleApiEsbParams(ApiTestCaseResult res) {
|
||||||
|
if(res == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
EsbApiParamsWithBLOBs esbParamBlobs = this.getEsbParamBLOBsByResourceID(res.getId());
|
EsbApiParamsWithBLOBs esbParamBlobs = this.getEsbParamBLOBsByResourceID(res.getId());
|
||||||
if (esbParamBlobs == null) {
|
if (esbParamBlobs == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -195,20 +204,6 @@ public class EsbApiParamService {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// try {
|
|
||||||
// if (StringUtils.isNotEmpty(res.getRequest())) {
|
|
||||||
// JSONObject jsonObj = JSONObject.parseObject(res.getRequest());
|
|
||||||
// JSONArray esbDataArray = JSONArray.parseArray(esbParamBlobs.getDataStruct());
|
|
||||||
// jsonObj.put("esbDataStruct", esbDataArray);
|
|
||||||
// jsonObj.put("esbFrontedScript", esbParamBlobs.getFrontedScript());
|
|
||||||
//
|
|
||||||
// JSONArray responseDataArray = JSONArray.parseArray(esbParamBlobs.getResponseDataStruct());
|
|
||||||
// jsonObj.put("backEsbDataStruct", responseDataArray);
|
|
||||||
//
|
|
||||||
// res.setRequest(jsonObj.toJSONString());
|
|
||||||
// }
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SaveApiDefinitionRequest updateEsbRequest(SaveApiDefinitionRequest request) {
|
public SaveApiDefinitionRequest updateEsbRequest(SaveApiDefinitionRequest request) {
|
||||||
|
|
|
@ -2,7 +2,13 @@
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="io.metersphere.base.mapper.ext.ExtApiDocumentMapper">
|
<mapper namespace="io.metersphere.base.mapper.ext.ExtApiDocumentMapper">
|
||||||
<select id="findApiDocumentSimpleInfoByRequest" resultType="io.metersphere.api.dto.document.ApiDocumentInfoDTO">
|
<select id="findApiDocumentSimpleInfoByRequest" resultType="io.metersphere.api.dto.document.ApiDocumentInfoDTO">
|
||||||
SELECT api.id,api.name FROM Api_definition api WHERE api.protocol = 'HTTP' AND api.status != 'Trash'
|
SELECT api.id,api.name FROM Api_definition api WHERE api.protocol = 'HTTP'
|
||||||
|
<if test="request.trashEnable == true">
|
||||||
|
AND api.status = 'Trash'
|
||||||
|
</if>
|
||||||
|
<if test="request.trashEnable == false">
|
||||||
|
AND api.status != 'Trash'
|
||||||
|
</if>
|
||||||
<if test="request.projectId != null">
|
<if test="request.projectId != null">
|
||||||
AND api.project_Id = #{request.projectId}
|
AND api.project_Id = #{request.projectId}
|
||||||
</if>
|
</if>
|
||||||
|
|
|
@ -2,16 +2,13 @@ package io.metersphere.base.mapper.ext;
|
||||||
|
|
||||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
||||||
|
import io.metersphere.api.dto.definition.ApiTestCaseInfo;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseResult;
|
import io.metersphere.api.dto.definition.ApiTestCaseResult;
|
||||||
import io.metersphere.base.domain.ApiTestCase;
|
import io.metersphere.base.domain.ApiTestCase;
|
||||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
|
||||||
import org.apache.ibatis.annotations.MapKey;
|
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.apache.ibatis.annotations.Select;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public interface ExtApiTestCaseMapper {
|
public interface ExtApiTestCaseMapper {
|
||||||
|
|
||||||
|
@ -27,7 +24,9 @@ public interface ExtApiTestCaseMapper {
|
||||||
|
|
||||||
long countByProjectIDAndCreateInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
|
long countByProjectIDAndCreateInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
|
||||||
|
|
||||||
List<ApiTestCaseWithBLOBs> getRequest(@Param("request") ApiTestCaseRequest request);
|
List<ApiTestCaseInfo> getRequest(@Param("request") ApiTestCaseRequest request);
|
||||||
|
|
||||||
ApiTestCase getNextNum(@Param("definitionId") String definitionId);
|
ApiTestCase getNextNum(@Param("definitionId") String definitionId);
|
||||||
|
|
||||||
|
ApiTestCaseInfo selectApiCaseInfoByPrimaryKey(String id);
|
||||||
}
|
}
|
|
@ -196,13 +196,25 @@
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectApiCaseInfoByPrimaryKey" resultType="io.metersphere.api.dto.definition.ApiTestCaseInfo">
|
||||||
|
SELECT
|
||||||
|
t1.*,
|
||||||
|
a.method AS apiMethod
|
||||||
|
FROM
|
||||||
|
api_test_case t1
|
||||||
|
inner join api_definition a on t1.api_definition_id = a.id
|
||||||
|
WHERE t1.id = #{0}
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="list" resultType="io.metersphere.api.dto.definition.ApiTestCaseResult">
|
<select id="list" resultType="io.metersphere.api.dto.definition.ApiTestCaseResult">
|
||||||
SELECT
|
SELECT
|
||||||
t1.*,
|
t1.*,
|
||||||
t2.STATUS AS execResult,
|
t2.STATUS AS execResult,
|
||||||
t2.create_time AS execTime,
|
t2.create_time AS execTime,
|
||||||
u2.NAME AS createUser,
|
u2.NAME AS createUser,
|
||||||
u1.NAME AS updateUser
|
u1.NAME AS updateUser,
|
||||||
|
a.method AS apiMethod
|
||||||
FROM
|
FROM
|
||||||
api_test_case t1
|
api_test_case t1
|
||||||
LEFT JOIN api_definition_exec_result t2 ON t1.last_result_id = t2.id
|
LEFT JOIN api_definition_exec_result t2 ON t1.last_result_id = t2.id
|
||||||
|
@ -361,15 +373,16 @@
|
||||||
AND testCase.create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
|
AND testCase.create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="getRequest" resultType="io.metersphere.base.domain.ApiTestCaseWithBLOBs">
|
<select id="getRequest" resultType="io.metersphere.api.dto.definition.ApiTestCaseInfo">
|
||||||
select id, request
|
select t1.id, t1.request,a.method AS apiMethod
|
||||||
from api_test_case
|
from api_test_case t1
|
||||||
|
inner join api_definition a on t1.api_definition_id = a.id
|
||||||
where 1
|
where 1
|
||||||
<if test="request.id != null and request.id!=''">
|
<if test="request.id != null and request.id!=''">
|
||||||
and id = #{request.id}
|
and t1.id = #{request.id}
|
||||||
</if>
|
</if>
|
||||||
<if test="request.ids != null and request.ids.size() > 0">
|
<if test="request.ids != null and request.ids.size() > 0">
|
||||||
and id in
|
and t1.id in
|
||||||
<foreach collection="request.ids" item="caseId" separator="," open="(" close=")">
|
<foreach collection="request.ids" item="caseId" separator="," open="(" close=")">
|
||||||
#{caseId}
|
#{caseId}
|
||||||
</foreach>
|
</foreach>
|
||||||
|
|
|
@ -148,5 +148,6 @@
|
||||||
<if test="request.name!=null">
|
<if test="request.name!=null">
|
||||||
AND file_metadata.name LIKE CONCAT('%', #{request.name}, '%')
|
AND file_metadata.name LIKE CONCAT('%', #{request.name}, '%')
|
||||||
</if>
|
</if>
|
||||||
|
order by update_time DESC
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
|
@ -1,5 +1,5 @@
|
||||||
package io.metersphere.commons.constants;
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
public enum ApiRunMode {
|
public enum ApiRunMode {
|
||||||
RUN, DEBUG, DEFINITION, SCENARIO, API_PLAN, JENKINS_API_PLAN, JENKINS, SCENARIO_PLAN, API, SCHEDULE_API_PLAN, SCHEDULE_SCENARIO_PLAN, SCHEDULE_PERFORMANCE_TEST
|
RUN, DEBUG, DEFINITION, SCENARIO, API_PLAN, JENKINS_API_PLAN, JENKINS, SCENARIO_PLAN, API, SCHEDULE_API_PLAN, SCHEDULE_SCENARIO,SCHEDULE_SCENARIO_PLAN, SCHEDULE_PERFORMANCE_TEST
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ public class ShiroUtils {
|
||||||
public static void loadBaseFilterChain(Map<String, String> filterChainDefinitionMap){
|
public static void loadBaseFilterChain(Map<String, String> filterChainDefinitionMap){
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/resource/**", "anon");
|
filterChainDefinitionMap.put("/resource/**", "anon");
|
||||||
|
filterChainDefinitionMap.put("/*.worker.js", "anon");
|
||||||
filterChainDefinitionMap.put("/login", "anon");
|
filterChainDefinitionMap.put("/login", "anon");
|
||||||
filterChainDefinitionMap.put("/signin", "anon");
|
filterChainDefinitionMap.put("/signin", "anon");
|
||||||
filterChainDefinitionMap.put("/ldap/signin", "anon");
|
filterChainDefinitionMap.put("/ldap/signin", "anon");
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.job.sechedule;
|
||||||
import io.metersphere.api.dto.automation.ExecuteType;
|
import io.metersphere.api.dto.automation.ExecuteType;
|
||||||
import io.metersphere.api.dto.automation.RunScenarioRequest;
|
import io.metersphere.api.dto.automation.RunScenarioRequest;
|
||||||
import io.metersphere.api.service.ApiAutomationService;
|
import io.metersphere.api.service.ApiAutomationService;
|
||||||
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.constants.ReportTriggerMode;
|
import io.metersphere.commons.constants.ReportTriggerMode;
|
||||||
import io.metersphere.commons.constants.ScheduleGroup;
|
import io.metersphere.commons.constants.ScheduleGroup;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
@ -58,6 +59,7 @@ public class ApiScenarioTestJob extends MsScheduleJob {
|
||||||
request.setExecuteType(ExecuteType.Saved.name());
|
request.setExecuteType(ExecuteType.Saved.name());
|
||||||
request.setIds(this.scenarioIds);
|
request.setIds(this.scenarioIds);
|
||||||
request.setReportUserID(this.userId);
|
request.setReportUserID(this.userId);
|
||||||
|
request.setRunMode(ApiRunMode.SCHEDULE_SCENARIO.name());
|
||||||
|
|
||||||
apiAutomationService.run(request);
|
apiAutomationService.run(request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package io.metersphere.service;
|
package io.metersphere.service;
|
||||||
|
|
||||||
import com.alibaba.excel.EasyExcelFactory;
|
import com.alibaba.excel.EasyExcelFactory;
|
||||||
import io.metersphere.api.dto.automation.ApiScenarioRequest;
|
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.*;
|
import io.metersphere.base.mapper.*;
|
||||||
import io.metersphere.base.mapper.ext.ExtOrganizationMapper;
|
import io.metersphere.base.mapper.ext.ExtOrganizationMapper;
|
||||||
|
@ -10,7 +9,10 @@ import io.metersphere.base.mapper.ext.ExtUserRoleMapper;
|
||||||
import io.metersphere.commons.constants.*;
|
import io.metersphere.commons.constants.*;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.user.SessionUser;
|
import io.metersphere.commons.user.SessionUser;
|
||||||
import io.metersphere.commons.utils.*;
|
import io.metersphere.commons.utils.CodingUtil;
|
||||||
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.controller.ResultHolder;
|
import io.metersphere.controller.ResultHolder;
|
||||||
import io.metersphere.controller.request.LoginRequest;
|
import io.metersphere.controller.request.LoginRequest;
|
||||||
import io.metersphere.controller.request.member.AddMemberRequest;
|
import io.metersphere.controller.request.member.AddMemberRequest;
|
||||||
|
@ -26,20 +28,16 @@ import io.metersphere.dto.UserRoleDTO;
|
||||||
import io.metersphere.dto.WorkspaceDTO;
|
import io.metersphere.dto.WorkspaceDTO;
|
||||||
import io.metersphere.excel.domain.*;
|
import io.metersphere.excel.domain.*;
|
||||||
import io.metersphere.excel.listener.EasyExcelListener;
|
import io.metersphere.excel.listener.EasyExcelListener;
|
||||||
import io.metersphere.excel.listener.TestCaseDataListener;
|
|
||||||
import io.metersphere.excel.listener.UserDataListener;
|
import io.metersphere.excel.listener.UserDataListener;
|
||||||
import io.metersphere.excel.utils.EasyExcelExporter;
|
import io.metersphere.excel.utils.EasyExcelExporter;
|
||||||
import io.metersphere.i18n.Translator;
|
import io.metersphere.i18n.Translator;
|
||||||
import io.metersphere.notice.domain.UserDetail;
|
import io.metersphere.notice.domain.UserDetail;
|
||||||
import io.metersphere.security.MsUserToken;
|
import io.metersphere.security.MsUserToken;
|
||||||
import io.metersphere.track.request.testcase.QueryTestCaseRequest;
|
|
||||||
import io.metersphere.xmind.XmindCaseParser;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.authc.*;
|
import org.apache.shiro.authc.*;
|
||||||
import org.apache.shiro.authz.UnauthorizedException;
|
import org.apache.shiro.authz.UnauthorizedException;
|
||||||
import org.apache.shiro.subject.Subject;
|
import org.apache.shiro.subject.Subject;
|
||||||
import org.python.antlr.ast.Str;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
@ -648,6 +646,8 @@ public class UserService {
|
||||||
UserExcelData data = new UserExcelData();
|
UserExcelData data = new UserExcelData();
|
||||||
data.setId("user_id_" + i);
|
data.setId("user_id_" + i);
|
||||||
data.setName(Translator.get("user") + i);
|
data.setName(Translator.get("user") + i);
|
||||||
|
data.setPassword(Translator.get("required")+";"+Translator.get("password_format_is_incorrect"));
|
||||||
|
data.setEmail(Translator.get("required"));
|
||||||
String workspace = "";
|
String workspace = "";
|
||||||
for (int workspaceIndex = 1; workspaceIndex <= i; workspaceIndex++) {
|
for (int workspaceIndex = 1; workspaceIndex <= i; workspaceIndex++) {
|
||||||
if (workspaceIndex == 1) {
|
if (workspaceIndex == 1) {
|
||||||
|
|
|
@ -611,6 +611,9 @@ public class TestPlanService {
|
||||||
|
|
||||||
List<ReportComponent> components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan);
|
List<ReportComponent> components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan);
|
||||||
List<Issues> issues = buildFunctionalCaseReport(planId, components);
|
List<Issues> issues = buildFunctionalCaseReport(planId, components);
|
||||||
|
buildApiCaseReport(planId, components);
|
||||||
|
buildScenarioCaseReport(planId, components);
|
||||||
|
buildLoadCaseReport(planId, components);
|
||||||
|
|
||||||
TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO();
|
TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO();
|
||||||
components.forEach(component -> {
|
components.forEach(component -> {
|
||||||
|
|
|
@ -192,3 +192,6 @@ CREATE TABLE IF NOT EXISTS test_case_test
|
||||||
|
|
||||||
alter table test_case
|
alter table test_case
|
||||||
modify test_id varchar(2000) null;
|
modify test_id varchar(2000) null;
|
||||||
|
|
||||||
|
-- update history data
|
||||||
|
update test_case set review_status = 'Prepare' where review_status is null;
|
|
@ -59,5 +59,7 @@ module_created_automatically=
|
||||||
options=
|
options=
|
||||||
options_yes=
|
options_yes=
|
||||||
options_no=
|
options_no=
|
||||||
|
required=
|
||||||
|
password_format_is_incorrect=
|
||||||
please_input_workspace_member=
|
please_input_workspace_member=
|
||||||
test_case_report_template_repeat=
|
test_case_report_template_repeat=
|
|
@ -138,6 +138,8 @@ module_created_automatically=If there is no such module, will be created automat
|
||||||
options=options
|
options=options
|
||||||
options_yes=Yes
|
options_yes=Yes
|
||||||
options_no=No
|
options_no=No
|
||||||
|
required=Required
|
||||||
|
password_format_is_incorrect=Valid password: 8-30 digits, English upper and lower case letters + numbers + special characters (optional)
|
||||||
please_input_workspace_member=Please input workspace merber
|
please_input_workspace_member=Please input workspace merber
|
||||||
test_case_report_template_repeat=The workspace has the same name template
|
test_case_report_template_repeat=The workspace has the same name template
|
||||||
plan_name_already_exists=Test plan name already exists
|
plan_name_already_exists=Test plan name already exists
|
||||||
|
|
|
@ -138,6 +138,8 @@ module_created_automatically=若无该模块将自动创建
|
||||||
options=选项
|
options=选项
|
||||||
options_yes=是
|
options_yes=是
|
||||||
options_no=否
|
options_no=否
|
||||||
|
required=必填
|
||||||
|
password_format_is_incorrect=有效密码:8-30位,英文大小写字母+数字+特殊字符(可选)
|
||||||
please_input_workspace_member=请填写该工作空间相关人员
|
please_input_workspace_member=请填写该工作空间相关人员
|
||||||
test_case_report_template_repeat=同一工作空间下不能存在同名模版
|
test_case_report_template_repeat=同一工作空间下不能存在同名模版
|
||||||
plan_name_already_exists=测试计划名称已存在
|
plan_name_already_exists=测试计划名称已存在
|
||||||
|
|
|
@ -138,6 +138,8 @@ module_created_automatically=若無該模塊將自動創建
|
||||||
options=選項
|
options=選項
|
||||||
options_yes=是
|
options_yes=是
|
||||||
options_no=否
|
options_no=否
|
||||||
|
required=必填
|
||||||
|
password_format_is_incorrect=有效密碼:8-30位,英文大小寫字母+數字+特殊字符(可選)
|
||||||
please_input_workspace_member=請填寫該工作空間相關人員
|
please_input_workspace_member=請填寫該工作空間相關人員
|
||||||
test_case_report_template_repeat=同壹工作空間下不能存在同名模版
|
test_case_report_template_repeat=同壹工作空間下不能存在同名模版
|
||||||
plan_name_already_exists=測試計劃名稱已存在
|
plan_name_already_exists=測試計劃名稱已存在
|
||||||
|
|
|
@ -22,14 +22,22 @@
|
||||||
"el-table-infinite-scroll": "^1.0.10",
|
"el-table-infinite-scroll": "^1.0.10",
|
||||||
"el-tree-transfer": "^2.4.7",
|
"el-tree-transfer": "^2.4.7",
|
||||||
"element-ui": "^2.13.0",
|
"element-ui": "^2.13.0",
|
||||||
"generate-schema": "^2.6.0",
|
|
||||||
"html2canvas": "^1.0.0-rc.7",
|
"html2canvas": "^1.0.0-rc.7",
|
||||||
"js-base64": "^3.4.4",
|
"js-base64": "^3.4.4",
|
||||||
|
"jsencrypt": "^3.1.0",
|
||||||
"json-bigint": "^1.0.0",
|
"json-bigint": "^1.0.0",
|
||||||
"json-schema-faker": "^0.5.0-rcv.32",
|
"json-schema-faker": "^0.5.0-rcv.32",
|
||||||
"json5": "^2.1.3",
|
"json5": "^2.1.3",
|
||||||
"jsoneditor": "^9.1.2",
|
"jsoneditor": "^9.1.2",
|
||||||
|
"jsonpath": "^1.1.0",
|
||||||
"jspdf": "^2.1.1",
|
"jspdf": "^2.1.1",
|
||||||
|
"lodash.isboolean": "^3.0.3",
|
||||||
|
"lodash.isempty": "^4.4.0",
|
||||||
|
"lodash.isinteger": "^4.0.4",
|
||||||
|
"lodash.isnull": "^3.0.0",
|
||||||
|
"lodash.isnumber": "^3.0.3",
|
||||||
|
"lodash.isobject": "^3.0.2",
|
||||||
|
"lodash.isstring": "^4.0.1",
|
||||||
"md5": "^2.3.0",
|
"md5": "^2.3.0",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
|
@ -41,16 +49,14 @@
|
||||||
"vue-float-action-button": "^0.6.6",
|
"vue-float-action-button": "^0.6.6",
|
||||||
"vue-i18n": "^8.15.3",
|
"vue-i18n": "^8.15.3",
|
||||||
"vue-jsonpath-picker": "^1.1.5",
|
"vue-jsonpath-picker": "^1.1.5",
|
||||||
|
"vue-minder-editor-plus": "^1.0.19",
|
||||||
"vue-papa-parse": "^2.0.0",
|
"vue-papa-parse": "^2.0.0",
|
||||||
"vue-pdf": "^4.2.0",
|
"vue-pdf": "^4.2.0",
|
||||||
"vue-router": "^3.1.3",
|
"vue-router": "^3.1.3",
|
||||||
"vuedraggable": "^2.24.3",
|
"vuedraggable": "^2.24.3",
|
||||||
"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",
|
|
||||||
"vue-minder-editor-plus": "^1.0.19",
|
|
||||||
"jsencrypt": "^3.1.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "^4.1.0",
|
"@vue/cli-plugin-babel": "^4.1.0",
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>metersphere-server</artifactId>
|
<artifactId>metersphere-server</artifactId>
|
||||||
<groupId>io.metersphere</groupId>
|
<groupId>io.metersphere</groupId>
|
||||||
<version>1.7</version>
|
<version>1.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-card class="table-card" v-loading="loading">
|
<el-card class="table-card" v-loading="result.loading">
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<ms-table-header :condition.sync="condition" @search="selectByParam" title=""
|
<ms-table-header :condition.sync="condition" @search="selectByParam" title=""
|
||||||
:show-create="false" :tip="$t('commons.search_by_id_name_tag')"/>
|
:show-create="false" :tip="$t('commons.search_by_id_name_tag')"/>
|
||||||
|
@ -218,6 +218,10 @@
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
selectNodeIds: Array,
|
selectNodeIds: Array,
|
||||||
|
selectProjectId: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
trashEnable: {
|
trashEnable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
@ -242,10 +246,10 @@
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
result: {},
|
||||||
type: API_SCENARIO_LIST,
|
type: API_SCENARIO_LIST,
|
||||||
headerItems: Api_Scenario_List,
|
headerItems: Api_Scenario_List,
|
||||||
tableLabel: Api_Scenario_List,
|
tableLabel: Api_Scenario_List,
|
||||||
loading: false,
|
|
||||||
screenHeight: document.documentElement.clientHeight - 280,//屏幕高度,
|
screenHeight: document.documentElement.clientHeight - 280,//屏幕高度,
|
||||||
condition: {
|
condition: {
|
||||||
components: API_SCENARIO_CONFIGS
|
components: API_SCENARIO_CONFIGS
|
||||||
|
@ -342,7 +346,7 @@
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
selectNodeIds() {
|
selectNodeIds() {
|
||||||
this.search();
|
this.selectProjectId ? this.search(this.selectProjectId) : this.search();
|
||||||
},
|
},
|
||||||
trashEnable() {
|
trashEnable() {
|
||||||
if (this.trashEnable) {
|
if (this.trashEnable) {
|
||||||
|
@ -354,7 +358,7 @@
|
||||||
this.search();
|
this.search();
|
||||||
},
|
},
|
||||||
batchReportId() {
|
batchReportId() {
|
||||||
this.loading = true;
|
this.result.loading = true;
|
||||||
this.getReport();
|
this.getReport();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -414,7 +418,7 @@
|
||||||
this.selectDataCounts = 0;
|
this.selectDataCounts = 0;
|
||||||
let url = "/api/automation/list/" + this.currentPage + "/" + this.pageSize;
|
let url = "/api/automation/list/" + this.currentPage + "/" + this.pageSize;
|
||||||
if (this.condition.projectId) {
|
if (this.condition.projectId) {
|
||||||
this.loading = true;
|
this.result.loading = true;
|
||||||
this.$post(url, this.condition, response => {
|
this.$post(url, this.condition, response => {
|
||||||
let data = response.data;
|
let data = response.data;
|
||||||
this.total = data.itemCount;
|
this.total = data.itemCount;
|
||||||
|
@ -424,7 +428,7 @@
|
||||||
item.tags = JSON.parse(item.tags);
|
item.tags = JSON.parse(item.tags);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.loading = false;
|
this.result.loading = false;
|
||||||
this.unSelection = data.listObject.map(s => s.id);
|
this.unSelection = data.listObject.map(s => s.id);
|
||||||
if (this.$refs.scenarioTable) {
|
if (this.$refs.scenarioTable) {
|
||||||
this.$refs.scenarioTable.doLayout()
|
this.$refs.scenarioTable.doLayout()
|
||||||
|
@ -546,13 +550,13 @@
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
this.loading = false;
|
this.result.loading = false;
|
||||||
this.$success("批量执行成功,请到报告页面查看详情!");
|
this.$success("批量执行成功,请到报告页面查看详情!");
|
||||||
} else {
|
} else {
|
||||||
setTimeout(this.getReport, 2000)
|
setTimeout(this.getReport, 2000)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.loading = false;
|
this.result.loading = false;
|
||||||
this.$error(this.$t('api_report.not_exist'));
|
this.$error(this.$t('api_report.not_exist'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -719,9 +723,9 @@
|
||||||
this.$warning(this.$t("api_test.automation.scenario.check_case"));
|
this.$warning(this.$t("api_test.automation.scenario.check_case"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.loading = true;
|
this.result.loading = true;
|
||||||
this.result = this.$post("/api/automation/export", param, response => {
|
this.result = this.$post("/api/automation/export", param, response => {
|
||||||
this.loading = false;
|
this.result.loading = false;
|
||||||
let obj = response.data;
|
let obj = response.data;
|
||||||
this.buildApiPath(obj.data);
|
this.buildApiPath(obj.data);
|
||||||
downloadFile("Metersphere_Scenario_" + localStorage.getItem(PROJECT_NAME) + ".json", JSON.stringify(obj));
|
downloadFile("Metersphere_Scenario_" + localStorage.getItem(PROJECT_NAME) + ".json", JSON.stringify(obj));
|
||||||
|
@ -734,9 +738,9 @@
|
||||||
this.$warning(this.$t("api_test.automation.scenario.check_case"));
|
this.$warning(this.$t("api_test.automation.scenario.check_case"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.loading = true;
|
this.result.loading = true;
|
||||||
this.result = this.$post("/api/automation/export/jmx", param, response => {
|
this.result = this.$post("/api/automation/export/jmx", param, response => {
|
||||||
this.loading = false;
|
this.result.loading = false;
|
||||||
let obj = response.data;
|
let obj = response.data;
|
||||||
if (obj && obj.length > 0) {
|
if (obj && obj.length > 0) {
|
||||||
obj.forEach(item => {
|
obj.forEach(item => {
|
||||||
|
|
|
@ -20,28 +20,29 @@
|
||||||
<template v-slot:append>
|
<template v-slot:append>
|
||||||
<el-dropdown v-if="!isReadOnly" size="small" split-button type="primary" class="ms-api-button" @click="handleCommand('add-api')"
|
<el-dropdown v-if="!isReadOnly" size="small" split-button type="primary" class="ms-api-button" @click="handleCommand('add-api')"
|
||||||
v-tester
|
v-tester
|
||||||
@command="handleCommand">
|
@command="handleCommand" trigger="click">
|
||||||
<el-button icon="el-icon-folder-add" @click="addScenario"></el-button>
|
<el-button icon="el-icon-folder-add" @click="addScenario"></el-button>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<el-dropdown-item command="add-scenario">{{ $t('api_test.automation.add_scenario') }}</el-dropdown-item>
|
<el-dropdown-item command="add-scenario">{{ $t('api_test.automation.add_scenario') }}</el-dropdown-item>
|
||||||
<el-dropdown-item command="import">{{ $t('api_test.api_import.label') }}</el-dropdown-item>
|
<el-dropdown-item command="import">{{ $t('api_test.api_import.label') }}</el-dropdown-item>
|
||||||
<el-dropdown-item command="export">{{ $t('report.export') }}MS</el-dropdown-item>
|
<el-dropdown-item command="exports">
|
||||||
<el-dropdown-item command="exportJmx">{{ $t('report.export') }}JMX</el-dropdown-item>
|
<el-dropdown placement="right-start" @command="chooseExportType">
|
||||||
|
<span>
|
||||||
|
{{ $t('report.export') }} <i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<template>
|
||||||
|
<el-dropdown-item command="export">{{ $t('report.export_to_ms_format') }}</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="exportJmx">{{ $t('report.export') }} JMETER 格式</el-dropdown-item>
|
||||||
|
</template>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<module-trash-button v-if="!isReadOnly" :condition="condition" :exe="enableTrash"/>
|
<module-trash-button v-if="!isReadOnly" :condition="condition" :exe="enableTrash"/>
|
||||||
<!-- 是否保留这个 -->
|
|
||||||
<!--<api-scenario-module-header-->
|
|
||||||
<!--:condition="condition"-->
|
|
||||||
<!--:current-module="currentModule"-->
|
|
||||||
<!--:is-read-only="isReadOnly"-->
|
|
||||||
<!--:project-id="projectId"-->
|
|
||||||
<!--@exportAPI="exportAPI"-->
|
|
||||||
<!--@addScenario="addScenario"-->
|
|
||||||
<!--@refreshTable="$emit('refreshTable')"-->
|
|
||||||
<!--@refresh="refresh"/>-->
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</ms-node-tree>
|
</ms-node-tree>
|
||||||
|
@ -150,6 +151,16 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
chooseExportType(e) {
|
||||||
|
switch (e) {
|
||||||
|
case "export":
|
||||||
|
this.$emit('exportAPI');
|
||||||
|
break;
|
||||||
|
case "exportJmx":
|
||||||
|
this.$emit('exportJmx');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
list(projectId) {
|
list(projectId) {
|
||||||
let url = undefined;
|
let url = undefined;
|
||||||
if (this.isPlanModel) {
|
if (this.isPlanModel) {
|
||||||
|
|
|
@ -585,7 +585,7 @@
|
||||||
arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId;
|
arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId;
|
||||||
}
|
}
|
||||||
if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) {
|
if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) {
|
||||||
this.recursiveSorting(arr[i].hashTree);
|
this.recursiveSorting(arr[i].hashTree, arr[i].projectId);
|
||||||
}
|
}
|
||||||
// 添加debug结果
|
// 添加debug结果
|
||||||
if (this.debugResult && this.debugResult.get(arr[i].id)) {
|
if (this.debugResult && this.debugResult.get(arr[i].id)) {
|
||||||
|
|
|
@ -267,8 +267,11 @@
|
||||||
open(api) {
|
open(api) {
|
||||||
if (api) {
|
if (api) {
|
||||||
let data = JSON.parse(JSON.stringify(api));
|
let data = JSON.parse(JSON.stringify(api));
|
||||||
|
if (data.protocol === "dubbo://") {
|
||||||
|
data.protocol = "DUBBO";
|
||||||
|
}
|
||||||
data.id = getUUID();
|
data.id = getUUID();
|
||||||
this.httpForm = {id: data.id, name: data.name, protocol: data.protocol, path: data.path, method: REQ_METHOD[0].id, userId: getCurrentUser().id, request: data};
|
this.httpForm = {id: data.id, name: data.name, protocol: data.protocol, path: data.path, method: api.method, userId: getCurrentUser().id, request: data};
|
||||||
this.getMaintainerOptions();
|
this.getMaintainerOptions();
|
||||||
this.list(data);
|
this.list(data);
|
||||||
this.httpVisible = true;
|
this.httpVisible = true;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
<ms-api-scenario-list
|
<ms-api-scenario-list
|
||||||
:select-node-ids="selectNodeIds"
|
:select-node-ids="selectNodeIds"
|
||||||
|
:select-project-id="projectId"
|
||||||
:referenced="true"
|
:referenced="true"
|
||||||
:trash-enable="false"
|
:trash-enable="false"
|
||||||
@selection="setData"
|
@selection="setData"
|
||||||
|
@ -131,6 +132,7 @@
|
||||||
},
|
},
|
||||||
setProject(projectId) {
|
setProject(projectId) {
|
||||||
this.projectId = projectId;
|
this.projectId = projectId;
|
||||||
|
this.selectNodeIds = [];
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
<div class="header-right" @click.stop>
|
<div class="header-right" @click.stop>
|
||||||
<slot name="message"></slot>
|
<slot name="message"></slot>
|
||||||
<el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top" v-if="showBtn">
|
<el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top" v-if="showBtn">
|
||||||
<el-switch v-model="data.enable" class="enable-switch" size="mini" :disabled="data.disabled"/>
|
<el-switch v-model="data.enable" class="enable-switch" size="mini" :disabled="data.disabled && !data.root"/>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<slot name="button"></slot>
|
<slot name="button"></slot>
|
||||||
<step-extend-btns style="display: contents" :data="data" @copy="copyRow" @remove="remove" @openScenario="openScenario" v-if="showBtn && !data.disabled"/>
|
<step-extend-btns style="display: contents" :data="data" @copy="copyRow" @remove="remove" @openScenario="openScenario" v-if="showBtn && (!data.disabled || data.root)"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -162,6 +162,7 @@
|
||||||
|
|
||||||
.script-content {
|
.script-content {
|
||||||
height: calc(100vh - 570px);
|
height: calc(100vh - 570px);
|
||||||
|
min-height: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.script-index {
|
.script-index {
|
||||||
|
|
|
@ -83,6 +83,7 @@
|
||||||
import ApiBaseComponent from "../common/ApiBaseComponent";
|
import ApiBaseComponent from "../common/ApiBaseComponent";
|
||||||
import ApiResponseComponent from "./ApiResponseComponent";
|
import ApiResponseComponent from "./ApiResponseComponent";
|
||||||
import CustomizeReqInfo from "@/business/components/api/automation/scenario/common/CustomizeReqInfo";
|
import CustomizeReqInfo from "@/business/components/api/automation/scenario/common/CustomizeReqInfo";
|
||||||
|
|
||||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||||
const esbDefinition = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinition.vue") : {};
|
const esbDefinition = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinition.vue") : {};
|
||||||
const esbDefinitionResponse = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinitionResponse.vue") : {};
|
const esbDefinitionResponse = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinitionResponse.vue") : {};
|
||||||
|
@ -245,7 +246,8 @@
|
||||||
}
|
}
|
||||||
this.request.requestResult = requestResult;
|
this.request.requestResult = requestResult;
|
||||||
this.request.id = response.data.id;
|
this.request.id = response.data.id;
|
||||||
//this.request.disabled = true;
|
this.request.disabled = true;
|
||||||
|
this.request.root = true;
|
||||||
if (!this.request.projectId) {
|
if (!this.request.projectId) {
|
||||||
this.request.projectId = response.data.projectId;
|
this.request.projectId = response.data.projectId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,7 +500,7 @@
|
||||||
arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId;
|
arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId;
|
||||||
}
|
}
|
||||||
if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) {
|
if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) {
|
||||||
this.recursiveSorting(arr[i].hashTree);
|
this.recursiveSorting(arr[i].hashTree, arr[i].projectId);
|
||||||
}
|
}
|
||||||
// 添加debug结果
|
// 添加debug结果
|
||||||
if (this.debugResult && this.debugResult.get(arr[i].id)) {
|
if (this.debugResult && this.debugResult.get(arr[i].id)) {
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
<el-tabs v-model="activeName">
|
<el-tabs v-model="activeName">
|
||||||
<el-tab-pane :label="$t('api_test.scenario.variables')" name="variable">
|
<el-tab-pane :label="$t('api_test.scenario.variables')" name="variable">
|
||||||
<div style="margin-top: 10px">
|
<div>
|
||||||
<el-row style="margin-bottom: 10px">
|
<el-row style="margin-bottom: 10px">
|
||||||
<el-col :span="8">
|
<div style="float: left">
|
||||||
<el-input placeholder="变量名称搜索" v-model="selectVariable" size="small" @change="filter"
|
<el-input placeholder="变量名称搜索" v-model="selectVariable" size="small" @change="filter"
|
||||||
@keyup.enter="filter">
|
@keyup.enter="filter">
|
||||||
<el-select v-model="searchType" slot="prepend" placeholder="类型" style="width: 90px" @change="filter">
|
<el-select v-model="searchType" slot="prepend" placeholder="类型" style="width: 90px" @change="filter">
|
||||||
|
@ -20,9 +20,9 @@
|
||||||
<el-option value="RANDOM" label="随机数"></el-option>
|
<el-option value="RANDOM" label="随机数"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-col>
|
</div>
|
||||||
|
|
||||||
<el-col :span="6">
|
<div style="float: right">
|
||||||
<el-dropdown split-button type="primary" @command="handleClick" @click="handleClick('CONSTANT')"
|
<el-dropdown split-button type="primary" @command="handleClick" @click="handleClick('CONSTANT')"
|
||||||
size="small" style="margin-left: 10px">
|
size="small" style="margin-left: 10px">
|
||||||
{{ $t('commons.add') }}
|
{{ $t('commons.add') }}
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
<el-button size="small" style="margin-left: 10px" @click="deleteVariable">{{ $t('commons.delete') }}
|
<el-button size="small" style="margin-left: 10px" @click="deleteVariable">{{ $t('commons.delete') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
</span>
|
</span>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-link class="ms-variable-link" @click="batchAdd" style="color: #783887"> {{ $t("commons.batch_add") }}
|
<el-link class="ms-variable-link" @click="batchAdd" style="color: #783887" :disabled="disabled"> {{ $t("commons.batch_add") }}
|
||||||
</el-link>
|
</el-link>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div style="min-height: 400px">
|
<div style="min-height: 400px">
|
||||||
|
@ -313,6 +313,7 @@
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: 45px;
|
margin-right: 45px;
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldset {
|
fieldset {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog :close-on-click-modal="false" width="60%" class="schedule-edit" :visible.sync="dialogVisible" :append-to-body='true'
|
<el-dialog :close-on-click-modal="false" width="60%" class="schedule-edit" :visible.sync="dialogVisible"
|
||||||
|
:append-to-body='true'
|
||||||
@close="close">
|
@close="close">
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
@ -18,12 +19,10 @@
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<schedule-switch :schedule="schedule" @scheduleChange="scheduleChange"></schedule-switch>
|
<schedule-switch :schedule="schedule" :corn-value="form.cronValue" @resultListChange="getExecuteTimeTemplate" @scheduleChange="scheduleChange"></schedule-switch>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-link :disabled="isReadOnly" type="primary" @click="showCronDialog">
|
<el-link :disabled="isReadOnly" type="primary" @click="showCronDialog">
|
||||||
|
@ -66,7 +65,13 @@ const noticeTemplate = requireComponent.keys().length > 0 ? requireComponent("./
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsScheduleMaintain",
|
name: "MsScheduleMaintain",
|
||||||
components: {CrontabResult, ScheduleSwitch,Crontab, MsScheduleNotification, "NoticeTemplate": noticeTemplate.default},
|
components: {
|
||||||
|
CrontabResult,
|
||||||
|
ScheduleSwitch,
|
||||||
|
Crontab,
|
||||||
|
MsScheduleNotification,
|
||||||
|
"NoticeTemplate": noticeTemplate.default
|
||||||
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
customValidate: {
|
customValidate: {
|
||||||
|
@ -143,8 +148,7 @@ export default {
|
||||||
this.updateTask(param);
|
this.updateTask(param);
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.updateTask(param);
|
this.updateTask(param);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -297,7 +301,9 @@ export default {
|
||||||
let time2 = new Date(resultList[1]);
|
let time2 = new Date(resultList[1]);
|
||||||
return time2 - time1;
|
return time2 - time1;
|
||||||
},
|
},
|
||||||
|
getExecuteTimeTemplate(executeTileArr){
|
||||||
|
alert(executeTileArr);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isTesterPermission() {
|
isTesterPermission() {
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
<i class="el-icon-date" size="small"></i>
|
<i class="el-icon-date" size="small"></i>
|
||||||
<span class="character">SCHEDULER</span>
|
<span class="character">SCHEDULER</span>
|
||||||
</span>
|
</span>
|
||||||
<!-- <el-switch :disabled="!schedule.value || isReadOnly" v-model="schedule.enable" @change="scheduleChange"/>-->
|
|
||||||
<!-- <el-switch :disabled="!schedule.value || isReadOnly" v-model="schedule.enable" />-->
|
|
||||||
<el-switch :disabled="!schedule.value" v-model="schedule.enable" @change="scheduleChange"/>
|
<el-switch :disabled="!schedule.value" v-model="schedule.enable" @change="scheduleChange"/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -14,7 +12,7 @@
|
||||||
{{ $t('schedule.next_execution_time') }}:
|
{{ $t('schedule.next_execution_time') }}:
|
||||||
<span :class="{'disable-character': !schedule.enable}"
|
<span :class="{'disable-character': !schedule.enable}"
|
||||||
v-if="!schedule.enable">{{ $t('schedule.not_set') }}</span>
|
v-if="!schedule.enable">{{ $t('schedule.not_set') }}</span>
|
||||||
<crontab-result v-if="schedule.enable" :enable-simple-mode="true" :ex="schedule.value" ref="crontabResult"/>
|
<crontab-result v-if="schedule.enable" :enable-simple-mode="true" :ex="cornValue" ref="crontabResult"/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,6 +31,7 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
testId: String,
|
testId: String,
|
||||||
schedule: Object,
|
schedule: Object,
|
||||||
|
cornValue:String,
|
||||||
isReadOnly: {
|
isReadOnly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
<api-documents-page class="api-doc-page"
|
<api-documents-page class="api-doc-page"
|
||||||
v-if="activeDom==='right'"
|
v-if="activeDom==='right'"
|
||||||
:project-id="projectId"
|
:project-id="projectId"
|
||||||
|
:trash-enable="trashEnable"
|
||||||
:module-ids="selectNodeIds"/>
|
:module-ids="selectNodeIds"/>
|
||||||
</ms-tab-button>
|
</ms-tab-button>
|
||||||
<!-- 添加/编辑测试窗口-->
|
<!-- 添加/编辑测试窗口-->
|
||||||
|
@ -81,13 +82,13 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- 快捷调试 -->
|
<!-- 快捷调试 -->
|
||||||
<div v-else-if="item.type=== 'debug'" class="ms-api-div">
|
<div v-else-if="item.type=== 'debug'" class="ms-api-div">
|
||||||
<ms-debug-http-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi"
|
<ms-debug-http-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi" @refreshModule="refreshModule"
|
||||||
v-if="currentProtocol==='HTTP'"/>
|
v-if="currentProtocol==='HTTP'"/>
|
||||||
<ms-debug-jdbc-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi"
|
<ms-debug-jdbc-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi" @refreshModule="refreshModule"
|
||||||
v-if="currentProtocol==='SQL'"/>
|
v-if="currentProtocol==='SQL'"/>
|
||||||
<ms-debug-tcp-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi"
|
<ms-debug-tcp-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi" @refreshModule="refreshModule"
|
||||||
v-if="currentProtocol==='TCP'"/>
|
v-if="currentProtocol==='TCP'"/>
|
||||||
<ms-debug-dubbo-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi"
|
<ms-debug-dubbo-page :currentProtocol="currentProtocol" :testCase="item.api" @saveAs="editApi" @refreshModule="refreshModule"
|
||||||
v-if="currentProtocol==='DUBBO'"/>
|
v-if="currentProtocol==='DUBBO'"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -356,6 +357,9 @@
|
||||||
}
|
}
|
||||||
this.$refs.apiList[0].exportApi(type);
|
this.$refs.apiList[0].exportApi(type);
|
||||||
},
|
},
|
||||||
|
refreshModule() {
|
||||||
|
this.$refs.nodeTree.list();
|
||||||
|
},
|
||||||
refresh(data) {
|
refresh(data) {
|
||||||
this.$refs.apiList[0].initTable(data);
|
this.$refs.apiList[0].initTable(data);
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
{{ description }}
|
{{ description }}
|
||||||
</span>
|
</span>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-checkbox v-model="isSelectAll" v-if="items.length > 1"/>
|
<el-checkbox v-model="isSelectAll" v-if="isShowEnable === true && items.length > 1"/>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="kv-row item" v-for="(item, index) in items" :key="index">
|
<div class="kv-row item" v-for="(item, index) in items" :key="index">
|
||||||
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
||||||
|
@ -52,7 +52,6 @@
|
||||||
valuePlaceholder: String,
|
valuePlaceholder: String,
|
||||||
isShowEnable: {
|
isShowEnable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
|
||||||
},
|
},
|
||||||
description: String,
|
description: String,
|
||||||
items: Array,
|
items: Array,
|
||||||
|
|
|
@ -278,6 +278,7 @@
|
||||||
let url = '/api/module/getModuleByName/' + getCurrentProjectID() + "/" + this.api.protocol;
|
let url = '/api/module/getModuleByName/' + getCurrentProjectID() + "/" + this.api.protocol;
|
||||||
this.$get(url, response => {
|
this.$get(url, response => {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
|
this.$emit('refreshModule');
|
||||||
this.saveApi(row, response.data);
|
this.saveApi(row, response.data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -332,6 +333,10 @@
|
||||||
row.id = data.id;
|
row.id = data.id;
|
||||||
row.createTime = data.createTime;
|
row.createTime = data.createTime;
|
||||||
row.updateTime = data.updateTime;
|
row.updateTime = data.updateTime;
|
||||||
|
if (!row.message) {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.$emit('refresh');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
saveTestCase(row) {
|
saveTestCase(row) {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<api-case-item v-loading="singleLoading && singleRunId === item.id || batchLoadingIds.indexOf(item.id) > -1"
|
<api-case-item v-loading="singleLoading && singleRunId === item.id || batchLoadingIds.indexOf(item.id) > -1"
|
||||||
@refresh="refresh"
|
@refresh="refresh"
|
||||||
@singleRun="singleRun"
|
@singleRun="singleRun"
|
||||||
|
@refreshModule="refreshModule"
|
||||||
@copyCase="copyCase"
|
@copyCase="copyCase"
|
||||||
@showExecResult="showExecResult"
|
@showExecResult="showExecResult"
|
||||||
@batchEditCase="batchEditCase"
|
@batchEditCase="batchEditCase"
|
||||||
|
@ -181,7 +182,9 @@
|
||||||
this.apiCaseList = [];
|
this.apiCaseList = [];
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
},
|
},
|
||||||
|
refreshModule(){
|
||||||
|
this.$emit('refreshModule');
|
||||||
|
},
|
||||||
runRefresh() {
|
runRefresh() {
|
||||||
this.batchLoadingIds = [];
|
this.batchLoadingIds = [];
|
||||||
this.singleLoading = false;
|
this.singleLoading = false;
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<el-button style="float: right;margin: 20px" type="primary" @click="handleCommand('save_as_api')"> {{$t('commons.save')}}</el-button>
|
<el-button style="float: right;margin: 20px" type="primary" @click="handleCommand('save_as_api')"> {{$t('commons.save')}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
<!-- 加载用例 -->
|
<!-- 加载用例 -->
|
||||||
<ms-api-case-list :loaded="false" ref="caseList"/>
|
<ms-api-case-list @refreshModule="refreshModule" :loaded="false" ref="caseList"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -122,7 +122,9 @@ export default {
|
||||||
this.runDebug();
|
this.runDebug();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
refreshModule() {
|
||||||
|
this.$emit('refreshModule');
|
||||||
|
},
|
||||||
runDebug() {
|
runDebug() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.request.name = getUUID().substring(0, 8);
|
this.request.name = getUUID().substring(0, 8);
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
<el-button style="float: right;margin: 20px" type="primary" @click="handleCommand('save_as_api')"> {{$t('commons.save')}}</el-button>
|
<el-button style="float: right;margin: 20px" type="primary" @click="handleCommand('save_as_api')"> {{$t('commons.save')}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
<!-- 加载用例 -->
|
<!-- 加载用例 -->
|
||||||
<ms-api-case-list :loaded="false" ref="caseList"/>
|
<ms-api-case-list @refreshModule="refreshModule" :loaded="false" ref="caseList"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -166,6 +166,9 @@ export default {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
refreshModule() {
|
||||||
|
this.$emit('refreshModule');
|
||||||
|
},
|
||||||
runRefresh(data) {
|
runRefresh(data) {
|
||||||
this.responseData = data;
|
this.responseData = data;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
<el-button style="float: right;margin: 20px" type="primary" @click="handleCommand('save_as_api')"> {{$t('commons.save')}}</el-button>
|
<el-button style="float: right;margin: 20px" type="primary" @click="handleCommand('save_as_api')"> {{$t('commons.save')}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
<!-- 加载用例 -->
|
<!-- 加载用例 -->
|
||||||
<ms-api-case-list :loaded="false" ref="caseList"/>
|
<ms-api-case-list @refreshModule="refreshModule" :loaded="false" ref="caseList"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -125,7 +125,9 @@ export default {
|
||||||
this.$refs['requestForm'].validate();
|
this.$refs['requestForm'].validate();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
refreshModule() {
|
||||||
|
this.$emit('refreshModule');
|
||||||
|
},
|
||||||
runDebug() {
|
runDebug() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.request.name = getUUID().substring(0, 8);
|
this.request.name = getUUID().substring(0, 8);
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<el-button style="float: right;margin: 20px" type="primary" @click="handleCommand('save_as_api')"> {{$t('commons.save')}}</el-button>
|
<el-button style="float: right;margin: 20px" type="primary" @click="handleCommand('save_as_api')"> {{$t('commons.save')}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
<!-- 加载用例 -->
|
<!-- 加载用例 -->
|
||||||
<ms-api-case-list :loaded="false" ref="caseList"/>
|
<ms-api-case-list @refreshModule="refreshModule" :loaded="false" ref="caseList"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -130,7 +130,9 @@ export default {
|
||||||
this.$refs['requestForm'].validate();
|
this.$refs['requestForm'].validate();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
refreshModule() {
|
||||||
|
this.$emit('refreshModule');
|
||||||
|
},
|
||||||
runDebug() {
|
runDebug() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.request.name = getUUID().substring(0, 8);
|
this.request.name = getUUID().substring(0, 8);
|
||||||
|
|
|
@ -369,6 +369,10 @@ export default {
|
||||||
moduleIds: Array,
|
moduleIds: Array,
|
||||||
sharePage:Boolean,
|
sharePage:Boolean,
|
||||||
pageHeaderHeight:Number,
|
pageHeaderHeight:Number,
|
||||||
|
trashEnable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
activated() {
|
activated() {
|
||||||
this.initApiDocSimpleList();
|
this.initApiDocSimpleList();
|
||||||
|
@ -409,6 +413,9 @@ export default {
|
||||||
},
|
},
|
||||||
clientHeight() { //如果clientHeight 发生改变,这个函数就会运行
|
clientHeight() { //如果clientHeight 发生改变,这个函数就会运行
|
||||||
this.changeFixed(this.clientHeight);
|
this.changeFixed(this.clientHeight);
|
||||||
|
},
|
||||||
|
trashEnable() {
|
||||||
|
this.initApiDocSimpleList();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -441,7 +448,10 @@ export default {
|
||||||
}
|
}
|
||||||
if (this.moduleIds.length > 0) {
|
if (this.moduleIds.length > 0) {
|
||||||
simpleRequest.moduleIds = this.moduleIds;
|
simpleRequest.moduleIds = this.moduleIds;
|
||||||
|
} else {
|
||||||
|
simpleRequest.moduleIds = [];
|
||||||
}
|
}
|
||||||
|
simpleRequest.trashEnable = this.trashEnable;
|
||||||
|
|
||||||
let simpleInfoUrl = "/api/document/selectApiSimpleInfo";
|
let simpleInfoUrl = "/api/document/selectApiSimpleInfo";
|
||||||
this.apiInfoArray = [];
|
this.apiInfoArray = [];
|
||||||
|
@ -533,9 +543,6 @@ export default {
|
||||||
//检查数据
|
//检查数据
|
||||||
this.checkApiInfoNode(this.apiStepIndex,true);
|
this.checkApiInfoNode(this.apiStepIndex,true);
|
||||||
},
|
},
|
||||||
stepClick(stepIndex) {
|
|
||||||
this.apiStepIndex = stepIndex;
|
|
||||||
},
|
|
||||||
getColor(enable, method) {
|
getColor(enable, method) {
|
||||||
return this.methodColorMap.get(method);
|
return this.methodColorMap.get(method);
|
||||||
},
|
},
|
||||||
|
@ -642,8 +649,6 @@ export default {
|
||||||
for(let i = 0;i<this.apiShowArray.length;i++){
|
for(let i = 0;i<this.apiShowArray.length;i++){
|
||||||
names += this.apiShowArray[i].name+";";
|
names += this.apiShowArray[i].name+";";
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("["+apiDocDivScrollTop+":"+this.apiStepIndex+"]:["+lastIndex+":"+this.currentApiIndexInApiShowArray+"]-------->"+names);
|
|
||||||
if(lastIndex < this.currentApiIndexInApiShowArray){
|
if(lastIndex < this.currentApiIndexInApiShowArray){
|
||||||
//上移
|
//上移
|
||||||
if(this.needAsyncSelect){
|
if(this.needAsyncSelect){
|
||||||
|
@ -684,10 +689,6 @@ export default {
|
||||||
}
|
}
|
||||||
this.apiStepIndex ++;
|
this.apiStepIndex ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this.apiStepIndex = lastIndex;
|
|
||||||
// //检查上下文 2个以内的节点有没有查询出来
|
|
||||||
// this.checkApiInfoNode(this.apiStepIndex);
|
|
||||||
},
|
},
|
||||||
redirectScroll(){
|
redirectScroll(){
|
||||||
//滚动条跳转:将滚动条下拉到显示对应对api接口的位置
|
//滚动条跳转:将滚动条下拉到显示对应对api接口的位置
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- <api-document-item :project-id="projectId" :module-ids="moduleIds"/>-->
|
<!-- <api-document-item :project-id="projectId" :module-ids="moduleIds"/>-->
|
||||||
<api-document-anchor :is-share-page="isSharePage" :project-id="projectId" :module-ids="moduleIds"></api-document-anchor>
|
<api-document-anchor :is-share-page="isSharePage" :trash-enable="trashEnable" :project-id="projectId" :module-ids="moduleIds"></api-document-anchor>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -23,6 +23,10 @@ export default {
|
||||||
projectId:String,
|
projectId:String,
|
||||||
moduleIds:Array,
|
moduleIds:Array,
|
||||||
activeDom:String,
|
activeDom:String,
|
||||||
|
trashEnable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
},
|
},
|
||||||
|
|
|
@ -155,6 +155,11 @@
|
||||||
created() {
|
created() {
|
||||||
this.getEnvironments();
|
this.getEnvironments();
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
projectId() {
|
||||||
|
return this.$store.state.projectId
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addPre() {
|
addPre() {
|
||||||
let jsr223PreProcessor = createComponent("JSR223PreProcessor");
|
let jsr223PreProcessor = createComponent("JSR223PreProcessor");
|
||||||
|
@ -210,7 +215,8 @@
|
||||||
|
|
||||||
getEnvironments() {
|
getEnvironments() {
|
||||||
this.environments = [];
|
this.environments = [];
|
||||||
this.$get('/api/environment/list/' + getCurrentProjectID(), response => {
|
let id = this.request.projectId ? this.request.projectId : this.projectId;
|
||||||
|
this.$get('/api/environment/list/' + id, response => {
|
||||||
this.environments = response.data;
|
this.environments = response.data;
|
||||||
this.environments.forEach(environment => {
|
this.environments.forEach(environment => {
|
||||||
parseEnvironment(environment);
|
parseEnvironment(environment);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form :model="request" :rules="rules" ref="request" label-width="100px" size="small" v-loading="loading"
|
<el-form :model="request" :rules="rules" ref="request" label-width="100px" size="small" v-loading="loading"
|
||||||
:disabled="isReadOnly">
|
:disabled="isReadOnly">
|
||||||
<el-button class="get-provider" type="primary" size="small" @click="getProviderList">Get Provider List</el-button>
|
<el-button class="get-provider" type="primary" size="mini" @click="getProviderList">Get Provider List</el-button>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="Interfaces" prop="interfaces">
|
<el-form-item label="Interfaces" prop="interfaces">
|
||||||
|
|
|
@ -8,20 +8,10 @@
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane :label="$t('api_test.definition.request.response_header')" name="headers" class="pane">
|
<el-tab-pane :label="$t('api_test.definition.request.response_header')" name="headers" class="pane">
|
||||||
<!--<div style="width: 400px">-->
|
|
||||||
<!--<pre>{{ response.responseResult.headers }}</pre>-->
|
|
||||||
<!--</div>-->
|
|
||||||
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="response.responseResult.headers"/>
|
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="response.responseResult.headers"/>
|
||||||
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!--<el-tab-pane label="Cookie" name="cookie" class="pane cookie">-->
|
|
||||||
<!--<pre>{{response.cookies}}</pre>-->
|
|
||||||
<!--</el-tab-pane>-->
|
|
||||||
|
|
||||||
<el-tab-pane :label="$t('api_test.definition.request.console')" name="console" class="pane">
|
<el-tab-pane :label="$t('api_test.definition.request.console')" name="console" class="pane">
|
||||||
<!--<div style="width: 400px">-->
|
|
||||||
<!--<pre>{{response.responseResult.console}}</pre>-->
|
|
||||||
<!--</div>-->
|
|
||||||
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="response.responseResult.console"/>
|
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="response.responseResult.console"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
|
@ -30,29 +20,10 @@
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane :label="$t('api_test.request.extract.label')" name="label" class="pane">
|
<el-tab-pane :label="$t('api_test.request.extract.label')" name="label" class="pane">
|
||||||
<!--<div style="width: 400px">-->
|
|
||||||
<!--<pre>{{response.responseResult.vars}}</pre>-->
|
|
||||||
<!--</div>-->
|
|
||||||
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="response.responseResult.vars"/>
|
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="response.responseResult.vars"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane :label="$t('api_report.request_body')" name="request_body" class="pane">
|
<el-tab-pane :label="$t('api_report.request_body')" name="request_body" class="pane">
|
||||||
<!--<div class="ms-div">-->
|
|
||||||
<!--{{$t('api_test.request.address')}} :-->
|
|
||||||
<!--<pre>{{ response.url }}</pre>-->
|
|
||||||
<!--</div>-->
|
|
||||||
<!--<div class="ms-div">-->
|
|
||||||
<!--{{$t('api_test.scenario.headers')}} :-->
|
|
||||||
<!--<pre>{{ response.headers }}</pre>-->
|
|
||||||
<!--</div>-->
|
|
||||||
<!--<div class="ms-div">-->
|
|
||||||
<!--Cookies :-->
|
|
||||||
<!--<pre>{{response.cookies}}</pre>-->
|
|
||||||
<!--</div>-->
|
|
||||||
<!--<div class="ms-div">-->
|
|
||||||
<!--Body :-->
|
|
||||||
<!--<pre>{{response.body ? response.body:""}}</pre>-->
|
|
||||||
<!--</div>-->
|
|
||||||
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="reqMessages"/>
|
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="reqMessages"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
|
|
|
@ -190,8 +190,8 @@ export default {
|
||||||
let req = this.api.request;
|
let req = this.api.request;
|
||||||
req.id = getUUID();
|
req.id = getUUID();
|
||||||
data.request = JSON.stringify(req);
|
data.request = JSON.stringify(req);
|
||||||
data.method = this.api.method;
|
data.method = req.method;
|
||||||
data.path = this.api.path;
|
data.path = req.path;
|
||||||
data.url = this.api.url;
|
data.url = this.api.url;
|
||||||
data.status = this.api.status;
|
data.status = this.api.status;
|
||||||
data.userId = this.api.userId;
|
data.userId = this.api.userId;
|
||||||
|
|
|
@ -43,16 +43,6 @@ export default {
|
||||||
name: "ApiReportView",
|
name: "ApiReportView",
|
||||||
component: () => import('@/business/components/api/report/ApiReportView'),
|
component: () => import('@/business/components/api/report/ApiReportView'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "definition/:redirectID?/:dataType?/:dataSelectRange?",
|
|
||||||
name: "ApiDefinition",
|
|
||||||
component: () => import('@/business/components/api/definition/ApiDefinition'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "automation/:redirectID?/:dataType?/:dataSelectRange?",
|
|
||||||
name: "ApiAutomation",
|
|
||||||
component: () => import('@/business/components/api/automation/ApiAutomation'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "automation/report",
|
path: "automation/report",
|
||||||
name: "ApiReportList",
|
name: "ApiReportList",
|
||||||
|
@ -64,6 +54,16 @@ export default {
|
||||||
component: () => import('@/business/components/api/automation/report/ApiReportView'),
|
component: () => import('@/business/components/api/automation/report/ApiReportView'),
|
||||||
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "definition/:redirectID?/:dataType?/:dataSelectRange?",
|
||||||
|
name: "ApiDefinition",
|
||||||
|
component: () => import('@/business/components/api/definition/ApiDefinition'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "automation/:redirectID?/:dataType?/:dataSelectRange?",
|
||||||
|
name: "ApiAutomation",
|
||||||
|
component: () => import('@/business/components/api/automation/ApiAutomation'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'monitor/view',
|
path: 'monitor/view',
|
||||||
name: 'ApiMonitor',
|
name: 'ApiMonitor',
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
<script>
|
<script>
|
||||||
import {schemaToJson} from './common';
|
import {schemaToJson} from './common';
|
||||||
import MsImportJson from './import/ImportJson';
|
import MsImportJson from './import/ImportJson';
|
||||||
|
const Convert = require('./convert/convert.js');
|
||||||
const GenerateSchema = require('generate-schema/src/schemas/json.js');
|
const MsConvert = new Convert();
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (!this.body.jsonSchema && this.body.raw && this.checkIsJson(this.body.raw)) {
|
if (!this.body.jsonSchema && this.body.raw && this.checkIsJson(this.body.raw)) {
|
||||||
let obj = {"root": GenerateSchema(JSON.parse(this.body.raw))}
|
let obj = {"root": MsConvert.format(JSON.parse(this.body.raw))}
|
||||||
this.schema = obj;
|
this.schema = obj;
|
||||||
}
|
}
|
||||||
else if (this.body.jsonSchema) {
|
else if (this.body.jsonSchema) {
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
const isBoolean = require("lodash.isboolean")
|
||||||
|
const isEmpty = require("lodash.isempty")
|
||||||
|
const isInteger = require("lodash.isinteger")
|
||||||
|
const isNull = require("lodash.isnull")
|
||||||
|
const isNumber = require("lodash.isnumber")
|
||||||
|
const isObject = require("lodash.isobject")
|
||||||
|
const isString = require("lodash.isstring")
|
||||||
|
const isArray = Array.isArray
|
||||||
|
|
||||||
|
|
||||||
|
class Convert {
|
||||||
|
constructor() {
|
||||||
|
this._option = {
|
||||||
|
$id: "http://example.com/root.json",
|
||||||
|
$schema: "http://json-schema.org/draft-07/schema#",
|
||||||
|
}
|
||||||
|
this._object = null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换函数
|
||||||
|
* @param {*} object 需要转换的对象
|
||||||
|
* @param {*} ?option 可选参数,目前只有能设置 root 节点的 $id 和 $schema
|
||||||
|
*/
|
||||||
|
format(object, option = {}) {
|
||||||
|
// 数据校验,确保传入的的object只能是对象或数组
|
||||||
|
if (!isObject(object)) {
|
||||||
|
throw new TypeError("传入参数只能是对象或数组")
|
||||||
|
}
|
||||||
|
// 合并属性
|
||||||
|
this._option = Object.assign(this._option, option)
|
||||||
|
// 需要转换的对象
|
||||||
|
this._object = object
|
||||||
|
let convertRes
|
||||||
|
// 数组类型和对象类型结构不一样
|
||||||
|
if (isArray(object)) {
|
||||||
|
convertRes = this._arrayToSchema()
|
||||||
|
} else {
|
||||||
|
convertRes = this._objectToSchema()
|
||||||
|
}
|
||||||
|
// 释放
|
||||||
|
this._object = null
|
||||||
|
return convertRes
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数组类型转换成JSONSCHEMA
|
||||||
|
*/
|
||||||
|
_arrayToSchema() {
|
||||||
|
// root节点基本信息
|
||||||
|
let result = this._value2object(this._object, this._option.$id, "", true)
|
||||||
|
if (this._object.length > 0) {
|
||||||
|
// 创建items对象的基本信息
|
||||||
|
let objectItem = this._object[0]
|
||||||
|
result["items"] = this._value2object(objectItem, `#/items`, 'items')
|
||||||
|
if (isObject(objectItem) && !isEmpty(objectItem)) {
|
||||||
|
// 递归遍历
|
||||||
|
let objectItemSchema = this._json2schema(objectItem, `#/items`)
|
||||||
|
// 合并对象
|
||||||
|
result["items"] = Object.assign(result["items"], objectItemSchema)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象类型转换成JSONSCHEMA
|
||||||
|
*/
|
||||||
|
_objectToSchema() {
|
||||||
|
let baseResult = this._value2object(this._object, this._option.$id, "", true)
|
||||||
|
let objectSchema = this._json2schema(this._object)
|
||||||
|
baseResult = Object.assign(baseResult, objectSchema)
|
||||||
|
return baseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归函数,转换object对象为json schmea 格式
|
||||||
|
* @param {*} object 需要转换对象
|
||||||
|
* @param {*} name $id值
|
||||||
|
*/
|
||||||
|
_json2schema(object, name = "") {
|
||||||
|
// 如果递归值不是对象,那么return掉
|
||||||
|
if (!isObject(object)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 处理当前路径$id
|
||||||
|
if (name === "" || name == undefined) {
|
||||||
|
name = "#"
|
||||||
|
}
|
||||||
|
let result = {};
|
||||||
|
// 判断传入object是对象还是数组。
|
||||||
|
if (isArray(object)) {
|
||||||
|
result.items = {}
|
||||||
|
} else {
|
||||||
|
result.properties = {}
|
||||||
|
}
|
||||||
|
// 遍历传入的对象
|
||||||
|
for (const key in object) {
|
||||||
|
if (object.hasOwnProperty(key)) {
|
||||||
|
const element = object[key];
|
||||||
|
// 如果只是undefined。跳过
|
||||||
|
if (element === undefined) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let $id = `${name}/properties/${key}`
|
||||||
|
// 判断当前 element 的值 是否也是对象,如果是就继续递归,不是就赋值给result
|
||||||
|
if (isObject(element)) {
|
||||||
|
// 创建当前属性的基本信息
|
||||||
|
result["properties"][key] = this._value2object(element, $id, key)
|
||||||
|
if (isArray(element)) {
|
||||||
|
// 针对空数组和有值的数组做不同处理
|
||||||
|
if (element.length > 0) {
|
||||||
|
// 如果是数组,那么就取第一项
|
||||||
|
let elementItem = element[0]
|
||||||
|
// 创建items对象的基本信息
|
||||||
|
result["properties"][key]["items"] = this._value2object(elementItem, `${$id}/items`, key + 'items')
|
||||||
|
// 判断第一项是否是对象,且对象属性不为空
|
||||||
|
if (isObject(elementItem) && !isEmpty(elementItem)) {
|
||||||
|
// 新增的properties才合并进来
|
||||||
|
result["properties"][key]["items"] = Object.assign(result["properties"][key]["items"], this._json2schema(elementItem, `${$id}/items`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 不是数组,递归遍历获取,然后合并对象属性
|
||||||
|
result["properties"][key] = Object.assign(result["properties"][key], this._json2schema(element, $id))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 一般属性直接获取基本信息
|
||||||
|
result["properties"][key] = this._value2object(element, $id, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 把json的值转换成对象类型
|
||||||
|
* @param {*} value
|
||||||
|
* @param {*} $id
|
||||||
|
* @param {*} key
|
||||||
|
*/
|
||||||
|
_value2object(value, $id, key = '', root = false) {
|
||||||
|
let objectTemplate = {
|
||||||
|
$id: $id,
|
||||||
|
title: `The ${key} Schema`,
|
||||||
|
mock: {
|
||||||
|
"mock": value
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否为初始化root数据
|
||||||
|
if (root) {
|
||||||
|
objectTemplate["$schema"] = this._option.$schema
|
||||||
|
objectTemplate["title"] = `The Root Schema`
|
||||||
|
objectTemplate["mock"] = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isInteger(value)) {
|
||||||
|
objectTemplate.type = "integer"
|
||||||
|
} else if (isNumber(value)) {
|
||||||
|
objectTemplate.type = "number"
|
||||||
|
} else if (isString(value)) {
|
||||||
|
objectTemplate.type = "string"
|
||||||
|
} else if (isBoolean(value)) {
|
||||||
|
objectTemplate.type = "boolean"
|
||||||
|
} else if (isNull(value)) {
|
||||||
|
objectTemplate.type = "null"
|
||||||
|
} else if (isArray(value)) {
|
||||||
|
objectTemplate.type = "array"
|
||||||
|
} else if (isObject(value)) {
|
||||||
|
objectTemplate.type = "object"
|
||||||
|
}
|
||||||
|
|
||||||
|
return objectTemplate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Convert
|
|
@ -36,8 +36,8 @@
|
||||||
import MsDialogFooter from '../../../common/components/MsDialogFooter'
|
import MsDialogFooter from '../../../common/components/MsDialogFooter'
|
||||||
import MsCodeEdit from "../../../common/components/MsCodeEdit";
|
import MsCodeEdit from "../../../common/components/MsCodeEdit";
|
||||||
import json5 from 'json5';
|
import json5 from 'json5';
|
||||||
|
const Convert = require('../convert/convert.js');
|
||||||
const GenerateSchema = require('generate-schema/src/schemas/json.js');
|
const MsConvert = new Convert();
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsImportJson",
|
name: "MsImportJson",
|
||||||
|
@ -93,7 +93,8 @@
|
||||||
this.$error("导入的数据非JSON格式");
|
this.$error("导入的数据非JSON格式");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let jsonData = GenerateSchema(json5.parse(this.json));
|
let jsonData = MsConvert.format(json5.parse(this.json));
|
||||||
|
//let jsonData = GenerateSchema(json5.parse(this.json));
|
||||||
this.$emit('jsonData', jsonData);
|
this.$emit('jsonData', jsonData);
|
||||||
} else {
|
} else {
|
||||||
if (!this.checkIsJsonSchema(this.jsonSchema)) {
|
if (!this.checkIsJsonSchema(this.jsonSchema)) {
|
||||||
|
|
|
@ -221,15 +221,6 @@ export default {
|
||||||
f().then(res => {
|
f().then(res => {
|
||||||
let response = res.data;
|
let response = res.data;
|
||||||
if (response.data.length === 0) {
|
if (response.data.length === 0) {
|
||||||
let type = file.name.substring(file.name.lastIndexOf(".") + 1);
|
|
||||||
|
|
||||||
this.tableData.push({
|
|
||||||
name: file.name,
|
|
||||||
size: (file.size / 1024).toFixed(2) + ' KB',
|
|
||||||
type: type.toUpperCase(),
|
|
||||||
updateTime: file.lastModified,
|
|
||||||
});
|
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
} else {
|
} else {
|
||||||
this.$error(this.$t('load_test.project_file_exist') + ', name: ' + file.name);
|
this.$error(this.$t('load_test.project_file_exist') + ', name: ' + file.name);
|
||||||
|
@ -241,21 +232,21 @@ export default {
|
||||||
|
|
||||||
let file = uploadResources.file;
|
let file = uploadResources.file;
|
||||||
this.checkFileExist(file, () => {
|
this.checkFileExist(file, () => {
|
||||||
self.uploadList.push(file);
|
let formData = new FormData();
|
||||||
let type = file.name.substring(file.name.lastIndexOf(".") + 1);
|
let url = '/project/upload/files/' + getCurrentProjectID()
|
||||||
if (type.toLowerCase() !== 'jmx') {
|
formData.append("file", file);
|
||||||
return;
|
let options = {
|
||||||
|
method: 'POST',
|
||||||
|
url: url,
|
||||||
|
data: formData,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': undefined
|
||||||
}
|
}
|
||||||
let jmxReader = new FileReader();
|
}
|
||||||
jmxReader.onload = (event) => {
|
self.$request(options, (response) => {
|
||||||
let threadGroups = findThreadGroup(event.target.result, file.name);
|
self.$success(this.$t('commons.save_success'));
|
||||||
threadGroups.forEach(tg => {
|
self.getProjectFiles();
|
||||||
tg.options = {};
|
|
||||||
self.scenarios.push(tg);
|
|
||||||
});
|
});
|
||||||
self.$emit('fileChange', self.scenarios);
|
|
||||||
};
|
|
||||||
jmxReader.readAsText(file);
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleExceed() {
|
handleExceed() {
|
||||||
|
|
|
@ -84,11 +84,13 @@ export default {
|
||||||
fileList: [],
|
fileList: [],
|
||||||
uploadList: [],
|
uploadList: [],
|
||||||
fileNumLimit: 10,
|
fileNumLimit: 10,
|
||||||
condition: {}
|
condition: {},
|
||||||
|
projectId: getCurrentProjectID(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
open() {
|
open(project) {
|
||||||
|
this.projectId = project.id;
|
||||||
this.loadFileVisible = true;
|
this.loadFileVisible = true;
|
||||||
this.getProjectFiles();
|
this.getProjectFiles();
|
||||||
},
|
},
|
||||||
|
@ -97,7 +99,7 @@ export default {
|
||||||
this.selectIds.clear();
|
this.selectIds.clear();
|
||||||
},
|
},
|
||||||
getProjectFiles() {
|
getProjectFiles() {
|
||||||
this.projectLoadingResult = this.$post('/performance/project/all/' + getCurrentProjectID() + "/" + this.currentPage + "/" + this.pageSize, this.condition, res => {
|
this.projectLoadingResult = this.$post('/performance/project/all/' + this.projectId + "/" + this.currentPage + "/" + this.pageSize, this.condition, res => {
|
||||||
let data = res.data;
|
let data = res.data;
|
||||||
this.total = data.itemCount;
|
this.total = data.itemCount;
|
||||||
this.existFiles = data.listObject;
|
this.existFiles = data.listObject;
|
||||||
|
@ -118,7 +120,7 @@ export default {
|
||||||
handleUpload(uploadResources) {
|
handleUpload(uploadResources) {
|
||||||
let file = uploadResources.file;
|
let file = uploadResources.file;
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
let url = '/project/upload/files/' + getCurrentProjectID()
|
let url = '/project/upload/files/' + this.projectId
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
let options = {
|
let options = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
|
@ -267,7 +267,14 @@
|
||||||
let lastOrganizationId = this.currentUser.lastOrganizationId;
|
let lastOrganizationId = this.currentUser.lastOrganizationId;
|
||||||
let userRole = this.currentUser.userRoles.filter(r => r.sourceId === lastOrganizationId);
|
let userRole = this.currentUser.userRoles.filter(r => r.sourceId === lastOrganizationId);
|
||||||
if (userRole.length > 0) {
|
if (userRole.length > 0) {
|
||||||
if (userRole[0].roleId === "org_admin") {
|
let isOrg_admin = false;
|
||||||
|
userRole.forEach(row=>{
|
||||||
|
if(row.roleId === "org_admin" ){
|
||||||
|
isOrg_admin = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (isOrg_admin) {
|
||||||
this.result = this.$post(url, this.condition, response => {
|
this.result = this.$post(url, this.condition, response => {
|
||||||
let data = response.data;
|
let data = response.data;
|
||||||
this.items = data.listObject;
|
this.items = data.listObject;
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="right-end"
|
placement="right-end"
|
||||||
title="示例"
|
title="示例"
|
||||||
width="400"
|
width="600"
|
||||||
trigger="click"
|
trigger="click">
|
||||||
:content="title">
|
<ms-code-edit :read-only="true" height="400px" :data.sync="title" :modes="modes" :mode="'html'"/>
|
||||||
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
||||||
{{ $t('organization.message.mail_template_example') }}
|
{{ $t('organization.message.mail_template_example') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
width="400"
|
width="400"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
:content="robotTitle">
|
:content="robotTitle">
|
||||||
|
<ms-code-edit :read-only="true" height="200px" :data.sync="robotTitle" :modes="modes" :mode="'text'"/>
|
||||||
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
||||||
{{ $t('organization.message.robot_template') }}
|
{{ $t('organization.message.robot_template') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -132,6 +133,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {hasLicense} from "@/common/js/utils";
|
import {hasLicense} from "@/common/js/utils";
|
||||||
|
import MsCodeEdit from "@/business/components/common/components/MsCodeEdit";
|
||||||
|
|
||||||
const TASK_TYPE = 'DEFECT_TASK';
|
const TASK_TYPE = 'DEFECT_TASK';
|
||||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||||
|
@ -140,6 +142,7 @@ const noticeTemplate = requireComponent.keys().length > 0 ? requireComponent("./
|
||||||
export default {
|
export default {
|
||||||
name: "DefectTaskNotification",
|
name: "DefectTaskNotification",
|
||||||
components: {
|
components: {
|
||||||
|
MsCodeEdit,
|
||||||
"NoticeTemplate": noticeTemplate.default
|
"NoticeTemplate": noticeTemplate.default
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -149,6 +152,7 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
modes: ['text', 'html'],
|
||||||
title: "<!DOCTYPE html>\n" +
|
title: "<!DOCTYPE html>\n" +
|
||||||
"<html lang=\"en\">\n" +
|
"<html lang=\"en\">\n" +
|
||||||
"<head>\n" +
|
"<head>\n" +
|
||||||
|
@ -274,6 +278,7 @@ export default {
|
||||||
.el-row {
|
.el-row {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button {
|
.el-button {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="right-end"
|
placement="right-end"
|
||||||
title="示例"
|
title="示例"
|
||||||
width="400"
|
width="600"
|
||||||
trigger="click"
|
trigger="click">
|
||||||
:content="title">
|
<ms-code-edit :read-only="true" height="400px" :data.sync="title" :modes="modes" :mode="'html'"/>
|
||||||
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
||||||
{{ $t('organization.message.mail_template_example') }}
|
{{ $t('organization.message.mail_template_example') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="right-end"
|
placement="right-end"
|
||||||
title="示例"
|
title="示例"
|
||||||
width="400"
|
width="600"
|
||||||
trigger="click"
|
trigger="click">
|
||||||
:content="robotTitle">
|
<ms-code-edit :read-only="true" height="200px" :data.sync="robotTitle" :modes="modes" :mode="'text'"/>
|
||||||
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
||||||
{{ $t('organization.message.robot_template') }}
|
{{ $t('organization.message.robot_template') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -136,6 +136,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {hasLicense} from "@/common/js/utils";
|
import {hasLicense} from "@/common/js/utils";
|
||||||
|
import MsCodeEdit from "@/business/components/common/components/MsCodeEdit";
|
||||||
|
|
||||||
const TASK_TYPE = 'JENKINS_TASK';
|
const TASK_TYPE = 'JENKINS_TASK';
|
||||||
|
|
||||||
|
@ -145,6 +146,7 @@ const noticeTemplate = requireComponent.keys().length > 0 ? requireComponent("./
|
||||||
export default {
|
export default {
|
||||||
name: "JenkinsNotification",
|
name: "JenkinsNotification",
|
||||||
components: {
|
components: {
|
||||||
|
MsCodeEdit,
|
||||||
"NoticeTemplate": noticeTemplate.default
|
"NoticeTemplate": noticeTemplate.default
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -154,6 +156,7 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
modes: ['text', 'html'],
|
||||||
title: '<!DOCTYPE html>\n' +
|
title: '<!DOCTYPE html>\n' +
|
||||||
'<html lang="en">\n' +
|
'<html lang="en">\n' +
|
||||||
'<head>\n' +
|
'<head>\n' +
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="right-end"
|
placement="right-end"
|
||||||
title="示例"
|
title="示例"
|
||||||
width="400"
|
width="600"
|
||||||
trigger="click"
|
trigger="click">
|
||||||
:content="title">
|
<ms-code-edit :read-only="true" height="400px" :data.sync="title" :modes="modes" :mode="'html'"/>
|
||||||
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
||||||
{{ $t('organization.message.mail_template_example') }}
|
{{ $t('organization.message.mail_template_example') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="right-end"
|
placement="right-end"
|
||||||
title="示例"
|
title="示例"
|
||||||
width="400"
|
width="200"
|
||||||
trigger="click"
|
trigger="click" >
|
||||||
:content="robotTitle">
|
<ms-code-edit :read-only="true" height="200px" :data.sync="robotTitle" :modes="modes" :mode="'text'"/>
|
||||||
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
||||||
{{ $t('organization.message.robot_template') }}
|
{{ $t('organization.message.robot_template') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -136,6 +136,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {hasLicense} from "@/common/js/utils";
|
import {hasLicense} from "@/common/js/utils";
|
||||||
|
import MsCodeEdit from "@/business/components/common/components/MsCodeEdit";
|
||||||
|
|
||||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||||
const noticeTemplate = requireComponent.keys().length > 0 ? requireComponent("./notice/NoticeTemplate.vue") : {};
|
const noticeTemplate = requireComponent.keys().length > 0 ? requireComponent("./notice/NoticeTemplate.vue") : {};
|
||||||
|
@ -143,6 +144,7 @@ const noticeTemplate = requireComponent.keys().length > 0 ? requireComponent("./
|
||||||
export default {
|
export default {
|
||||||
name: "ScheduleTaskNotification",
|
name: "ScheduleTaskNotification",
|
||||||
components: {
|
components: {
|
||||||
|
MsCodeEdit,
|
||||||
"NoticeTemplate": noticeTemplate.default
|
"NoticeTemplate": noticeTemplate.default
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -155,6 +157,7 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
modes: ['text', 'html'],
|
||||||
title: '<!DOCTYPE html>\n' +
|
title: '<!DOCTYPE html>\n' +
|
||||||
'<html lang="en">\n' +
|
'<html lang="en">\n' +
|
||||||
'<head>\n' +
|
'<head>\n' +
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="right-end"
|
placement="right-end"
|
||||||
title="示例"
|
title="示例"
|
||||||
width="400"
|
width="600"
|
||||||
trigger="click"
|
trigger="click">
|
||||||
:content="title">
|
<ms-code-edit :read-only="true" height="400px" :data.sync="title" :modes="modes" :mode="'html'"/>
|
||||||
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
||||||
{{ $t('organization.message.mail_template_example') }}
|
{{ $t('organization.message.mail_template_example') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="right-end"
|
placement="right-end"
|
||||||
title="示例"
|
title="示例"
|
||||||
width="400"
|
width="600"
|
||||||
trigger="click"
|
trigger="click">
|
||||||
:content="robotTitle">
|
<ms-code-edit :read-only="true" height="200px" :data.sync="robotTitle" :modes="modes" :mode="'text'"/>
|
||||||
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
||||||
{{ $t('organization.message.robot_template') }}
|
{{ $t('organization.message.robot_template') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -133,6 +133,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {hasLicense} from "@/common/js/utils";
|
import {hasLicense} from "@/common/js/utils";
|
||||||
|
import MsCodeEdit from "@/business/components/common/components/MsCodeEdit";
|
||||||
|
|
||||||
const TASK_TYPE = 'TEST_PLAN_TASK';
|
const TASK_TYPE = 'TEST_PLAN_TASK';
|
||||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||||
|
@ -141,6 +142,7 @@ const noticeTemplate = requireComponent.keys().length > 0 ? requireComponent("./
|
||||||
export default {
|
export default {
|
||||||
name: "TestPlanTaskNotification",
|
name: "TestPlanTaskNotification",
|
||||||
components: {
|
components: {
|
||||||
|
MsCodeEdit,
|
||||||
"NoticeTemplate": noticeTemplate.default
|
"NoticeTemplate": noticeTemplate.default
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -150,6 +152,7 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
modes: ['text', 'html'],
|
||||||
title: "<!DOCTYPE html>\n" +
|
title: "<!DOCTYPE html>\n" +
|
||||||
"<html lang=\"en\">\n" +
|
"<html lang=\"en\">\n" +
|
||||||
"<head>\n" +
|
"<head>\n" +
|
||||||
|
@ -308,6 +311,7 @@ export default {
|
||||||
.el-row {
|
.el-row {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button {
|
.el-button {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="right-end"
|
placement="right-end"
|
||||||
title="示例"
|
title="示例"
|
||||||
width="400"
|
width="600"
|
||||||
trigger="click"
|
trigger="click">
|
||||||
:content="title">
|
<ms-code-edit :read-only="true" height="400px" :data.sync="title" :modes="modes" :mode="'html'"/>
|
||||||
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
||||||
{{ $t('organization.message.mail_template_example') }}
|
{{ $t('organization.message.mail_template_example') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="right-end"
|
placement="right-end"
|
||||||
title="示例"
|
title="示例"
|
||||||
width="400"
|
width="600"
|
||||||
trigger="click"
|
trigger="click">
|
||||||
:content="robotTitle">
|
<ms-code-edit :read-only="true" height="200px" :data.sync="robotTitle" :modes="modes" :mode="'text'"/>
|
||||||
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
<el-button icon="el-icon-warning" plain size="mini" slot="reference">
|
||||||
{{ $t('organization.message.robot_template') }}
|
{{ $t('organization.message.robot_template') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -133,6 +133,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {hasLicense} from "@/common/js/utils";
|
import {hasLicense} from "@/common/js/utils";
|
||||||
|
import MsCodeEdit from "@/business/components/common/components/MsCodeEdit";
|
||||||
|
|
||||||
const TASK_TYPE = 'REVIEW_TASK';
|
const TASK_TYPE = 'REVIEW_TASK';
|
||||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||||
|
@ -141,6 +142,7 @@ const noticeTemplate = requireComponent.keys().length > 0 ? requireComponent("./
|
||||||
export default {
|
export default {
|
||||||
name: "TestReviewNotification",
|
name: "TestReviewNotification",
|
||||||
components: {
|
components: {
|
||||||
|
MsCodeEdit,
|
||||||
"NoticeTemplate": noticeTemplate.default
|
"NoticeTemplate": noticeTemplate.default
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -150,6 +152,7 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
modes: ['text', 'html'],
|
||||||
title: "<!DOCTYPE html>\n" +
|
title: "<!DOCTYPE html>\n" +
|
||||||
"<html lang=\"en\">\n" +
|
"<html lang=\"en\">\n" +
|
||||||
"<head>\n" +
|
"<head>\n" +
|
||||||
|
@ -313,6 +316,7 @@ export default {
|
||||||
.el-row {
|
.el-row {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button {
|
.el-button {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
<template v-slot:button>
|
<template v-slot:button>
|
||||||
<ms-table-button :is-tester-permission="true" icon="el-icon-box"
|
<ms-table-button :is-tester-permission="true" icon="el-icon-box"
|
||||||
:content="$t('api_test.jar_config.title')" @click="openJarConfig"/>
|
:content="$t('api_test.jar_config.title')" @click="openJarConfig"/>
|
||||||
<ms-table-button :is-tester-permission="true" icon="el-icon-files"
|
|
||||||
:content="$t('load_test.other_resource')" @click="openFiles"/>
|
|
||||||
</template>
|
</template>
|
||||||
</ms-table-header>
|
</ms-table-header>
|
||||||
</template>
|
</template>
|
||||||
|
@ -45,6 +43,8 @@
|
||||||
<template v-slot:behind>
|
<template v-slot:behind>
|
||||||
<ms-table-operator-button :is-tester-permission="true" :tip="$t('api_test.environment.environment_config')" icon="el-icon-setting"
|
<ms-table-operator-button :is-tester-permission="true" :tip="$t('api_test.environment.environment_config')" icon="el-icon-setting"
|
||||||
type="info" @exec="openEnvironmentConfig(scope.row)"/>
|
type="info" @exec="openEnvironmentConfig(scope.row)"/>
|
||||||
|
<ms-table-operator-button :is-tester-permission="true" :tip="$t('load_test.other_resource')" icon="el-icon-files"
|
||||||
|
type="success" @exec="openFiles(scope.row)"/>
|
||||||
</template>
|
</template>
|
||||||
</ms-table-operator>
|
</ms-table-operator>
|
||||||
</template>
|
</template>
|
||||||
|
@ -228,8 +228,8 @@ export default {
|
||||||
openJarConfig() {
|
openJarConfig() {
|
||||||
this.$refs.jarConfig.open();
|
this.$refs.jarConfig.open();
|
||||||
},
|
},
|
||||||
openFiles() {
|
openFiles(project) {
|
||||||
this.$refs.resourceFiles.open();
|
this.$refs.resourceFiles.open(project);
|
||||||
},
|
},
|
||||||
handleDelete(project) {
|
handleDelete(project) {
|
||||||
this.$refs.deleteConfirm.open(project);
|
this.$refs.deleteConfirm.open(project);
|
||||||
|
|
|
@ -2,19 +2,24 @@
|
||||||
<el-dialog class="user-casecader" :title="title" :visible.sync="dialogVisible"
|
<el-dialog class="user-casecader" :title="title" :visible.sync="dialogVisible"
|
||||||
@close="close">
|
@close="close">
|
||||||
<div class="block" >
|
<div class="block" >
|
||||||
<!-- <el-row>-->
|
|
||||||
<!-- <span class="demonstration" v-html="lable"></span>-->
|
|
||||||
<!-- </el-row>-->
|
|
||||||
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
|
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
|
||||||
<el-form-item prop="workspace" label-width="0px">
|
<el-form-item prop="workspace" label-width="0px">
|
||||||
<el-cascader
|
<!-- <el-cascader-->
|
||||||
:options="options"
|
<!-- :options="options"-->
|
||||||
|
<!-- :props="props"-->
|
||||||
|
<!-- v-model="selectedIds"-->
|
||||||
|
<!-- ref="cascaderSelector"-->
|
||||||
|
<!-- style="width:100%;"-->
|
||||||
|
<!-- :key="isResouceShow"-->
|
||||||
|
<!-- clearable></el-cascader>-->
|
||||||
|
|
||||||
|
<el-cascader-panel :options="options"
|
||||||
:props="props"
|
:props="props"
|
||||||
v-model="selectedIds"
|
v-model="selectedIds"
|
||||||
ref="cascaderSelector"
|
ref="cascaderSelector"
|
||||||
style="width:100%"
|
style="width:100%;"
|
||||||
:key="isResouceShow"
|
:key="isResouceShow"
|
||||||
clearable></el-cascader>
|
clearable></el-cascader-panel>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,7 +42,7 @@ export default {
|
||||||
components: {ElUploadList, MsTableButton,MsDialogFooter},
|
components: {ElUploadList, MsTableButton,MsDialogFooter},
|
||||||
data() {
|
data() {
|
||||||
var validateSelect = (rule, value, callback) => {
|
var validateSelect = (rule, value, callback) => {
|
||||||
let checkNodes = this.$refs.cascaderSelector.checkedNodes;
|
let checkNodes = this.$refs.cascaderSelector.getCheckedNodes(true);
|
||||||
if(checkNodes.length==0){
|
if(checkNodes.length==0){
|
||||||
callback(new Error(this.$t('workspace.select')));
|
callback(new Error(this.$t('workspace.select')));
|
||||||
}
|
}
|
||||||
|
@ -95,7 +100,7 @@ export default {
|
||||||
confirm(){
|
confirm(){
|
||||||
this.$refs.ruleForm.validate((valid) => {
|
this.$refs.ruleForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
let checkNodes = this.$refs.cascaderSelector.checkedNodes;
|
let checkNodes = this.$refs.cascaderSelector.getCheckedNodes(true);
|
||||||
let selectValueArr = [];
|
let selectValueArr = [];
|
||||||
for (let i = 0; i < checkNodes.length; i++) {
|
for (let i = 0; i < checkNodes.length; i++) {
|
||||||
selectValueArr.push(checkNodes[i].value);
|
selectValueArr.push(checkNodes[i].value);
|
||||||
|
@ -116,9 +121,19 @@ export default {
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
.user-casecader >>> .el-dialog {
|
.user-casecader >>> .el-dialog {
|
||||||
width: 400px;
|
width: 600px;
|
||||||
}
|
}
|
||||||
/deep/ .el-form-item__content{
|
/deep/ .el-form-item__content{
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
}
|
}
|
||||||
|
/*.el-cascader-menu {*/
|
||||||
|
/* height: 300px;*/
|
||||||
|
/*}*/
|
||||||
|
/*.el-cascader >>> .el-input--suffix {*/
|
||||||
|
/* max-height: 200px;*/
|
||||||
|
/*}*/
|
||||||
|
/*.el-cascader >>> .el-cascader__tags {*/
|
||||||
|
/* max-height: 190px;*/
|
||||||
|
/* overflow: auto;*/
|
||||||
|
/*}*/
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -5,9 +5,13 @@
|
||||||
|
|
||||||
<!--操作按钮-->
|
<!--操作按钮-->
|
||||||
<div class="ms-opt-btn">
|
<div class="ms-opt-btn">
|
||||||
<el-button v-if="type!='add'" id="inputDelay" type="primary" size="small" @click="saveCase" title="ctrl + s">
|
<ms-table-button v-if="type!='add'" :is-tester-permission="true"
|
||||||
{{ $t('commons.save') }}
|
id="inputDelay"
|
||||||
</el-button>
|
type="primary"
|
||||||
|
:content="$t('commons.save')"
|
||||||
|
size="small" @click="saveCase"
|
||||||
|
icon=""
|
||||||
|
title="ctrl + s"/>
|
||||||
<el-dropdown v-else split-button type="primary" class="ms-api-buttion" @click="handleCommand"
|
<el-dropdown v-else split-button type="primary" class="ms-api-buttion" @click="handleCommand"
|
||||||
@command="handleCommand" size="small" style="float: right;margin-right: 20px">
|
@command="handleCommand" size="small" style="float: right;margin-right: 20px">
|
||||||
{{ $t('commons.save') }}
|
{{ $t('commons.save') }}
|
||||||
|
@ -58,14 +62,14 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="7">
|
<!-- <el-col :span="7">-->
|
||||||
<el-form-item label="评审状态" :label-width="formLabelWidth" prop="reviewStatus">
|
<!-- <el-form-item label="评审状态" :label-width="formLabelWidth" prop="reviewStatus">-->
|
||||||
<el-select size="small" v-model="form.reviewStatus" class="ms-case-input">
|
<!-- <el-select size="small" v-model="form.reviewStatus" class="ms-case-input">-->
|
||||||
<el-option v-for="item in options" :key="item.id" :label="item.label" :value="item.id">
|
<!-- <el-option v-for="item in options" :key="item.id" :label="item.label" :value="item.id">-->
|
||||||
</el-option>
|
<!-- </el-option>-->
|
||||||
</el-select>
|
<!-- </el-select>-->
|
||||||
</el-form-item>
|
<!-- </el-form-item>-->
|
||||||
</el-col>
|
<!-- </el-col>-->
|
||||||
<el-col :span="7">
|
<el-col :span="7">
|
||||||
<el-form-item :label="$t('commons.tag')" :label-width="formLabelWidth" prop="tag">
|
<el-form-item :label="$t('commons.tag')" :label-width="formLabelWidth" prop="tag">
|
||||||
<ms-input-tag :currentScenario="form" v-if="showInputTag" ref="tag" class="ms-case-input"/>
|
<ms-input-tag :currentScenario="form" v-if="showInputTag" ref="tag" class="ms-case-input"/>
|
||||||
|
@ -84,8 +88,6 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="7">
|
<el-col :span="7">
|
||||||
<el-form-item :label="$t('test_track.case.priority')" :label-width="formLabelWidth" prop="priority">
|
<el-form-item :label="$t('test_track.case.priority')" :label-width="formLabelWidth" prop="priority">
|
||||||
<el-select :disabled="readOnly" v-model="form.priority" clearable
|
<el-select :disabled="readOnly" v-model="form.priority" clearable
|
||||||
|
@ -97,16 +99,17 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="14">
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
<el-col :span="7">
|
||||||
<el-form-item :label="$t('test_track.case.relate_test')" :label-width="formLabelWidth">
|
<el-form-item :label="$t('test_track.case.relate_test')" :label-width="formLabelWidth">
|
||||||
<el-cascader filterable placeholder="请选择要关联的测试" show-all-levels v-model="form.selected" :props="props"
|
<el-cascader :options="sysList" filterable placeholder="请选择要关联的测试" show-all-levels
|
||||||
class="ms-case"></el-cascader>
|
v-model="form.selected" :props="props"
|
||||||
|
class="ms-case" @change="clearInput" ref="cascade"></el-cascader>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
<el-col :span="7">
|
||||||
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="10">
|
|
||||||
<el-form-item label="关联需求" :label-width="formLabelWidth" prop="demandId">
|
<el-form-item label="关联需求" :label-width="formLabelWidth" prop="demandId">
|
||||||
<el-select filterable :disabled="readOnly" v-model="form.demandId" @visible-change="visibleChange"
|
<el-select filterable :disabled="readOnly" v-model="form.demandId" @visible-change="visibleChange"
|
||||||
placeholder="请选择要关联的需求" class="ms-case-input">
|
placeholder="请选择要关联的需求" class="ms-case-input">
|
||||||
|
@ -120,7 +123,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="10" :offset="1">
|
<el-col :span="7">
|
||||||
<el-form-item label="需求ID/名称" :label-width="formLabelWidth" prop="demandName"
|
<el-form-item label="需求ID/名称" :label-width="formLabelWidth" prop="demandName"
|
||||||
v-if="form.demandId=='other'">
|
v-if="form.demandId=='other'">
|
||||||
<el-input v-model="form.demandName"></el-input>
|
<el-input v-model="form.demandName"></el-input>
|
||||||
|
@ -286,7 +289,7 @@
|
||||||
<script>
|
<script>
|
||||||
import {TokenKey, WORKSPACE_ID} from '@/common/js/constants';
|
import {TokenKey, WORKSPACE_ID} from '@/common/js/constants';
|
||||||
import MsDialogFooter from '../../../common/components/MsDialogFooter'
|
import MsDialogFooter from '../../../common/components/MsDialogFooter'
|
||||||
import {getCurrentUser, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
import {getCurrentUser, handleCtrlSEvent, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||||
import {Message} from "element-ui";
|
import {Message} from "element-ui";
|
||||||
import TestCaseAttachment from "@/business/components/track/case/components/TestCaseAttachment";
|
import TestCaseAttachment from "@/business/components/track/case/components/TestCaseAttachment";
|
||||||
import {buildNodePath} from "../../../api/definition/model/NodeTree";
|
import {buildNodePath} from "../../../api/definition/model/NodeTree";
|
||||||
|
@ -297,10 +300,12 @@ import {ELEMENTS} from "@/business/components/api/automation/scenario/Setting";
|
||||||
import TestCaseComment from "@/business/components/track/case/components/TestCaseComment";
|
import TestCaseComment from "@/business/components/track/case/components/TestCaseComment";
|
||||||
import ReviewCommentItem from "@/business/components/track/review/commom/ReviewCommentItem";
|
import ReviewCommentItem from "@/business/components/track/review/commom/ReviewCommentItem";
|
||||||
import {API_STATUS, REVIEW_STATUS, TEST} from "@/business/components/api/definition/model/JsonData";
|
import {API_STATUS, REVIEW_STATUS, TEST} from "@/business/components/api/definition/model/JsonData";
|
||||||
|
import MsTableButton from "@/business/components/common/components/MsTableButton";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "TestCaseEdit",
|
name: "TestCaseEdit",
|
||||||
components: {
|
components: {
|
||||||
|
MsTableButton,
|
||||||
|
|
||||||
ReviewCommentItem,
|
ReviewCommentItem,
|
||||||
TestCaseComment, MsPreviousNextButton, MsInputTag, CaseComment, MsDialogFooter, TestCaseAttachment
|
TestCaseComment, MsPreviousNextButton, MsInputTag, CaseComment, MsDialogFooter, TestCaseAttachment
|
||||||
|
@ -309,43 +314,10 @@ export default {
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
multiple: true,
|
multiple: true,
|
||||||
lazy: true,
|
//lazy: true,
|
||||||
lazyLoad: ((node, resolve) => {
|
//lazyLoad:this.lazyLoad
|
||||||
const { level } = node;
|
|
||||||
if(node.level==0){
|
|
||||||
const nodes = TEST
|
|
||||||
.map(item => ({
|
|
||||||
value: item.id,
|
|
||||||
label: item.name,
|
|
||||||
leaf: level >= 1
|
|
||||||
}));
|
|
||||||
resolve(nodes)
|
|
||||||
}
|
|
||||||
if(node.level==1){
|
|
||||||
this.testOptions = [];
|
|
||||||
let url = '';
|
|
||||||
this.form.type=node.data.value
|
|
||||||
if (this.form.type === 'testcase' || this.form.type === 'automation') {
|
|
||||||
url = '/api/' + this.form.type + '/list/' + this.projectId
|
|
||||||
} else if (this.form.type === 'performance' || this.form.type === 'api') {
|
|
||||||
url = '/' + this.form.type + '/list/' + this.projectId
|
|
||||||
}
|
|
||||||
if (this.projectId && this.form.type != '' && this.form.type != 'undefined') {
|
|
||||||
this.$get(url, response => {
|
|
||||||
const nodes = response.data
|
|
||||||
.map(item => ({
|
|
||||||
value: item.id,
|
|
||||||
label: item.name,
|
|
||||||
leaf: level >= 1
|
|
||||||
}));
|
|
||||||
resolve(nodes)
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
|
sysList: [],//一级选择框的数据
|
||||||
options: REVIEW_STATUS,
|
options: REVIEW_STATUS,
|
||||||
statuOptions: API_STATUS,
|
statuOptions: API_STATUS,
|
||||||
comments: [],
|
comments: [],
|
||||||
|
@ -389,6 +361,7 @@ export default {
|
||||||
{max: 255, message: this.$t('test_track.length_less_than') + '255', trigger: 'blur'}
|
{max: 255, message: this.$t('test_track.length_less_than') + '255', trigger: 'blur'}
|
||||||
],
|
],
|
||||||
module: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
|
module: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
|
||||||
|
demandName: [{required: true, message: this.$t('test_track.case.input_demand_name'), trigger: 'change'}],
|
||||||
maintainer: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
maintainer: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||||
priority: [{required: true, message: this.$t('test_track.case.input_priority'), trigger: 'change'}],
|
priority: [{required: true, message: this.$t('test_track.case.input_priority'), trigger: 'change'}],
|
||||||
method: [{required: true, message: this.$t('test_track.case.input_method'), trigger: 'change'}],
|
method: [{required: true, message: this.$t('test_track.case.input_method'), trigger: 'change'}],
|
||||||
|
@ -430,7 +403,7 @@ export default {
|
||||||
type: String
|
type: String
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
projectId() {
|
projectIds() {
|
||||||
return this.$store.state.projectId
|
return this.$store.state.projectId
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -456,8 +429,88 @@ export default {
|
||||||
this.$emit('setModuleOptions', this.moduleOptions);
|
this.$emit('setModuleOptions', this.moduleOptions);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
this.loadOptions();
|
||||||
|
this.addListener(); // 添加 ctrl s 监听
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
clearInput() {
|
||||||
|
//this.$refs['cascade'].panel.clearCheckedNodes()
|
||||||
|
},
|
||||||
|
async loadOptions(sysLib) {
|
||||||
|
sysLib = TEST
|
||||||
|
.map(item => ({
|
||||||
|
value: item.id,
|
||||||
|
label: item.name,
|
||||||
|
}));
|
||||||
|
let array = [];
|
||||||
|
for (let i = 0; i < sysLib.length; i++) {
|
||||||
|
if (sysLib.length > 0) {
|
||||||
|
let res = await this.getTestOptions(sysLib[i].value);
|
||||||
|
sysLib[i].children = res;
|
||||||
|
}
|
||||||
|
array.push(sysLib[i]);
|
||||||
|
}
|
||||||
|
this.sysList = array;
|
||||||
|
},
|
||||||
|
getTestOptions(val) {
|
||||||
|
this.form.type = val
|
||||||
|
this.projectId = this.projectIds
|
||||||
|
this.testOptions = [];
|
||||||
|
let url = '';
|
||||||
|
if (this.form.type === 'testcase' || this.form.type === 'automation') {
|
||||||
|
url = '/api/' + this.form.type + '/list/' + this.projectId
|
||||||
|
} else if (this.form.type === 'performance' || this.form.type === 'api') {
|
||||||
|
url = '/' + this.form.type + '/list/' + this.projectId
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.$get(url).then(res => {
|
||||||
|
console.log(res.data.data)
|
||||||
|
const data = res.data.data.map(item => ({
|
||||||
|
value: item.id,
|
||||||
|
label: item.name,
|
||||||
|
leaf: true
|
||||||
|
}))
|
||||||
|
resolve(data)
|
||||||
|
}).catch((err) => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/* lazyLoad(node, resolve){
|
||||||
|
const { level } = node;
|
||||||
|
if(node.level==0){
|
||||||
|
const nodes = TEST
|
||||||
|
.map(item => ({
|
||||||
|
value: item.id,
|
||||||
|
label: item.name,
|
||||||
|
leaf: level >= 1
|
||||||
|
}));
|
||||||
|
resolve(nodes)
|
||||||
|
}
|
||||||
|
if(node.level==1){
|
||||||
|
this.projectId = getCurrentProjectID()
|
||||||
|
this.testOptions = [];
|
||||||
|
let url = '';
|
||||||
|
this.form.type=node.data.value
|
||||||
|
if (this.form.type === 'testcase' || this.form.type === 'automation') {
|
||||||
|
url = '/api/' + this.form.type + '/list/' + this.projectId
|
||||||
|
} else if (this.form.type === 'performance' || this.form.type === 'api') {
|
||||||
|
url = '/' + this.form.type + '/list/' + this.projectId
|
||||||
|
}
|
||||||
|
if (this.projectId && this.form.type != '' && this.form.type != 'undefined') {
|
||||||
|
this.$get(url, response => {
|
||||||
|
const nodes = response.data
|
||||||
|
.map(item => ({
|
||||||
|
value: item.id,
|
||||||
|
label: item.name,
|
||||||
|
leaf: level >= 1
|
||||||
|
}));
|
||||||
|
resolve(nodes)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},*/
|
||||||
handleCommand(e) {
|
handleCommand(e) {
|
||||||
if (e === "ADD_AND_CREATE") {
|
if (e === "ADD_AND_CREATE") {
|
||||||
this.$refs['caseFrom'].validate((valid) => {
|
this.$refs['caseFrom'].validate((valid) => {
|
||||||
|
@ -467,7 +520,8 @@ export default {
|
||||||
this.saveCase();
|
this.saveCase();
|
||||||
let tab = {}
|
let tab = {}
|
||||||
tab.name = 'add'
|
tab.name = 'add'
|
||||||
this.$emit('addTab',tab)}
|
this.$emit('addTab', tab)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.saveCase();
|
this.saveCase();
|
||||||
|
@ -499,6 +553,10 @@ export default {
|
||||||
this.$nextTick(() => (this.isStepTableAlive = true));
|
this.$nextTick(() => (this.isStepTableAlive = true));
|
||||||
},
|
},
|
||||||
open(testCase) {
|
open(testCase) {
|
||||||
|
/*
|
||||||
|
this.form.selected=[["automation", "3edaaf31-3fa4-4a53-9654-320205c2953a"],["automation", "3aa58bd1-c986-448c-8060-d32713dbd4eb"]]
|
||||||
|
*/
|
||||||
|
this.projectId = this.projectIds;
|
||||||
if (window.history && window.history.pushState) {
|
if (window.history && window.history.pushState) {
|
||||||
history.pushState(null, null, document.URL);
|
history.pushState(null, null, document.URL);
|
||||||
window.addEventListener('popstate', this.close);
|
window.addEventListener('popstate', this.close);
|
||||||
|
@ -570,7 +628,7 @@ export default {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setFormData(testCase) {
|
async setFormData(testCase) {
|
||||||
testCase.tags = JSON.parse(testCase.tags);
|
testCase.tags = JSON.parse(testCase.tags);
|
||||||
testCase.selected = JSON.parse(testCase.testId);
|
testCase.selected = JSON.parse(testCase.testId);
|
||||||
let tmp = {};
|
let tmp = {};
|
||||||
|
@ -580,11 +638,12 @@ export default {
|
||||||
tmp.steps = []
|
tmp.steps = []
|
||||||
}
|
}
|
||||||
Object.assign(this.form, tmp);
|
Object.assign(this.form, tmp);
|
||||||
|
console.log(this.form.selected)
|
||||||
this.form.module = testCase.nodeId;
|
this.form.module = testCase.nodeId;
|
||||||
/*
|
|
||||||
this.form.testId=testCase.selected
|
|
||||||
*/
|
|
||||||
this.getFileMetaData(testCase);
|
this.getFileMetaData(testCase);
|
||||||
|
/* testCase.selected = JSON.parse(testCase.testId);
|
||||||
|
this.form.selected= testCase.selected*/
|
||||||
|
await this.loadOptions(this.sysList)
|
||||||
},
|
},
|
||||||
setTestCaseExtInfo(testCase) {
|
setTestCaseExtInfo(testCase) {
|
||||||
this.testCase = {};
|
this.testCase = {};
|
||||||
|
@ -782,21 +841,7 @@ export default {
|
||||||
this.maintainerOptions = response.data;
|
this.maintainerOptions = response.data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getTestOptions(val) {
|
|
||||||
this.testOptions = [];
|
|
||||||
let url = '';
|
|
||||||
if (this.form.type === 'testcase' || this.form.type === 'automation') {
|
|
||||||
url = '/api/' + this.form.type + '/list/' + this.projectId
|
|
||||||
} else if (this.form.type === 'performance' || this.form.type === 'api') {
|
|
||||||
url = '/' + this.form.type + '/list/' + this.projectId
|
|
||||||
}
|
|
||||||
if (this.projectId && this.form.type != '' && this.form.type != 'undefined') {
|
|
||||||
this.result = this.$get(url, response => {
|
|
||||||
this.testOptions = response.data;
|
|
||||||
this.testOptions.unshift({id: 'other', name: this.$t('test_track.case.other')})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
visibleChange(flag) {
|
visibleChange(flag) {
|
||||||
if (flag) {
|
if (flag) {
|
||||||
this.getDemandOptions();
|
this.getDemandOptions();
|
||||||
|
@ -936,6 +981,15 @@ export default {
|
||||||
/// todo: 是否需要对文件内容和大小做限制
|
/// todo: 是否需要对文件内容和大小做限制
|
||||||
return file.size > 0;
|
return file.size > 0;
|
||||||
},
|
},
|
||||||
|
addListener() {
|
||||||
|
document.addEventListener("keydown", this.createCtrlSHandle);
|
||||||
|
},
|
||||||
|
removeListener() {
|
||||||
|
document.removeEventListener("keydown", this.createCtrlSHandle);
|
||||||
|
},
|
||||||
|
createCtrlSHandle(event) {
|
||||||
|
handleCtrlSEvent(event, this.saveCase);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -90,26 +90,26 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row v-if="testCase.method === 'auto' && testCase.testId && testCase.testId != 'other'">
|
<!-- <el-row v-if="testCase.method === 'auto' && testCase.testId && testCase.testId != 'other'">-->
|
||||||
<el-col class="test-detail" :span="20" :offset="1">
|
<!-- <el-col class="test-detail" :span="20" :offset="1">-->
|
||||||
<el-tabs v-model="activeTab" type="border-card" @tab-click="testTabChange">
|
<!-- <el-tabs v-model="activeTab" type="border-card" @tab-click="testTabChange">-->
|
||||||
<el-tab-pane name="detail" :label="$t('test_track.plan_view.test_detail')">
|
<!-- <el-tab-pane name="detail" :label="$t('test_track.plan_view.test_detail')">-->
|
||||||
<api-test-detail :is-read-only="isReadOnly" v-if="testCase.type === 'api'" @runTest="testRun"
|
<!-- <api-test-detail :is-read-only="isReadOnly" v-if="testCase.type === 'api'" @runTest="testRun"-->
|
||||||
:id="testCase.testId" ref="apiTestDetail"/>
|
<!-- :id="testCase.testId" ref="apiTestDetail"/>-->
|
||||||
<performance-test-detail :is-read-only="isReadOnly" v-if="testCase.type === 'performance'"
|
<!-- <performance-test-detail :is-read-only="isReadOnly" v-if="testCase.type === 'performance'"-->
|
||||||
@runTest="testRun" :id="testCase.testId" ref="performanceTestDetail"/>
|
<!-- @runTest="testRun" :id="testCase.testId" ref="performanceTestDetail"/>-->
|
||||||
</el-tab-pane>
|
<!-- </el-tab-pane>-->
|
||||||
<el-tab-pane name="result" :label="$t('test_track.plan_view.test_result')">
|
<!-- <el-tab-pane name="result" :label="$t('test_track.plan_view.test_result')">-->
|
||||||
<api-test-result :report-id="testCase.reportId" v-if=" testCase.type === 'api'"
|
<!-- <api-test-result :report-id="testCase.reportId" v-if=" testCase.type === 'api'"-->
|
||||||
ref="apiTestResult"/>
|
<!-- ref="apiTestResult"/>-->
|
||||||
<performance-test-result :is-read-only="isReadOnly" :report-id="testCase.reportId"
|
<!-- <performance-test-result :is-read-only="isReadOnly" :report-id="testCase.reportId"-->
|
||||||
v-if="testCase.type === 'performance'" ref="performanceTestResult"/>
|
<!-- v-if="testCase.type === 'performance'" ref="performanceTestResult"/>-->
|
||||||
</el-tab-pane>
|
<!-- </el-tab-pane>-->
|
||||||
</el-tabs>
|
<!-- </el-tabs>-->
|
||||||
</el-col>
|
<!-- </el-col>-->
|
||||||
</el-row>
|
<!-- </el-row>-->
|
||||||
|
|
||||||
<el-row v-if="testCase.method && testCase.method !== 'auto'">
|
<el-row>
|
||||||
<el-col :span="22" :offset="1">
|
<el-col :span="22" :offset="1">
|
||||||
<div>
|
<div>
|
||||||
<span class="cast_label">{{ $t('test_track.case.steps') }}:</span>
|
<span class="cast_label">{{ $t('test_track.case.steps') }}:</span>
|
||||||
|
@ -491,7 +491,7 @@ export default {
|
||||||
}
|
}
|
||||||
this.testCase = item;
|
this.testCase = item;
|
||||||
this.getRelatedTest();
|
this.getRelatedTest();
|
||||||
this.initTest();
|
// this.initTest();
|
||||||
this.getIssues(item.caseId);
|
this.getIssues(item.caseId);
|
||||||
this.stepResultChange();
|
this.stepResultChange();
|
||||||
this.getFileMetaData(item);
|
this.getFileMetaData(item);
|
||||||
|
@ -519,19 +519,19 @@ export default {
|
||||||
listenGoBack(this.handleClose);
|
listenGoBack(this.handleClose);
|
||||||
this.initData(testCase);
|
this.initData(testCase);
|
||||||
},
|
},
|
||||||
initTest() {
|
// initTest() {
|
||||||
this.$nextTick(() => {
|
// this.$nextTick(() => {
|
||||||
if (this.testCase.testId && this.testCase.testId !== 'other') {
|
// if (this.testCase.testId && this.testCase.testId !== 'other') {
|
||||||
if (this.testCase.method === 'auto') {
|
// if (this.testCase.method === 'auto') {
|
||||||
if (this.$refs.apiTestDetail && this.testCase.type === 'api') {
|
// if (this.$refs.apiTestDetail && this.testCase.type === 'api') {
|
||||||
this.$refs.apiTestDetail.init();
|
// this.$refs.apiTestDetail.init();
|
||||||
} else if (this.testCase.type === 'performance') {
|
// } else if (this.testCase.type === 'performance') {
|
||||||
this.$refs.performanceTestDetail.init();
|
// this.$refs.performanceTestDetail.init();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
},
|
// },
|
||||||
testRun(reportId) {
|
testRun(reportId) {
|
||||||
this.testCase.reportId = reportId;
|
this.testCase.reportId = reportId;
|
||||||
this.saveReport(reportId);
|
this.saveReport(reportId);
|
||||||
|
@ -641,7 +641,7 @@ export default {
|
||||||
this.$post('/test/plan/edit/status/' + planId);
|
this.$post('/test/plan/edit/status/' + planId);
|
||||||
},
|
},
|
||||||
stepResultChange() {
|
stepResultChange() {
|
||||||
if (this.testCase.method === 'manual') {
|
if (this.testCase.method === 'manual' || !this.testCase.method) {
|
||||||
this.isFailure = this.testCase.steptResults.filter(s => {
|
this.isFailure = this.testCase.steptResults.filter(s => {
|
||||||
return s.executeResult === 'Failure' || s.executeResult === 'Blocking';
|
return s.executeResult === 'Failure' || s.executeResult === 'Blocking';
|
||||||
}).length > 0;
|
}).length > 0;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 95a9d5c21af6a664b22ecc85cda6935ea706f623
|
Subproject commit 2115bd28a90854d2b6276a90878934715498c584
|
|
@ -1166,6 +1166,7 @@ export default {
|
||||||
input_type: "Please select type",
|
input_type: "Please select type",
|
||||||
input_method: "Please select method",
|
input_method: "Please select method",
|
||||||
input_prerequisite: "Please select prerequisite",
|
input_prerequisite: "Please select prerequisite",
|
||||||
|
input_demand_name: "Please input demand id or name",
|
||||||
delete_confirm: "Confirm delete test case",
|
delete_confirm: "Confirm delete test case",
|
||||||
delete: "Delete case",
|
delete: "Delete case",
|
||||||
save_create_continue: "Save and create continue",
|
save_create_continue: "Save and create continue",
|
||||||
|
|
|
@ -1170,6 +1170,7 @@ export default {
|
||||||
input_type: "请选择用例类型",
|
input_type: "请选择用例类型",
|
||||||
input_method: "请选择测试方式",
|
input_method: "请选择测试方式",
|
||||||
input_prerequisite: "请输入前置条件",
|
input_prerequisite: "请输入前置条件",
|
||||||
|
input_demand_name: "请输入需求ID或名称",
|
||||||
delete_confirm: "确认删除测试用例",
|
delete_confirm: "确认删除测试用例",
|
||||||
delete: "删除用例",
|
delete: "删除用例",
|
||||||
save_create_continue: "保存并继续创建",
|
save_create_continue: "保存并继续创建",
|
||||||
|
|
|
@ -1168,6 +1168,7 @@ export default {
|
||||||
input_type: "請選擇用例類型",
|
input_type: "請選擇用例類型",
|
||||||
input_method: "請選擇測試方式",
|
input_method: "請選擇測試方式",
|
||||||
input_prerequisite: "請輸入前置條件",
|
input_prerequisite: "請輸入前置條件",
|
||||||
|
input_demand_name: "請輸入請求ID或名稱",
|
||||||
delete_confirm: "確認刪除測試用例",
|
delete_confirm: "確認刪除測試用例",
|
||||||
delete: "刪除用例",
|
delete: "刪除用例",
|
||||||
save_create_continue: "保存並繼續創建",
|
save_create_continue: "保存並繼續創建",
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -4,7 +4,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>io.metersphere</groupId>
|
<groupId>io.metersphere</groupId>
|
||||||
<artifactId>metersphere-server</artifactId>
|
<artifactId>metersphere-server</artifactId>
|
||||||
<version>1.7</version>
|
<version>1.8</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|
Loading…
Reference in New Issue