merge: 合并dev最新修改

This commit is contained in:
BugKing 2021-11-26 15:40:44 +08:00
commit 7f0de8ca96
52 changed files with 512 additions and 267 deletions

View File

@ -196,7 +196,7 @@ public class ApiTestCaseController {
@PostMapping(value = "/jenkins/run") @PostMapping(value = "/jenkins/run")
@MsAuditLog(module = "api_definition_case", type = OperLogConstants.EXECUTE, content = "#msClass.getLogDetails(#request.caseId)", msClass = ApiTestCaseService.class) @MsAuditLog(module = "api_definition_case", type = OperLogConstants.EXECUTE, content = "#msClass.getLogDetails(#request.caseId)", msClass = ApiTestCaseService.class)
public String jenkinsRun(@RequestBody RunCaseRequest request) { public String jenkinsRun(@RequestBody RunCaseRequest request) {
return apiTestCaseService.run(request); return apiTestCaseService.jenkinsRun(request);
} }
@GetMapping(value = "/jenkins/exec/result/{id}") @GetMapping(value = "/jenkins/exec/result/{id}")

View File

@ -121,10 +121,8 @@ public class MsScenario extends MsTestElement {
}); });
this.setHeaders(headers); this.setHeaders(headers);
} }
if (element.get("environmentMap") != null) {
this.setEnvironmentMap((Map) element.get("environmentMap"));
}
this.setHashTree(sourceHashTree); this.setHashTree(sourceHashTree);
hashTree = sourceHashTree;
} }
} catch (Exception ex) { } catch (Exception ex) {

View File

@ -174,9 +174,9 @@ public class MsAssertions extends MsTestElement {
JSR223Assertion assertion = new JSR223Assertion(); JSR223Assertion assertion = new JSR223Assertion();
assertion.setEnabled(this.isEnable()); assertion.setEnabled(this.isEnable());
if (StringUtils.isNotEmpty(assertionJSR223.getDesc())) { if (StringUtils.isNotEmpty(assertionJSR223.getDesc())) {
assertion.setName("JSR223" + "==" + this.getName() + "==" + assertionJSR223.getDesc() + "==" + assertionJSR223.getScript()); assertion.setName("JSR223" + "==" + this.getName() + "==" + assertionJSR223.getDesc() + "&&" + assertionJSR223.getScript());
} else { } else {
assertion.setName("JSR223" + "==" + this.getName() + "==" + "JSR223Assertion" + "==" + assertionJSR223.getScript()); assertion.setName("JSR223" + "==" + this.getName() + "==" + "JSR223Assertion" + "&&" + assertionJSR223.getScript());
} }
assertion.setProperty(TestElement.TEST_CLASS, JSR223Assertion.class.getName()); assertion.setProperty(TestElement.TEST_CLASS, JSR223Assertion.class.getName());
assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI"));

View File

@ -73,7 +73,7 @@ public class ApiJmeterFileService {
} }
} }
HashTree hashTree; HashTree hashTree;
if (StringUtils.equalsAnyIgnoreCase(runMode, ApiRunMode.DEFINITION.name(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) { if (StringUtils.equalsAnyIgnoreCase(runMode, ApiRunMode.DEFINITION.name(), ApiRunMode.JENKINS_API_PLAN.name(),ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) {
String testId = remoteTestId; String testId = remoteTestId;
if (remoteTestId.contains(":")) { if (remoteTestId.contains(":")) {
//执行测试计划案例时会有拼接ID,ID为 planTestCaseId:测试计划报告ID //执行测试计划案例时会有拼接ID,ID为 planTestCaseId:测试计划报告ID

View File

@ -736,16 +736,20 @@ public class ApiTestCaseService {
return ids; return ids;
} }
private ApiDefinitionExecResult addResult(String id, String status) { private ApiDefinitionExecResult addResult(String resourceId, String status, String reportId) {
ApiDefinitionExecResult apiResult = new ApiDefinitionExecResult(); ApiDefinitionExecResult apiResult = new ApiDefinitionExecResult();
if (StringUtils.isEmpty(reportId)) {
apiResult.setId(UUID.randomUUID().toString()); apiResult.setId(UUID.randomUUID().toString());
} else {
apiResult.setId(reportId);
}
apiResult.setCreateTime(System.currentTimeMillis()); apiResult.setCreateTime(System.currentTimeMillis());
apiResult.setStartTime(System.currentTimeMillis()); apiResult.setStartTime(System.currentTimeMillis());
apiResult.setEndTime(System.currentTimeMillis()); apiResult.setEndTime(System.currentTimeMillis());
apiResult.setTriggerMode(TriggerMode.BATCH.name()); apiResult.setTriggerMode(TriggerMode.BATCH.name());
apiResult.setActuator("LOCAL"); apiResult.setActuator("LOCAL");
apiResult.setUserId(Objects.requireNonNull(SessionUtils.getUser()).getId()); apiResult.setUserId(Objects.requireNonNull(SessionUtils.getUser()).getId());
apiResult.setResourceId(id); apiResult.setResourceId(resourceId);
apiResult.setStartTime(System.currentTimeMillis()); apiResult.setStartTime(System.currentTimeMillis());
apiResult.setType(ApiRunMode.DEFINITION.name()); apiResult.setType(ApiRunMode.DEFINITION.name());
apiResult.setStatus(status); apiResult.setStatus(status);
@ -765,7 +769,7 @@ public class ApiTestCaseService {
ApiTestCaseMapper sqlSessionMapper = sqlSession.getMapper(ApiTestCaseMapper.class); ApiTestCaseMapper sqlSessionMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
for (ApiTestCaseWithBLOBs caseWithBLOBs : list) { for (ApiTestCaseWithBLOBs caseWithBLOBs : list) {
ApiDefinitionExecResult report = addResult(caseWithBLOBs.getId(), APITestStatus.Running.name()); ApiDefinitionExecResult report = addResult(caseWithBLOBs.getId(), APITestStatus.Running.name(), null);
report.setName(caseWithBLOBs.getName()); report.setName(caseWithBLOBs.getName());
caseWithBLOBs.setLastResultId(report.getId()); caseWithBLOBs.setLastResultId(report.getId());
caseWithBLOBs.setUpdateTime(System.currentTimeMillis()); caseWithBLOBs.setUpdateTime(System.currentTimeMillis());
@ -792,6 +796,38 @@ public class ApiTestCaseService {
} }
} }
public String jenkinsRun(RunCaseRequest request) {
ApiTestCaseWithBLOBs caseWithBLOBs = null;
if (request.getBloBs() == null) {
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(request.getCaseId());
if (caseWithBLOBs == null) {
return null;
}
request.setBloBs(caseWithBLOBs);
} else {
caseWithBLOBs = request.getBloBs();
}
if (caseWithBLOBs == null) {
return null;
}
if (StringUtils.isBlank(request.getEnvironmentId())) {
request.setEnvironmentId(extApiTestCaseMapper.getApiCaseEnvironment(request.getCaseId()));
}
//提前生成报告
ApiDefinitionExecResult report = addResult(caseWithBLOBs.getId(), APITestStatus.Running.name(), request.getReportId());
report.setName(caseWithBLOBs.getName());
report.setTriggerMode(ApiRunMode.API.name());
report.setType(ApiRunMode.JENKINS.name());
apiDefinitionExecResultMapper.insert(report);
//更新接口案例的最后执行状态等信息
caseWithBLOBs.setLastResultId(report.getId());
caseWithBLOBs.setUpdateTime(System.currentTimeMillis());
caseWithBLOBs.setStatus(APITestStatus.Running.name());
apiTestCaseMapper.updateByPrimaryKey(caseWithBLOBs);
request.setReport(report);
return this.run(request);
}
public String run(RunCaseRequest request) { public String run(RunCaseRequest request) {
ApiTestCaseWithBLOBs testCaseWithBLOBs = request.getBloBs(); ApiTestCaseWithBLOBs testCaseWithBLOBs = request.getBloBs();
if (StringUtils.equals(request.getRunMode(), ApiRunMode.JENKINS_API_PLAN.name())) { if (StringUtils.equals(request.getRunMode(), ApiRunMode.JENKINS_API_PLAN.name())) {
@ -800,15 +836,13 @@ public class ApiTestCaseService {
//通过测试计划id查询环境 //通过测试计划id查询环境
request.setReportId(request.getTestPlanId()); request.setReportId(request.getTestPlanId());
} }
if (StringUtils.equals(request.getRunMode(), ApiRunMode.JENKINS.name())) {
request.setReportId(request.getEnvironmentId());
}
// 多态JSON普通转换会丢失内容需要通过 ObjectMapper 获取 // 多态JSON普通转换会丢失内容需要通过 ObjectMapper 获取
if (testCaseWithBLOBs != null && StringUtils.isNotEmpty(testCaseWithBLOBs.getRequest())) { if (testCaseWithBLOBs != null && StringUtils.isNotEmpty(testCaseWithBLOBs.getRequest())) {
try { try {
HashTree jmeterHashTree = this.generateHashTree(request, testCaseWithBLOBs); HashTree jmeterHashTree = this.generateHashTree(request, testCaseWithBLOBs);
// 调用执行方法 // 调用执行方法
jMeterService.runLocal(request.getReportId(),null, jmeterHashTree, null, request.getRunMode()); jMeterService.runLocal(request.getReportId(), null, jmeterHashTree, null, request.getRunMode());
} catch (Exception ex) { } catch (Exception ex) {
ApiDefinitionExecResult result = MessageCache.caseExecResourceLock.get(request.getReportId()); ApiDefinitionExecResult result = MessageCache.caseExecResourceLock.get(request.getReportId());
@ -834,7 +868,7 @@ public class ApiTestCaseService {
request.setTestPlanId(testPlanID); request.setTestPlanId(testPlanID);
HashTree jmeterHashTree = this.generateHashTree(request, apiCaseBolbs); HashTree jmeterHashTree = this.generateHashTree(request, apiCaseBolbs);
// 调用执行方法 // 调用执行方法
jMeterService.runLocal(id,null, jmeterHashTree, debugReportId, runMode); jMeterService.runLocal(id, null, jmeterHashTree, debugReportId, runMode);
} catch (Exception ex) { } catch (Exception ex) {
LogUtil.error(ex); LogUtil.error(ex);
} }
@ -1171,9 +1205,7 @@ public class ApiTestCaseService {
if (StringUtils.isBlank(environmentId)) { if (StringUtils.isBlank(environmentId)) {
return null; return null;
} }
// "environmentId"
try { try {
environmentId = environmentId.substring(1, environmentId.length() - 1);
return apiTestEnvironmentMapper.selectByPrimaryKey(environmentId); return apiTestEnvironmentMapper.selectByPrimaryKey(environmentId);
} catch (Exception e) { } catch (Exception e) {
LogUtil.error("api case environmentId incorrect parsing. api case id: " + caseId); LogUtil.error("api case environmentId incorrect parsing. api case id: " + caseId);

View File

@ -252,14 +252,22 @@ public class MsResultService {
ResponseAssertionResult responseAssertionResult = new ResponseAssertionResult(); ResponseAssertionResult responseAssertionResult = new ResponseAssertionResult();
responseAssertionResult.setName(assertionResult.getName()); responseAssertionResult.setName(assertionResult.getName());
if (StringUtils.isNotEmpty(assertionResult.getName()) && assertionResult.getName().indexOf("==") != -1) { if (StringUtils.isNotEmpty(assertionResult.getName()) && assertionResult.getName().indexOf("==") != -1) {
String[] array = assertionResult.getName().split("=="); if (assertionResult.getName().indexOf("JSR223") != -1) {
String[] array = assertionResult.getName().split("==", 3);
if ("JSR223".equals(array[0])) { if ("JSR223".equals(array[0])) {
responseAssertionResult.setName(array[1]); responseAssertionResult.setName(array[1]);
responseAssertionResult.setContent(array[2]); if (array[2].indexOf("&&") != -1) {
if (array.length > 3) { String[] content = array[2].split("&&");
responseAssertionResult.setScript(array[3]); responseAssertionResult.setContent(content[0]);
if (content.length > 1) {
responseAssertionResult.setScript(content[1]);
} }
} else { } else {
responseAssertionResult.setContent(array[2]);
}
}
} else {
String[] array = assertionResult.getName().split("==");
responseAssertionResult.setName(array[0]); responseAssertionResult.setName(array[0]);
StringBuffer content = new StringBuffer(); StringBuffer content = new StringBuffer();
for (int i = 1; i < array.length; i++) { for (int i = 1; i < array.length; i++) {

View File

@ -72,6 +72,7 @@ public class TestResultService {
reportTask.setTriggerMode(TriggerMode.API.name()); reportTask.setTriggerMode(TriggerMode.API.name());
reportTask.setName(apiTestCaseWithBLOBs.getName()); reportTask.setName(apiTestCaseWithBLOBs.getName());
reportTask.setExecutor(userName); reportTask.setExecutor(userName);
reportTask.setUserId(apiTestCaseWithBLOBs.getCreateUserId());
reportTask.setExecutionTime(DateUtils.getTimeString(apiTestCaseWithBLOBs.getCreateTime())); reportTask.setExecutionTime(DateUtils.getTimeString(apiTestCaseWithBLOBs.getCreateTime()));
reportTask.setEnvironment(name); reportTask.setEnvironment(name);
//测试计划用例定时jenkins //测试计划用例定时jenkins
@ -105,18 +106,17 @@ public class TestResultService {
} }
//报告内容 //报告内容
reportTask = new ApiTestReportVariable(); reportTask = new ApiTestReportVariable();
if (StringUtils.equalsAny(runMode, ApiRunMode.SCHEDULE_SCENARIO.name())) {
reportTask.setStatus(scenarioReport.getStatus()); reportTask.setStatus(scenarioReport.getStatus());
reportTask.setId(scenarioReport.getId()); reportTask.setId(scenarioReport.getId());
reportTask.setTriggerMode(scenarioReport.getTriggerMode()); reportTask.setTriggerMode(scenarioReport.getTriggerMode());
reportTask.setName(scenarioReport.getName()); reportTask.setName(scenarioReport.getName());
reportTask.setExecutor(userName); reportTask.setExecutor(userName);
reportTask.setUserId(scenarioReport.getUserId());
reportTask.setPrincipal(principal); reportTask.setPrincipal(principal);
reportTask.setExecutionTime(DateUtils.getTimeString(scenarioReport.getUpdateTime())); reportTask.setExecutionTime(DateUtils.getTimeString(scenarioReport.getUpdateTime()));
reportTask.setEnvironment(environment); reportTask.setEnvironment(environment);
SystemParameterService systemParameterService = CommonBeanFactory.getBean(SystemParameterService.class); SystemParameterService systemParameterService = CommonBeanFactory.getBean(SystemParameterService.class);
assert systemParameterService != null; assert systemParameterService != null;
}
testResult.setTestId(scenarioReport.getScenarioId()); testResult.setTestId(scenarioReport.getScenarioId());
planScenarioId = scenarioReport.getTestPlanScenarioId(); planScenarioId = scenarioReport.getTestPlanScenarioId();
} }

View File

@ -30,5 +30,7 @@ public class CustomField implements Serializable {
private String options; private String options;
private String defaultValue;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }

View File

@ -726,7 +726,7 @@
order by `order` desc limit 1; order by `order` desc limit 1;
</select> </select>
<select id="getApiCaseEnvironment" resultType="java.lang.String"> <select id="getApiCaseEnvironment" resultType="java.lang.String">
select request -> '$.useEnvironment' from api_test_case where id = #{caseId} select request ->> '$.useEnvironment' from api_test_case where id = #{caseId}
</select> </select>
<update id="deleteToGc" parameterType="io.metersphere.api.dto.definition.ApiTestCaseRequest"> <update id="deleteToGc" parameterType="io.metersphere.api.dto.definition.ApiTestCaseRequest">
update api_test_case update api_test_case

View File

@ -35,4 +35,6 @@ public interface ExtProjectMapper {
long getProjectMemberSize(@Param("projectId") String projectId); long getProjectMemberSize(@Param("projectId") String projectId);
List<Project>getProjectByUserId(@Param("userId")String userId); List<Project>getProjectByUserId(@Param("userId")String userId);
int getProjectPlanBugSize(@Param("projectId") String projectId);
} }

View File

@ -244,4 +244,11 @@
<select id="getProjectByUserId" resultType="io.metersphere.base.domain.Project"> <select id="getProjectByUserId" resultType="io.metersphere.base.domain.Project">
SELECT * from project where project.id in (SELECT user_group.source_id from user_group where user_group.user_id = #{userId}) SELECT * from project where project.id in (SELECT user_group.source_id from user_group where user_group.user_id = #{userId})
</select> </select>
<select id="getProjectPlanBugSize" resultType="java.lang.Integer">
select count(distinct(tci.issues_id)) from test_plan_test_case tptc
join test_case_issues tci on tptc.case_id = tci.test_case_id
join issues on tci.issues_id = issues.id
join test_plan on tptc.plan_id = test_plan.id
where test_plan.project_id = #{projectId} and (issues.status != 'closed' or issues.status is null);
</select>
</mapper> </mapper>

View File

@ -214,21 +214,14 @@
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>
</select> </select>
<select id="listByMethod" resultType="io.metersphere.track.dto.TestCaseDTO"> <select id="listByMethod" resultType="io.metersphere.track.dto.TestCaseDTO">
SELECT id,name,project_id,"api" as type from api_test select id,name,project_id,'性能测试' as type from load_test
<where>
<if test="request.projectId!=null">
and project_id=#{request.projectId}
</if>
</where>
UNION ALL
select id,name,project_id,"perform" as type from load_test
<where> <where>
<if test="request.projectId!=null"> <if test="request.projectId!=null">
and project_id= #{request.projectId} and project_id= #{request.projectId}
</if> </if>
</where> </where>
UNION ALL UNION ALL
select id,name,project_id,"scenario" as type from api_scenario select id,name,project_id,'接口场景' as type from api_scenario
<where> <where>
<if test="request.projectId!=null"> <if test="request.projectId!=null">
@ -237,7 +230,7 @@
</where> </where>
and api_scenario.status!='Trash' and api_scenario.status!='Trash'
UNION ALL UNION ALL
select b.id,b.name,b.project_id,"definition" as type from api_test_case b select b.id,b.name,b.project_id,'接口用例' as type from api_test_case b
inner join inner join
api_definition a api_definition a
on on
@ -448,7 +441,7 @@
</select> </select>
<select id="getTestPlanBug" resultType="int"> <select id="getTestPlanBug" resultType="int">
select count(tci.issues_id) from test_plan_test_case tptc join test_case_issues tci on tptc.case_id = tci.test_case_id join issues on tci.issues_id = issues.id select count(tci.issues_id) from test_plan_test_case tptc join test_case_issues tci on tptc.case_id = tci.test_case_id join issues on tci.issues_id = issues.id
where tptc.plan_id = #{planId} and issues.status != 'closed'; where tptc.plan_id = #{planId} and (issues.status != 'closed' or issues.status is null);
</select> </select>
<select id="getTestPlanCase" resultType="int"> <select id="getTestPlanCase" resultType="int">
select count(s) select count(s)

View File

@ -115,7 +115,28 @@
parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest"> parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
select DISTINCT test_plan.*, project.name as projectName,schedule.id as scheduleId, select DISTINCT test_plan.*, project.name as projectName,schedule.id as scheduleId,
(select name from user where user.id = test_plan.creator) as createUser, (select name from user where user.id = test_plan.creator) as createUser,
IF(schedule.enable = true,true,false) as scheduleOpen IF(schedule.enable = true,true,false) as scheduleOpen,
(select COUNT(*) from test_plan_test_case t
inner join test_case on t.case_id = test_case.id
left join test_case_node on test_case_node.id = test_case.node_id
inner join project on project.id = test_case.project_id
where test_case.status != 'Trash' and t.plan_id = test_plan.id) as testPlanTestCaseCount,
(select COUNT(*) from test_plan_api_case t
inner join api_test_case c on t.api_case_id = c.id
inner join api_definition a on c.api_definition_id = a.id
where t.test_plan_id = test_plan.id) as testPlanApiCaseCount,
(select COUNT(*) from test_plan_api_scenario t
inner join api_scenario c on t.api_scenario_id = c.id and c.status != 'Trash'
where t.test_plan_id = test_plan.id) as testPlanApiScenarioCount,
(select COUNT(*) from test_plan_load_case t
inner join load_test lt on t.load_case_id = lt.id
left join user u on lt.user_id = u.id
left join project p on lt.project_id = p.id
where t.test_plan_id = test_plan.id) as testPlanLoadCaseCount
from test_plan from test_plan
LEFT JOIN schedule ON schedule.resource_id = test_plan.id LEFT JOIN schedule ON schedule.resource_id = test_plan.id
JOIN project on project.id = test_plan.project_id JOIN project on project.id = test_plan.project_id

View File

@ -24,7 +24,7 @@ public class IssueTemplateController {
private IssueTemplateService issueTemplateService; private IssueTemplateService issueTemplateService;
@PostMapping("/add") @PostMapping("/add")
@MsAuditLog(module = "workspace_template_settings_issue", type = OperLogConstants.CREATE, content = "#msClass.getLogDetails(#request.id)", msClass = IssueTemplateService.class) @MsAuditLog(module = "workspace_template_settings_issue", type = OperLogConstants.CREATE, content = "#msClass.getLogDetails(#request)", msClass = IssueTemplateService.class)
public void add(@RequestBody UpdateIssueTemplateRequest request) { public void add(@RequestBody UpdateIssueTemplateRequest request) {
issueTemplateService.add(request); issueTemplateService.add(request);
} }
@ -42,7 +42,7 @@ public class IssueTemplateController {
} }
@PostMapping("/update") @PostMapping("/update")
@MsAuditLog(module = "workspace_template_settings_issue", type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#request.id)", content = "#msClass.getLogDetails(#request.id)", msClass = IssueTemplateService.class) @MsAuditLog(module = "workspace_template_settings_issue", type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#request.id,#request.customFields)", content = "#msClass.getLogDetails(#request)", msClass = IssueTemplateService.class)
public void update(@RequestBody UpdateIssueTemplateRequest request) { public void update(@RequestBody UpdateIssueTemplateRequest request) {
issueTemplateService.update(request); issueTemplateService.update(request);
} }

View File

@ -101,6 +101,11 @@ public class SystemReference {
issueFieldColumns.put("title", "标题"); issueFieldColumns.put("title", "标题");
issueFieldColumns.put("content", "缺陷内容"); issueFieldColumns.put("content", "缺陷内容");
issueFieldColumns.put("description", "描述"); issueFieldColumns.put("description", "描述");
issueFieldColumns.put("scene", "使用场景");
issueFieldColumns.put("type", "属性类型");
issueFieldColumns.put("system", "系统字段");
issueFieldColumns.put("remark", "字段备注");
issueFieldColumns.put("defaultValue", "字段值");
projectColumns.put("name", "名称"); projectColumns.put("name", "名称");
projectColumns.put("description", "描述"); projectColumns.put("description", "描述");

View File

@ -1,5 +1,6 @@
package io.metersphere.notice.sender.impl; package io.metersphere.notice.sender.impl;
import com.alibaba.fastjson.JSON;
import io.metersphere.base.domain.Notification; import io.metersphere.base.domain.Notification;
import io.metersphere.commons.constants.NotificationConstants; import io.metersphere.commons.constants.NotificationConstants;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
@ -38,7 +39,7 @@ public class InSiteNoticeSender extends AbstractNoticeSender {
Map<String, Object> paramMap = noticeModel.getParamMap(); Map<String, Object> paramMap = noticeModel.getParamMap();
Notification notification = new Notification(); Notification notification = new Notification();
notification.setTitle(noticeModel.getSubject()); notification.setTitle(noticeModel.getSubject());
notification.setContent(context); notification.setContent(JSON.toJSONString(paramMap));
notification.setOperator(noticeModel.getOperator()); notification.setOperator(noticeModel.getOperator());
notification.setOperation(noticeModel.getEvent()); notification.setOperation(noticeModel.getEvent());
notification.setResourceId((String) paramMap.get("id")); notification.setResourceId((String) paramMap.get("id"));

View File

@ -76,7 +76,7 @@ public class PerformanceNoticeEvent implements LoadTestFinishEvent {
NoticeModel noticeModel = NoticeModel.builder() NoticeModel noticeModel = NoticeModel.builder()
.operator(loadTestReport.getUserId()) .operator(loadTestReport.getUserId())
.successContext(successContext) .successContext(successContext)
.successMailTemplate("PerformanceApiSuccessNotification") .successMailTemplate("PerformanceSuccessNotification")
.failedContext(failedContext) .failedContext(failedContext)
.failedMailTemplate("PerformanceFailedNotification") .failedMailTemplate("PerformanceFailedNotification")
.testId(loadTestReport.getTestId()) .testId(loadTestReport.getTestId())

View File

@ -2,6 +2,8 @@ package io.metersphere.service;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.CustomFieldMapper;
import io.metersphere.base.mapper.CustomFieldTemplateMapper;
import io.metersphere.base.mapper.IssueTemplateMapper; import io.metersphere.base.mapper.IssueTemplateMapper;
import io.metersphere.base.mapper.ext.ExtIssueTemplateMapper; import io.metersphere.base.mapper.ext.ExtIssueTemplateMapper;
import io.metersphere.commons.constants.TemplateConstants; import io.metersphere.commons.constants.TemplateConstants;
@ -25,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -47,6 +50,12 @@ public class IssueTemplateService extends TemplateBaseService {
@Resource @Resource
ProjectService projectService; ProjectService projectService;
@Resource
CustomFieldMapper customFieldMapper;
@Resource
CustomFieldTemplateMapper customFieldTemplateMapper;
public String add(UpdateIssueTemplateRequest request) { public String add(UpdateIssueTemplateRequest request) {
checkExist(request); checkExist(request);
IssueTemplate template = new IssueTemplate(); IssueTemplate template = new IssueTemplate();
@ -222,13 +231,57 @@ public class IssueTemplateService extends TemplateBaseService {
return issueTemplateDao; return issueTemplateDao;
} }
public String getLogDetails(String id) { public String getLogDetails(String id, List<CustomFieldTemplate>newCustomFieldTemplates) {
List<DetailColumn> columns = new LinkedList<>();
IssueTemplate templateWithBLOBs = issueTemplateMapper.selectByPrimaryKey(id); IssueTemplate templateWithBLOBs = issueTemplateMapper.selectByPrimaryKey(id);
if (templateWithBLOBs != null) { if(templateWithBLOBs==null){
List<DetailColumn> columns = ReflexObjectUtil.getColumns(templateWithBLOBs, SystemReference.issueFieldColumns); return null;
}
CustomFieldTemplateExample example = new CustomFieldTemplateExample();
example.createCriteria().andTemplateIdEqualTo(templateWithBLOBs.getId());
example.createCriteria().andSceneEqualTo("ISSUE");
List<CustomFieldTemplate> customFieldTemplates = customFieldTemplateMapper.selectByExample(example);
if(newCustomFieldTemplates.size()>customFieldTemplates.size()){
for (int i = 0; i < newCustomFieldTemplates.size()-customFieldTemplates.size(); i++) {
CustomFieldTemplate customFieldTemplate = new CustomFieldTemplate();
customFieldTemplates.add(customFieldTemplate);
}
}
return getCustomFieldColums(columns, templateWithBLOBs, customFieldTemplates);
}
public String getLogDetails(UpdateIssueTemplateRequest request) {
List<DetailColumn> columns = new LinkedList<>();
IssueTemplate templateWithBLOBs = issueTemplateMapper.selectByPrimaryKey(request.getId());
if(templateWithBLOBs==null){
return null;
}
List<CustomFieldTemplate> newCustomFieldTemplates = request.getCustomFields();
CustomFieldTemplateExample example = new CustomFieldTemplateExample();
example.createCriteria().andTemplateIdEqualTo(templateWithBLOBs.getId());
example.createCriteria().andSceneEqualTo("ISSUE");
List<CustomFieldTemplate> customFieldTemplates = customFieldTemplateMapper.selectByExample(example);
if(newCustomFieldTemplates.size()<customFieldTemplates.size()){
for (int i = 0; i < customFieldTemplates.size()-newCustomFieldTemplates.size(); i++) {
CustomFieldTemplate customFieldTemplate = new CustomFieldTemplate();
newCustomFieldTemplates.add(customFieldTemplate);
}
}
return getCustomFieldColums(columns, templateWithBLOBs, newCustomFieldTemplates);
}
private String getCustomFieldColums(List<DetailColumn> columns, IssueTemplate templateWithBLOBs, List<CustomFieldTemplate> customFields) {
for (CustomFieldTemplate customFieldTemplate : customFields) {
CustomField customField = customFieldMapper.selectByPrimaryKey(customFieldTemplate.getFieldId());
customField.setDefaultValue(customFieldTemplate.getDefaultValue());
List<DetailColumn> columnsField = ReflexObjectUtil.getColumns(customField, SystemReference.issueFieldColumns);
columns.addAll(columnsField);
}
List<DetailColumn> columnIssues = ReflexObjectUtil.getColumns(templateWithBLOBs, SystemReference.issueFieldColumns);
columns.addAll(columnIssues);
OperatingLogDetails details = new OperatingLogDetails(JSON.toJSONString(templateWithBLOBs.getId()), null, templateWithBLOBs.getName(), templateWithBLOBs.getCreateUser(), columns); OperatingLogDetails details = new OperatingLogDetails(JSON.toJSONString(templateWithBLOBs.getId()), null, templateWithBLOBs.getName(), templateWithBLOBs.getCreateUser(), columns);
return JSON.toJSONString(details); return JSON.toJSONString(details);
} }
return null;
}
} }

View File

@ -745,4 +745,8 @@ public class ProjectService {
public long getProjectMemberSize(String id) { public long getProjectMemberSize(String id) {
return extProjectMapper.getProjectMemberSize(id); return extProjectMapper.getProjectMemberSize(id);
} }
public int getProjectBugSize(String projectId) {
return extProjectMapper.getProjectPlanBugSize(projectId);
}
} }

View File

@ -12,4 +12,8 @@ public class TestPlanDTOWithMetric extends TestPlanDTO {
private Integer tested; private Integer tested;
private Integer total; private Integer total;
private String createUser; private String createUser;
private Integer testPlanTestCaseCount;
private Integer testPlanApiCaseCount;
private Integer testPlanApiScenarioCount;
private Integer testPlanLoadCaseCount;
} }

View File

@ -252,7 +252,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
protected String msImg2HtmlImg(String input, String endpoint) { protected String msImg2HtmlImg(String input, String endpoint) {
// ![中心主题.png](/resource/md/get/a0b19136_中心主题.png) -> <img src="xxx/resource/md/get/a0b19136_中心主题.png"/> // ![中心主题.png](/resource/md/get/a0b19136_中心主题.png) -> <img src="xxx/resource/md/get/a0b19136_中心主题.png"/>
String regex = "(\\!\\[.*?\\]\\((.*)\\))"; String regex = "(\\!\\[.*?\\]\\((.*?)\\))";
Pattern pattern = Pattern.compile(regex); Pattern pattern = Pattern.compile(regex);
if (StringUtils.isBlank(input)) { if (StringUtils.isBlank(input)) {
return ""; return "";
@ -272,7 +272,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
} }
protected String removeImage(String input) { protected String removeImage(String input) {
String regex = "(\\!\\[.*?\\]\\((.*)\\))"; String regex = "(\\!\\[.*?\\]\\((.*?)\\))";
if (StringUtils.isBlank(input)) { if (StringUtils.isBlank(input)) {
return ""; return "";
} }
@ -286,7 +286,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
protected String getImages(String input) { protected String getImages(String input) {
String result = ""; String result = "";
String regex = "(\\!\\[.*?\\]\\((.*)\\))"; String regex = "(\\!\\[.*?\\]\\((.*?)\\))";
if (StringUtils.isBlank(input)) { if (StringUtils.isBlank(input)) {
return result; return result;
} }
@ -299,7 +299,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
protected String htmlImg2MsImg(String input) { protected String htmlImg2MsImg(String input) {
// <img src="xxx/resource/md/get/a0b19136_中心主题.png"/> -> ![中心主题.png](/resource/md/get/a0b19136_中心主题.png) // <img src="xxx/resource/md/get/a0b19136_中心主题.png"/> -> ![中心主题.png](/resource/md/get/a0b19136_中心主题.png)
String regex = "(<img\\s*src=\\\"(.*)\\\".*?>)"; String regex = "(<img\\s*src=\\\"(.*?)\\\".*?>)";
Pattern pattern = Pattern.compile(regex); Pattern pattern = Pattern.compile(regex);
if (StringUtils.isBlank(input)) { if (StringUtils.isBlank(input)) {
return ""; return "";
@ -321,7 +321,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
public List<File> getImageFiles(String input) { public List<File> getImageFiles(String input) {
List<File> files = new ArrayList<>(); List<File> files = new ArrayList<>();
String regex = "(\\!\\[.*?\\]\\((.*)\\))"; String regex = "(\\!\\[.*?\\]\\((.*?)\\))";
Pattern pattern = Pattern.compile(regex); Pattern pattern = Pattern.compile(regex);
if (StringUtils.isBlank(input)) { if (StringUtils.isBlank(input)) {
return new ArrayList<>(); return new ArrayList<>();

View File

@ -391,7 +391,13 @@ public class TestPlanApiCaseService {
if (caseWithBLOBs != null) { if (caseWithBLOBs != null) {
apiResult.setName(caseWithBLOBs.getName()); apiResult.setName(caseWithBLOBs.getName());
} }
if(StringUtils.equalsIgnoreCase(request.getTriggerMode(),ApiRunMode.SCHEDULE_API_PLAN.name())) {
apiResult.setTriggerMode(TriggerMode.SCHEDULE.name());
}else if(StringUtils.equalsIgnoreCase(request.getTriggerMode(),ApiRunMode.JENKINS_API_PLAN.name())){
apiResult.setTriggerMode(TriggerMode.MANUAL.name());
}else {
apiResult.setTriggerMode(TriggerMode.BATCH.name()); apiResult.setTriggerMode(TriggerMode.BATCH.name());
}
apiResult.setActuator("LOCAL"); apiResult.setActuator("LOCAL");
if (request.getConfig() != null && StringUtils.isNotEmpty(request.getConfig().getResourcePoolId())) { if (request.getConfig() != null && StringUtils.isNotEmpty(request.getConfig().getResourcePoolId())) {
apiResult.setActuator(request.getConfig().getResourcePoolId()); apiResult.setActuator(request.getConfig().getResourcePoolId());

View File

@ -9,6 +9,7 @@ import io.metersphere.commons.constants.TestPlanTestCaseStatus;
import io.metersphere.commons.utils.DateUtils; import io.metersphere.commons.utils.DateUtils;
import io.metersphere.commons.utils.MathUtils; import io.metersphere.commons.utils.MathUtils;
import io.metersphere.performance.base.ChartsData; import io.metersphere.performance.base.ChartsData;
import io.metersphere.service.ProjectService;
import io.metersphere.track.dto.TestPlanDTOWithMetric; import io.metersphere.track.dto.TestPlanDTOWithMetric;
import io.metersphere.track.response.BugStatustics; import io.metersphere.track.response.BugStatustics;
import io.metersphere.track.response.TestPlanBugCount; import io.metersphere.track.response.TestPlanBugCount;
@ -40,6 +41,8 @@ public class TrackService {
private TestPlanScenarioCaseService testPlanScenarioCaseService; private TestPlanScenarioCaseService testPlanScenarioCaseService;
@Resource @Resource
private TestPlanLoadCaseService testPlanLoadCaseService; private TestPlanLoadCaseService testPlanLoadCaseService;
@Resource
private ProjectService projectService;
public List<TrackCountResult> countPriority(String projectId) { public List<TrackCountResult> countPriority(String projectId) {
return extTestCaseMapper.countPriority(projectId); return extTestCaseMapper.countPriority(projectId);
@ -115,7 +118,6 @@ public class TrackService {
List<TestPlanBugCount> list = new ArrayList<>(); List<TestPlanBugCount> list = new ArrayList<>();
BugStatustics bugStatustics = new BugStatustics(); BugStatustics bugStatustics = new BugStatustics();
int index = 1; int index = 1;
int totalBugSize = 0;
int totalCaseSize = 0; int totalCaseSize = 0;
for (TestPlan plan : plans) { for (TestPlan plan : plans) {
int planBugSize = getPlanBugSize(plan.getId()); int planBugSize = getPlanBugSize(plan.getId());
@ -137,12 +139,11 @@ public class TrackService {
double planPassRage = getPlanPassRage(plan.getId()); double planPassRage = getPlanPassRage(plan.getId());
testPlanBug.setPassRage(planPassRage + "%"); testPlanBug.setPassRage(planPassRage + "%");
list.add(testPlanBug); list.add(testPlanBug);
totalBugSize += planBugSize;
totalCaseSize += planCaseSize; totalCaseSize += planCaseSize;
} }
int totalBugSize = projectService.getProjectBugSize(projectId);
bugStatustics.setList(list); bugStatustics.setList(list);
float rage =totalCaseSize == 0 ? 0 : (float) totalBugSize * 100 / totalCaseSize; float rage =totalCaseSize == 0 ? 0 : (float) totalBugSize * 100 / totalCaseSize;
DecimalFormat df = new DecimalFormat("0.0"); DecimalFormat df = new DecimalFormat("0.0");

View File

@ -33,37 +33,9 @@ alter table api_scenario
alter table api_scenario alter table api_scenario
add environment_group_id varchar(50) null; add environment_group_id varchar(50) null;
DELIMITER $$ update api_scenario
DROP PROCEDURE IF EXISTS proc_loop_test$$ set environment_json = api_scenario.scenario_definition -> '$.environmentMap'
CREATE PROCEDURE proc_loop_test() where api_scenario.environment_json is null;
BEGIN
DECLARE int_val INT DEFAULT 0;
DECLARE size INT DEFAULT 10;
DECLARE count_scenario INT DEFAULT 0;
SELECT COUNT(1) INTO count_scenario FROM api_scenario;
test_loop :
LOOP
IF (int_val > count_scenario / size)
THEN
UPDATE api_scenario
SET environment_json = api_scenario.scenario_definition -> '$.environmentMap'
WHERE api_scenario.id IN (SELECT id FROM (SELECT id FROM api_scenario LIMIT int_val, size) l);
#
LEAVE test_loop;
END IF;
UPDATE api_scenario
SET environment_json = api_scenario.scenario_definition -> '$.environmentMap'
WHERE api_scenario.id IN (SELECT id FROM (SELECT id FROM api_scenario LIMIT int_val, size) l);
SET int_val = int_val + size;
END LOOP;
END$$
DELIMITER ;
CALL proc_loop_test();
DROP PROCEDURE proc_loop_test;
update api_scenario set environment_type = 'JSON'; update api_scenario set environment_type = 'JSON';

View File

@ -1,18 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MeterSphere</title>
</head>
<body style="text-align: left">
<div style="text-align: left">
<p>尊敬的用户:</p>
<p style="margin-left: 60px">您好:
</div>
<div style="margin-left: 100px">
<p>您所执行的 ${name} 性能测试已完成<br/>
请点击下面链接进入测试报告页面</p>
<a href="${url}/#/${type}/report/view/${id}">${url}/#/${type}/report/view/${id}</a>
</div>
</body>
</html>

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MeterSphere</title>
</head>
<body style="text-align: left">
<div style="margin-left: 100px">
${operator}执行性能测试成功: ${name}, 报告: ${reportUrl}
</div>
</body>
</html>

View File

@ -427,7 +427,7 @@ export default {
} }
}, },
editScenario(row) { editScenario(row) {
const index = this.tabs.find(p => p.currentScenario.id === row.id); const index = this.tabs.find(p => p.currentScenario.id === row.id && p.currentScenario.copy === row.copy);
if (!index) { if (!index) {
this.addTab({name: 'edit', currentScenario: row}); this.addTab({name: 'edit', currentScenario: row});
} else { } else {
@ -486,6 +486,7 @@ export default {
/deep/ .el-tabs__header { /deep/ .el-tabs__header {
margin: 0 0 0px; margin: 0 0 0px;
} }
/deep/ .el-table__empty-block { /deep/ .el-table__empty-block {
width: 100%; width: 100%;
min-width: 100%; min-width: 100%;

View File

@ -99,7 +99,7 @@ export function saveScenario(url, scenario, scenarioDefinition, _this, success)
success(response); success(response);
} }
}, error => { }, error => {
_this.$emit('errorRefresh', {}); _this.$emit('errorRefresh', error);
}); });
} }

View File

@ -52,7 +52,6 @@
:fields-width="fieldsWidth" :fields-width="fieldsWidth"
min-width="120px"> min-width="120px">
<template slot-scope="scope"> <template slot-scope="scope">
<!--<span style="cursor:pointer" v-if="isReadOnly"> {{ scope.row.num }} </span>-->
<el-tooltip content="编辑"> <el-tooltip content="编辑">
<a style="cursor:pointer" @click="edit(scope.row)"> {{ scope.row.num }} </a> <a style="cursor:pointer" @click="edit(scope.row)"> {{ scope.row.num }} </a>
</el-tooltip> </el-tooltip>
@ -66,7 +65,6 @@
:fields-width="fieldsWidth" :fields-width="fieldsWidth"
min-width="120px"> min-width="120px">
<template slot-scope="scope"> <template slot-scope="scope">
<!--<span style="cursor:pointer" v-if="isReadOnly"> {{ scope.row.customNum }} </span>-->
<el-tooltip content="编辑"> <el-tooltip content="编辑">
<a style="cursor:pointer" @click="edit(scope.row)"> {{ scope.row.customNum }} </a> <a style="cursor:pointer" @click="edit(scope.row)"> {{ scope.row.customNum }} </a>
</el-tooltip> </el-tooltip>
@ -537,14 +535,6 @@ export default {
}; };
}, },
created() { created() {
// if (!hasLicense()) {
// for (let i = 0; i < this.unTrashButtons.length; i++) {
// if (this.unTrashButtons[i].handleClick === this.generateGraph) {
// this.unTrashButtons.splice(i,1);
// break;
// }
// }
// }
scenario.$on('hide', id => { scenario.$on('hide', id => {
this.hideStopBtn(id); this.hideStopBtn(id);
}); });

View File

@ -205,12 +205,14 @@
:project-list="projectList" :project-list="projectList"
:env-map="projectEnvMap" :env-map="projectEnvMap"
:env-group-id="envGroupId" :env-group-id="envGroupId"
:environment-type="environmentType"
@remove="remove" @remove="remove"
@copyRow="copyRow" @copyRow="copyRow"
@suggestClick="suggestClick" @suggestClick="suggestClick"
@refReload="refReload" @refReload="refReload"
@runScenario="runDebug" @runScenario="runDebug"
@stopScenario="stop" @stopScenario="stop"
@setDomain="setDomain"
@openScenario="openScenario"/> @openScenario="openScenario"/>
</span> </span>
</el-tree> </el-tree>
@ -528,7 +530,7 @@ export default {
currentUser: () => { currentUser: () => {
return getCurrentUser(); return getCurrentUser();
}, },
setDomain(flag) { setDomain() {
if (this.projectEnvMap && this.projectEnvMap.size > 0) { if (this.projectEnvMap && this.projectEnvMap.size > 0) {
let scenario = { let scenario = {
id: this.currentScenario.id, id: this.currentScenario.id,
@ -1501,7 +1503,7 @@ export default {
this.initMessageSocket(); this.initMessageSocket();
} }
}, },
errorRefresh() { errorRefresh(error) {
this.debug = false; this.debug = false;
this.isTop = false; this.isTop = false;
this.debugLoading = false; this.debugLoading = false;

View File

@ -9,7 +9,7 @@
<el-input :placeholder="$t('api_test.definition.request.path_all_info')" v-model="request.url" <el-input :placeholder="$t('api_test.definition.request.path_all_info')" v-model="request.url"
style="width: 50%" size="small" @blur="urlChange" :disabled="request.disabled"> style="width: 50%" size="small" @blur="urlChange" :disabled="request.disabled">
</el-input> </el-input>
<el-checkbox v-if="isCustomizeReq" class="is-ref-environment" v-model="request.isRefEnvironment"> <el-checkbox v-if="isCustomizeReq" class="is-ref-environment" v-model="request.isRefEnvironment" @change="setDomain" :disabled="request.disabled">
{{ $t('api_test.request.refer_to_environment') }} {{ $t('api_test.request.refer_to_environment') }}
</el-checkbox> </el-checkbox>
</div> </div>
@ -123,6 +123,9 @@ export default {
this.$error(this.$t('api_test.request.url_invalid'), 2000); this.$error(this.$t('api_test.request.url_invalid'), 2000);
} }
}, },
setDomain() {
this.$emit("setDomain");
}
} }
} }
</script> </script>

View File

@ -52,7 +52,7 @@
<!--请求内容--> <!--请求内容-->
<template v-slot:request> <template v-slot:request>
<legend style="width: 100%"> <legend style="width: 100%">
<customize-req-info :is-customize-req="isCustomizeReq" :request="request"/> <customize-req-info :is-customize-req="isCustomizeReq" :request="request" @setDomain="setDomain"/>
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p> <p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
<ms-api-request-form <ms-api-request-form
v-if="request.protocol==='HTTP' || request.type==='HTTPSamplerProxy'" v-if="request.protocol==='HTTP' || request.type==='HTTPSamplerProxy'"
@ -217,6 +217,9 @@ export default {
this.request.projectId = getCurrentProjectID(); this.request.projectId = getCurrentProjectID();
} }
this.request.customizeReq = this.isCustomizeReq; this.request.customizeReq = this.isCustomizeReq;
if(this.request.num){
this.isShowNum = true;
}
// //
this.getApiInfo(); this.getApiInfo();
if (this.request.protocol === 'HTTP') { if (this.request.protocol === 'HTTP') {
@ -447,91 +450,30 @@ export default {
} }
this.reload(); this.reload();
this.sort(); this.sort();
} else {
this.request.referenced = "Deleted";
} }
}) })
} }
if(this.request.id && this.request.referenced === 'Copy'){ else if(this.request.id && this.request.referenced === 'Copy'){
let requestResult = this.request.requestResult;
let enable = this.request.enable;
if(this.request.refType==='CASE'){ if(this.request.refType==='CASE'){
this.$get("/api/testcase/get/" + this.request.id, response => { this.$get("/api/testcase/get/" + this.request.id, response => {
if (response.data) { if (response.data) {
let hashTree = [];
if (this.request.hashTree) {
hashTree = JSON.parse(JSON.stringify(this.request.hashTree));
}
Object.assign(this.request, JSON.parse(response.data.request));
this.request.name = response.data.name;
this.request.referenced = "Copy";
this.request.enable = enable;
if (response.data.path && response.data.path != null) {
this.request.path = response.data.path;
this.request.url = response.data.url;
}
if (response.data.method && response.data.method != null) {
this.request.method = response.data.method;
}
if (requestResult && Object.prototype.toString.call(requestResult) !== '[object Array]') {
this.request.requestResult = [requestResult];
} else {
this.request.requestResult = requestResult;
}
if(response.data.num){ if(response.data.num){
this.request.num = response.data.num; this.request.num = response.data.num;
this.isShowNum = true; this.isShowNum = true;
} }
this.request.id = response.data.id; this.request.id = response.data.id;
this.request.root = true;
this.request.projectId = response.data.projectId;
let req = JSON.parse(response.data.request);
if (req && this.request) {
this.request.hashTree = hashTree;
this.mergeHashTree(req.hashTree);
}
this.reload();
this.sort();
} }
}) })
} }
if(this.request.refType==='API'){ else if(this.request.refType==='API'){
this.$get("/api/definition/get/" + this.request.id, response => { this.$get("/api/definition/get/" + this.request.id, response => {
if (response.data) { if (response.data) {
let hashTree = [];
if (this.request.hashTree) {
hashTree = JSON.parse(JSON.stringify(this.request.hashTree));
}
Object.assign(this.request, JSON.parse(response.data.request));
this.request.name = response.data.name;
this.request.referenced = "Copy";
this.request.enable = enable;
if (response.data.path && response.data.path != null) {
this.request.path = response.data.path;
this.request.url = response.data.url;
}
if (response.data.method && response.data.method != null) {
this.request.method = response.data.method;
}
if (requestResult && Object.prototype.toString.call(requestResult) !== '[object Array]') {
this.request.requestResult = [requestResult];
} else {
this.request.requestResult = requestResult;
}
if(response.data.num){ if(response.data.num){
this.request.num = response.data.num; this.request.num = response.data.num;
this.isShowNum = true; this.isShowNum = true;
} }
this.request.id = response.data.id; this.request.id = response.data.id;
this.request.root = true;
this.request.projectId = response.data.projectId;
let req = JSON.parse(response.data.request);
if (req && this.request) {
this.request.hashTree = hashTree;
this.mergeHashTree(req.hashTree);
}
this.reload();
this.sort();
} }
}) })
} }
@ -675,6 +617,9 @@ export default {
this.loading = false; this.loading = false;
this.$emit('refReload', this.request, this.node); this.$emit('refReload', this.request, this.node);
}, },
setDomain() {
this.$emit("setDomain");
},
reload() { reload() {
this.loading = true this.loading = true
this.$nextTick(() => { this.$nextTick(() => {

View File

@ -36,7 +36,6 @@ export default {
this.getExecResult(); this.getExecResult();
} else { } else {
this.response = this.result; this.response = this.result;
// this.isActive = true;
} }
if(this.apiActive){ if(this.apiActive){
this.isActive = false this.isActive = false
@ -62,10 +61,14 @@ export default {
let url = "/api/definition/report/getReport/" + this.apiItem.id; let url = "/api/definition/report/getReport/" + this.apiItem.id;
this.$get(url, response => { this.$get(url, response => {
if (response.data) { if (response.data) {
try {
let data = JSON.parse(response.data.content); let data = JSON.parse(response.data.content);
this.response = data; this.response = data;
this.$set(this.apiItem, 'responseData', data); this.$set(this.apiItem, 'responseData', data);
this.isActive = true; this.isActive = true;
}catch (error){
this.isActive = true;
}
} }
}); });
} }

View File

@ -41,7 +41,7 @@
</template> </template>
<template v-slot:scenarioEnable> <template v-slot:scenarioEnable>
<el-tooltip content="启用场景环境:当前步骤使用场景原始环境配置运行" placement="top"> <el-tooltip content="启用场景环境:当前步骤使用场景原始环境配置运行" placement="top">
<el-checkbox v-model="scenario.environmentEnable" @change="checkEnv">启用场景环境</el-checkbox> <el-checkbox v-model="scenario.environmentEnable" @change="checkEnv" :disabled="scenario.disabled">启用场景环境</el-checkbox>
</el-tooltip> </el-tooltip>
</template> </template>
<template v-slot:button> <template v-slot:button>
@ -66,8 +66,7 @@ import MsTcpBasisParameters from "../../../definition/components/request/tcp/Tcp
import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters"; import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters";
import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm"; import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm";
import ApiBaseComponent from "../common/ApiBaseComponent"; import ApiBaseComponent from "../common/ApiBaseComponent";
import {getCurrentProjectID, getUUID} from "@/common/js/utils"; import {getCurrentProjectID, getUUID, strMapToObj} from "@/common/js/utils";
import {getUrl} from "@/business/components/api/automation/scenario/component/urlhelper";
export default { export default {
name: "ApiScenarioComponent", name: "ApiScenarioComponent",
@ -88,7 +87,10 @@ export default {
default: false, default: false,
}, },
currentEnvironmentId: String, currentEnvironmentId: String,
projectList: Array projectList: Array,
environmentType: String,
environmentGroupId: String,
envMap: Map
}, },
watch: { watch: {
message() { message() {
@ -99,6 +101,9 @@ export default {
}, },
}, },
created() { created() {
if(this.scenario.num){
this.isShowNum = true;
}
if (!this.scenario.projectId) { if (!this.scenario.projectId) {
this.scenario.projectId = getCurrentProjectID(); this.scenario.projectId = getCurrentProjectID();
} }
@ -128,8 +133,16 @@ export default {
this.scenario.variables = obj.variables; this.scenario.variables = obj.variables;
this.scenario.environmentMap = obj.environmentMap; this.scenario.environmentMap = obj.environmentMap;
this.$emit('refReload'); this.$emit('refReload');
} else { }
this.scenario.referenced = "Deleted"; })
}
else if(this.scenario.id && this.scenario.referenced === 'Copy' && !this.scenario.loaded){
this.result = this.$get("/api/automation/getApiScenario/" + this.scenario.id, response => {
if (response.data) {
if(response.data.num){
this.scenario.num = response.data.num;
this.isShowNum = true;
}
} }
}) })
} }
@ -163,21 +176,23 @@ export default {
this.$emit('stopScenario'); this.$emit('stopScenario');
this.reload(); this.reload();
}, },
checkEnv() { checkEnv(val) {
this.$post("/api/automation/checkScenarioEnv", {scenarioDefinition: JSON.stringify(this.scenario), projectId: this.projectId}, res => { this.$post("/api/automation/checkScenarioEnv", {scenarioDefinition: JSON.stringify(this.scenario), projectId: this.projectId}, res => {
if (this.scenario.environmentEnable && !res.data) { if (this.scenario.environmentEnable && !res.data) {
this.scenario.environmentEnable = false; this.scenario.environmentEnable = false;
this.$warning("当前场景没有环境,需要先设置自身环境"); this.$warning("当前场景没有环境,需要先设置自身环境");
return; return;
} }
this.setDomain(); this.setDomain(val);
}); });
}, },
setDomain() { setDomain(val) {
if (this.scenario.environmentEnable) {
let param = { let param = {
environmentEnable: true, environmentEnable: val,
id: this.scenario.id, id: this.scenario.id,
environmentType: this.environmentType,
environmentGroupId: this.environmentGroupId,
environmentMap: strMapToObj(this.envMap),
definition: JSON.stringify(this.scenario) definition: JSON.stringify(this.scenario)
} }
this.$post("/api/automation/setDomain", param, res => { this.$post("/api/automation/setDomain", param, res => {
@ -186,7 +201,6 @@ export default {
this.scenario.hashTree = data.hashTree; this.scenario.hashTree = data.hashTree;
} }
}) })
}
}, },
getCode() { getCode() {
if (this.node && this.node.data.code && this.node.data.debug) { if (this.node && this.node.data.code && this.node.data.debug) {

View File

@ -20,7 +20,7 @@
:title="title" :title="title"
:color="titleColor" :color="titleColor"
:response="response" :response="response"
:environmet-type="environmentType" :environment-type="environmentType"
:environment-group-id="envGroupId" :environment-group-id="envGroupId"
:background-color="backgroundColor" :background-color="backgroundColor"
:project-list="projectList" :project-list="projectList"
@ -34,7 +34,7 @@
@copyRow="copyRow" @copyRow="copyRow"
@refReload="refReload" @refReload="refReload"
@openScenario="openScenario" @openScenario="openScenario"
@setDomain="setDomain"
/> />
</keep-alive> </keep-alive>
</div> </div>
@ -231,6 +231,9 @@ export default {
}, },
stopScenario() { stopScenario() {
this.$emit('stopScenario'); this.$emit('stopScenario');
},
setDomain() {
this.$emit("setDomain");
} }
} }
} }

View File

@ -555,28 +555,28 @@ export default {
} }
}, },
closeConfirm(targetName) { closeConfirm(targetName) {
let tabs = this.apiTabs; let tab = this.apiTabs;
if(!tabs[1].api) { tab.forEach(t => {
this.handleTabRemove(targetName); if (t.name === targetName) {
} if (t.api && this.$store.state.apiMap.size > 0 && this.$store.state.apiMap.has(t.api.id)) {
if (tabs[1].api && this.$store.state.apiMap.size > 0) { if (this.$store.state.apiMap.get(t.api.id).get("responseChange") === true || this.$store.state.apiMap.get(t.api.id).get("requestChange") === true ||
if (this.$store.state.apiMap.get(tabs[1].api.id).get("responseChange") === true || this.$store.state.apiMap.get(tabs[1].api.id).get("requestChange") === true || this.$store.state.apiMap.get(t.api.id).get("fromChange") === true) {
this.$store.state.apiMap.get(tabs[1].api.id).get("fromChange") === true) { this.$alert("接口[ " + t.api.name + " ]未保存,是否确认关闭?", '', {
this.$alert("接口[ " + tabs[1].api.name + " ]未保存,是否确认关闭?", '', {
confirmButtonText: this.$t('commons.confirm'), confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'), cancelButtonText: this.$t('commons.cancel'),
callback: (action) => { callback: (action) => {
if (action === 'confirm') { if (action === 'confirm') {
this.$store.state.apiMap.delete(tabs[1].api.id); this.$store.state.apiMap.delete(t.api.id);
this.handleTabRemove(targetName); this.handleTabRemove(targetName);
} }
} }
}); });
} }
} else{ } else {
this.handleTabRemove(targetName); this.handleTabRemove(targetName);
} }
}
})
}, },
handleTabRemove(targetName) { handleTabRemove(targetName) {
let tabs = this.apiTabs; let tabs = this.apiTabs;

View File

@ -267,6 +267,8 @@ export default {
this.$emit('saveApi', data); this.$emit('saveApi', data);
}); });
this.$store.state.apiMap.delete(this.currentApi.id); this.$store.state.apiMap.delete(this.currentApi.id);
this.responseCount = 0;
this.count = 0
}, },
handleSave() { handleSave() {
if (this.$refs.httpApi) { if (this.$refs.httpApi) {

View File

@ -72,7 +72,7 @@
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item :label="$t('commons.tag')" prop="tag"> <el-form-item :label="$t('commons.tag')" prop="tag">
<ms-input-tag :currentScenario="httpForm" ref="tag"/> <ms-input-tag :currentScenario="httpForm" ref="tag" v-model="httpForm.tags"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
@ -179,6 +179,7 @@
label: 'name', label: 'name',
}, },
mockBaseUrl: "", mockBaseUrl: "",
count: 0
} }
}, },
props: {moduleOptions: {}, request: {}, response: {}, basisData: {}, syncTabs: Array, projectId: String}, props: {moduleOptions: {}, request: {}, response: {}, basisData: {}, syncTabs: Array, projectId: String},
@ -232,6 +233,14 @@
} }
} }
}, },
'httpForm.tags': {
handler(v, v1) {
this.count++;
if (v && v1 && JSON.stringify(v) !== JSON.stringify(v1) && this.count > 1) {
this.apiMapStatus();
}
}
},
syncTabs() { syncTabs() {
if (this.basisData && this.syncTabs && this.syncTabs.includes(this.basisData.id)) { if (this.basisData && this.syncTabs && this.syncTabs.includes(this.basisData.id)) {
// //
@ -337,6 +346,8 @@
if (valid) { if (valid) {
this.setParameter(); this.setParameter();
this.$emit('saveApi', this.httpForm); this.$emit('saveApi', this.httpForm);
this.count = 0;
this.$store.state.apiMap.delete(this.httpForm.id);
} else { } else {
return false; return false;
} }

View File

@ -502,9 +502,13 @@ export default {
let url = "/api/definition/report/get/" + apiCase.lastResultId; let url = "/api/definition/report/get/" + apiCase.lastResultId;
this.$get(url, response => { this.$get(url, response => {
if (response.data) { if (response.data) {
try {
let data = JSON.parse(response.data.content); let data = JSON.parse(response.data.content);
this.response = data; this.response = data;
this.resVisible = true; this.resVisible = true;
} catch (error) {
this.resVisible = true;
}
} }
}); });
} }
@ -653,9 +657,9 @@ export default {
} else if (this.selectDataRange != null) { } else if (this.selectDataRange != null) {
let selectParamArr = this.selectDataRange.split(":"); let selectParamArr = this.selectDataRange.split(":");
if (selectParamArr.length === 2) { if (selectParamArr.length === 2) {
if(selectParamArr[0] === "single") { if (selectParamArr[0] === "single") {
this.condition.id = selectParamArr[1]; this.condition.id = selectParamArr[1];
}else { } else {
this.condition.apiDefinitionId = selectParamArr[1]; this.condition.apiDefinitionId = selectParamArr[1];
} }
} }

View File

@ -13,25 +13,78 @@
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="script">
<template v-slot:default="{row}">
<div class="assertion-item btn circle" v-if="row.script">
<i class="el-icon-view el-button el-button--primary el-button--mini is-circle" circle
@click="showPage(row.script)"/>
</div>
</template>
</el-table-column>
<el-dialog :title="$t('api_test.request.assertions.script')" :visible.sync="visible" width="900px" append-to-body>
<el-row type="flex" justify="space-between" align="middle" class="quick-script-block">
<el-col :span="codeSpan" class="script-content">
<ms-code-edit v-if="isCodeEditAlive"
:read-only="disabled"
:data.sync="scriptContent" theme="eclipse" :modes="['java','python']"
ref="codeEdit"/>
</el-col>
</el-row>
</el-dialog>
</el-table> </el-table>
</template> </template>
<script> <script>
import MsCodeEdit from "@/business/components/common/components/MsCodeEdit";
export default { export default {
name: "MsAssertionResults", name: "MsAssertionResults",
components: {MsCodeEdit},
props: { props: {
assertions: Array assertions: Array
}, },
data() {
return {
visible: false,
disabled: false,
codeSpan: 20,
isCodeEditAlive: true,
scriptContent: '',
}
},
methods: { methods: {
getRowStyle() { getRowStyle() {
return {backgroundColor: "#F5F5F5"}; return {backgroundColor: "#F5F5F5"};
} },
} showPage(script) {
this.disabled = true;
this.visible = true;
this.scriptContent = script;
this.reload();
},
reload() {
this.isCodeEditAlive = false;
this.$nextTick(() => (this.isCodeEditAlive = true));
},
},
} }
</script> </script>
<style scoped> <style scoped>
.assertion-item.btn.circle {
text-align: right;
min-width: 80px;
}
.script-content {
height: calc(100vh - 570px);
min-height: 440px;
}
.quick-script-block {
margin-bottom: 10px;
}
</style> </style>

View File

@ -39,6 +39,10 @@ export const Test_Plan_List = [
{id: 'executionTimes', label: i18n.t('commons.execution_times')}, {id: 'executionTimes', label: i18n.t('commons.execution_times')},
{id: 'passRate', label: i18n.t('commons.pass_rate')}, {id: 'passRate', label: i18n.t('commons.pass_rate')},
{id: 'createUser', label: i18n.t('commons.create_user')}, {id: 'createUser', label: i18n.t('commons.create_user')},
{id: 'testPlanTestCaseCount', label: i18n.t('test_track.plan.test_plan_test_case_count')},
{id: 'testPlanApiCaseCount', label: i18n.t('test_track.plan.test_plan_api_case_count')},
{id: 'testPlanApiScenarioCount', label: i18n.t('test_track.plan.test_plan_api_scenario_count')},
{id: 'testPlanLoadCaseCount', label: i18n.t('test_track.plan.test_plan_load_case_count')}
] ]
//接口定义-api列表 //接口定义-api列表
export const Api_List = [ export const Api_List = [

View File

@ -50,6 +50,15 @@ export function getResource(d) {
switch (d.resourceType) { switch (d.resourceType) {
case "JENKINS_TASK" : case "JENKINS_TASK" :
resourceType = "Jenkins"; resourceType = "Jenkins";
if (d.operation === 'EXECUTE_SUCCESSFUL') {
resourceType = "Jenkins 成功";
}
if (d.operation === 'EXECUTE_FAILED') {
resourceType = "Jenkins 失败";
}
if (d.operation === 'EXECUTE_COMPLETED') {
resourceType = "Jenkins 完成";
}
break; break;
case "TEST_PLAN_TASK" : case "TEST_PLAN_TASK" :
resourceType = "测试计划"; resourceType = "测试计划";
@ -115,7 +124,40 @@ export function getUrl(d) {
let url = "/#"; let url = "/#";
switch (d.resourceType) { switch (d.resourceType) {
case "JENKINS_TASK" : case "JENKINS_TASK" :
// jenkins 跳转需要特殊处理
try {
let obj = JSON.parse(d.content);
// 接口自动化,性能测试
if (obj.reportUrl) {
let s = obj.reportUrl.indexOf('#');
url += obj.reportUrl.substring(s + 1);
}
// 接口用例
else if (obj.caseStatus) {
url += "/api/definition?caseId=" + d.resourceId;
}
// 测试计划
else if (obj.url) {
let s = obj.url.indexOf('#');
url += obj.url.substring(s + 1);
} else {
url += "/track/plan/all"; url += "/track/plan/all";
}
} catch (e) {
// jenkins 跳转需要特殊处理
if (d.content.indexOf("接口用例") > -1) {
url += "/api/definition?caseId=" + d.resourceId;
} else if (d.content.indexOf("性能测试") > -1) {
url += "/performance/test/edit/" + d.resourceId;
} else if (d.content.indexOf("接口测试") > -1) {
url += "/api/automation/report/view/" + d.resourceId;
} else if (d.content.indexOf("测试计划运行") > -1) {
url += "/track/plan/view/" + d.resourceId;
} else {
url += "/track/plan/all";
}
}
break; break;
case "TEST_PLAN_TASK" : case "TEST_PLAN_TASK" :
url += "/track/plan/view/" + d.resourceId; url += "/track/plan/view/" + d.resourceId;
@ -133,7 +175,7 @@ export function getUrl(d) {
url += "/api/automation?resourceId=" + d.resourceId; url += "/api/automation?resourceId=" + d.resourceId;
break; break;
case "API_DEFINITION_TASK" : case "API_DEFINITION_TASK" :
if (d.operation.startsWith('CASE_') || d.operation.startsWith('EXECUTE_') ) { if (d.operation.startsWith('CASE_') || d.operation.startsWith('EXECUTE_')) {
url += "/api/definition?caseId=" + d.resourceId; url += "/api/definition?caseId=" + d.resourceId;
} else { } else {
url += "/api/definition?resourceId=" + d.resourceId; url += "/api/definition?resourceId=" + d.resourceId;

View File

@ -157,11 +157,11 @@ export default {
'</head>\n' + '</head>\n' +
'<body>\n' + '<body>\n' +
'<div>\n' + '<div>\n' +
'${operator}所执行的 ${name} ${type}测试运行成功' + '${operator}执行 Jenkins 成功: ${name}' +
'</div>\n' + '</div>\n' +
'</body>\n' + '</body>\n' +
'</html>', '</html>',
robotTitle: "${operator}所执行的 ${name} ${type}测试运行成功", robotTitle: "${operator}执行 Jenkins 成功: ${name}",
jenkinsTask: [{ jenkinsTask: [{
taskType: "jenkinsTask", taskType: "jenkinsTask",
event: "", event: "",

View File

@ -360,9 +360,13 @@ export default {
let url = "/api/definition/report/get/" + reportId; let url = "/api/definition/report/get/" + reportId;
this.$get(url, response => { this.$get(url, response => {
if (response.data) { if (response.data) {
try {
let data = JSON.parse(response.data.content); let data = JSON.parse(response.data.content);
this.response = data; this.response = data;
this.visible = true; this.visible = true;
} catch (error) {
this.visible = true;
}
} }
}); });
} }

View File

@ -295,7 +295,7 @@ export default {
handleTabClose() { handleTabClose() {
let message = ""; let message = "";
this.tabs.forEach(t => { this.tabs.forEach(t => {
if (t && this.$store.state.testCaseMap.has(t.testCaseInfo.id) && this.$store.state.testCaseMap.get(t.testCaseInfo.id) > 2) { if (t && this.$store.state.testCaseMap.has(t.testCaseInfo.id) && this.$store.state.testCaseMap.get(t.testCaseInfo.id) > 1) {
message += t.testCaseInfo.name + ""; message += t.testCaseInfo.name + "";
} }
}) })
@ -320,7 +320,7 @@ export default {
}, },
closeConfirm(targetName) { closeConfirm(targetName) {
let t = this.tabs.filter(tab => tab.name === targetName); let t = this.tabs.filter(tab => tab.name === targetName);
if (t && this.$store.state.testCaseMap.has(t[0].testCaseInfo.id) && this.$store.state.testCaseMap.get(t[0].testCaseInfo.id) > 2) { if (t && this.$store.state.testCaseMap.has(t[0].testCaseInfo.id) && this.$store.state.testCaseMap.get(t[0].testCaseInfo.id) > 1) {
this.$alert("用例[ " + t[0].testCaseInfo.name + " ]未保存,是否确认关闭?", '', { this.$alert("用例[ " + t[0].testCaseInfo.name + " ]未保存,是否确认关闭?", '', {
confirmButtonText: this.$t('commons.confirm'), confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'), cancelButtonText: this.$t('commons.cancel'),

View File

@ -457,6 +457,7 @@ export default {
if (!this.form.remark) { if (!this.form.remark) {
this.form.remark = ""; this.form.remark = "";
} }
this.$store.state.testCaseMap.set(this.form.id, 0);
}, },
handleCommand(e) { handleCommand(e) {
if (e === "ADD_AND_CREATE") { if (e === "ADD_AND_CREATE") {
@ -498,7 +499,10 @@ export default {
}, },
reload() { reload() {
this.isStepTableAlive = false; this.isStepTableAlive = false;
this.$nextTick(() => (this.isStepTableAlive = true)); this.$nextTick(() => {
this.isStepTableAlive = true;
this.$store.state.testCaseMap.set(this.form.id, 0);
});
}, },
reloadForm() { reloadForm() {
this.isFormAlive = false; this.isFormAlive = false;
@ -606,7 +610,6 @@ export default {
this.showInputTag = true; this.showInputTag = true;
}); });
}); });
this.$store.state.testCaseMap.set(this.form.id, 0);
}, },
async setFormData(testCase) { async setFormData(testCase) {
try { try {
@ -635,7 +638,6 @@ export default {
this.setDefaultValue(); this.setDefaultValue();
// //
this.reloadForm(); this.reloadForm();
this.$store.state.testCaseMap.set(this.form.id, 0);
}, },
setTestCaseExtInfo(testCase) { setTestCaseExtInfo(testCase) {
this.testCase = {}; this.testCase = {};
@ -692,7 +694,6 @@ export default {
callback(this); callback(this);
} }
// //
this.$refs.otherInfo.getFileMetaData(this.form.id);
}); });
} }
}, },

View File

@ -128,6 +128,38 @@
:min-width="100" :min-width="100"
:key="index"> :key="index">
</el-table-column> </el-table-column>
<el-table-column
v-if="item.id == 'testPlanTestCaseCount'"
prop="testPlanTestCaseCount"
:label="$t('test_track.plan.test_plan_test_case_count')"
show-overflow-tooltip
:min-width="100"
:key="index">
</el-table-column>
<el-table-column
v-if="item.id == 'testPlanApiCaseCount'"
prop="testPlanApiCaseCount"
:label="$t('test_track.plan.test_plan_api_case_count')"
show-overflow-tooltip
:min-width="100"
:key="index">
</el-table-column>
<el-table-column
v-if="item.id == 'testPlanApiScenarioCount'"
prop="testPlanApiScenarioCount"
:label="$t('test_track.plan.test_plan_api_scenario_count')"
show-overflow-tooltip
:min-width="100"
:key="index">
</el-table-column>
<el-table-column
v-if="item.id == 'testPlanLoadCaseCount'"
prop="testPlanLoadCaseCount"
:label="$t('test_track.plan.test_plan_load_case_count')"
show-overflow-tooltip
:min-width="100"
:key="index">
</el-table-column>
<el-table-column <el-table-column
v-if="item.id == 'passRate'" v-if="item.id == 'passRate'"
prop="passRate" prop="passRate"

View File

@ -37,6 +37,7 @@
import MsApiScenarioList from "../../../../../api/automation/scenario/ApiScenarioList"; import MsApiScenarioList from "../../../../../api/automation/scenario/ApiScenarioList";
import MsApiScenarioModule from "../../../../../api/automation/scenario/ApiScenarioModule"; import MsApiScenarioModule from "../../../../../api/automation/scenario/ApiScenarioModule";
import RelevanceScenarioList from "./RelevanceScenarioList"; import RelevanceScenarioList from "./RelevanceScenarioList";
import {ENV_TYPE} from "@/common/js/constants";
export default { export default {
name: "TestCaseScenarioRelevance", name: "TestCaseScenarioRelevance",
@ -109,6 +110,17 @@
let map = this.$refs.apiScenarioList.map; let map = this.$refs.apiScenarioList.map;
let envType = this.$refs.apiScenarioList.environmentType; let envType = this.$refs.apiScenarioList.environmentType;
let envGroupId = this.$refs.apiScenarioList.envGroupId; let envGroupId = this.$refs.apiScenarioList.envGroupId;
if (!map || map.size < 1) {
this.$warning("请选择用例!");
return false;
}
if (envType === ENV_TYPE.JSON && (!envMap || envMap.size < 1)) {
this.$warning("请选择环境!");
return false;
} else if (envType === ENV_TYPE.GROUP && !envGroupId) {
this.$warning("请选择环境!");
return false;
}
param.planId = this.planId; param.planId = this.planId;
param.mapping = strMapToObj(map); param.mapping = strMapToObj(map);
param.envMap = strMapToObj(envMap); param.envMap = strMapToObj(envMap);

View File

@ -119,6 +119,10 @@ export let CUSTOM_TABLE_HEADER = {
{id: 'executionTimes', key: 'c', label: 'commons.execution_times'}, {id: 'executionTimes', key: 'c', label: 'commons.execution_times'},
{id: 'passRate', key: 'd', label: 'commons.pass_rate'}, {id: 'passRate', key: 'd', label: 'commons.pass_rate'},
{id: 'createUser', key: 'e', label: 'commons.create_user'}, {id: 'createUser', key: 'e', label: 'commons.create_user'},
{id: 'testPlanTestCaseCount', key: 'f', label: 'test_track.plan.test_plan_test_case_count'},
{id: 'testPlanApiCaseCount', key: 'g', label: 'test_track.plan.test_plan_api_case_count'},
{id: 'testPlanApiScenarioCount', key: 'h', label: 'test_track.plan.test_plan_api_scenario_count'},
{id: 'testPlanLoadCaseCount', key: 'i', label: 'test_track.plan.test_plan_load_case_count'}
], ],
//测试计划-功能用例 //测试计划-功能用例
TEST_PLAN_FUNCTION_TEST_CASE: [ TEST_PLAN_FUNCTION_TEST_CASE: [

View File

@ -1769,6 +1769,10 @@ export default {
api_case: "Api case", api_case: "Api case",
scenario_case: "Scenario case", scenario_case: "Scenario case",
execute_result: "Execute Result", execute_result: "Execute Result",
test_plan_test_case_count: "Track case count",
test_plan_api_case_count: "Api case count",
test_plan_api_scenario_count: "Scenario case count",
test_plan_load_case_count: "Load case count",
load_case: { load_case: {
case: "Load Case", case: "Load Case",
execution_status: "Execution status", execution_status: "Execution status",

View File

@ -1780,6 +1780,10 @@ export default {
api_case: "接口测试用例", api_case: "接口测试用例",
scenario_case: "场景测试用例", scenario_case: "场景测试用例",
execute_result: "执行结果", execute_result: "执行结果",
test_plan_test_case_count: "功能用例数",
test_plan_api_case_count: "接口用例数",
test_plan_api_scenario_count: "场景用例数",
test_plan_load_case_count: "性能用例数",
load_case: { load_case: {
case: "性能用例", case: "性能用例",
execution_status: "执行状态", execution_status: "执行状态",

View File

@ -1778,6 +1778,10 @@ export default {
api_case: "接口測試用例", api_case: "接口測試用例",
scenario_case: "場景測試用例", scenario_case: "場景測試用例",
execute_result: "執行結果", execute_result: "執行結果",
test_plan_test_case_count: "功能用例數",
test_plan_api_case_count: "接口用例數",
test_plan_api_scenario_count: "場景用例數",
test_plan_load_case_count: "性能用例數",
load_case: { load_case: {
case: "性能用例", case: "性能用例",
execution_status: "執行狀態", execution_status: "執行狀態",