Merge remote-tracking branch 'origin/master'

This commit is contained in:
Captain.B 2021-01-28 17:38:23 +08:00
commit 047e662fc9
24 changed files with 271 additions and 192 deletions

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import io.metersphere.api.dto.definition.request.MsTestElement;
import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.api.dto.definition.request.auth.MsAuthManager;
import io.metersphere.api.dto.definition.request.dns.MsDNSCacheManager;
import io.metersphere.api.dto.scenario.Body;
import io.metersphere.api.dto.scenario.KeyValue;
@ -87,6 +88,9 @@ public class MsHTTPSamplerProxy extends MsTestElement {
@JSONField(ordinal = 35)
private Object requestResult;
@JSONField(ordinal = 36)
private MsAuthManager authManager;
@Override
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
if (!this.isEnable()) {
@ -223,6 +227,9 @@ public class MsHTTPSamplerProxy extends MsTestElement {
el.toHashTree(httpSamplerTree, el.getHashTree(), config);
}
}
if (this.authManager != null) {
this.authManager.toHashTree(tree, hashTree, config);
}
}
private boolean isVariable(String path, String value) {

View File

@ -177,6 +177,9 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
} else if (StringUtils.equals(this.runMode, ApiRunMode.JENKINS.name())) {
apiDefinitionService.addResult(testResult);
apiDefinitionExecResultService.saveApiResult(testResult, ApiRunMode.DEFINITION.name());
apiTestService.changeStatus(testId, APITestStatus.Completed);
report = apiReportService.getRunningReport(testResult.getTestId());
apiReportService.complete(testResult, report);
} else if (StringUtils.equalsAny(this.runMode, ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name())) {
apiDefinitionService.addResult(testResult);

View File

@ -88,6 +88,12 @@ public class ApiDefinitionExecResultService {
* @param type
*/
public void saveApiResultByScheduleTask(TestResult result, String type) {
String saveResultType = type;
if(StringUtils.equalsAny(ApiRunMode.SCHEDULE_API_PLAN.name(),saveResultType)){
saveResultType = ApiRunMode.API_PLAN.name();
}
String finalSaveResultType = saveResultType;
result.getScenarios().get(0).getRequestResults().forEach(item -> {
ApiDefinitionExecResult saveResult = new ApiDefinitionExecResult();
saveResult.setId(UUID.randomUUID().toString());
@ -98,7 +104,7 @@ public class ApiDefinitionExecResultService {
saveResult.setStartTime(item.getStartTime());
String status = item.isSuccess() ? "success" : "error";
saveResult.setEndTime(item.getResponseResult().getResponseTime());
saveResult.setType(type);
saveResult.setType(finalSaveResultType);
saveResult.setStatus(status);
String userID = null;
@ -107,6 +113,7 @@ public class ApiDefinitionExecResultService {
String scheduleCreateUser = testPlanService.findScheduleCreateUserById(apiCase.getTestPlanId());
userID = scheduleCreateUser;
apiCase.setStatus(status);
apiCase.setUpdateTime(System.currentTimeMillis());
testPlanApiCaseService.updateByPrimaryKeySelective(apiCase);
} else {
userID = Objects.requireNonNull(SessionUtils.getUser()).getId();

View File

@ -27,25 +27,23 @@ import java.util.*;
*/
public class TestPlanTestJob extends MsScheduleJob {
private String projectID;
private Map<String,String> planScenarioIdMap;
private Map<String,String> apiTestCaseIdMap;
private Map<String,String> performanceIdMap;
private PerformanceTestService performanceTestService;
private TestPlanScenarioCaseService testPlanScenarioCaseService;
private TestPlanApiCaseService testPlanApiCaseService;
private ApiTestCaseService apiTestCaseService;
private TestPlanReportService testPlanReportService;
private TestPlanLoadCaseService testPlanLoadCaseService;
// private PerformanceTestService performanceTestService;
// private TestPlanScenarioCaseService testPlanScenarioCaseService;
// private TestPlanApiCaseService testPlanApiCaseService;
// private ApiTestCaseService apiTestCaseService;
// private TestPlanReportService testPlanReportService;
// private TestPlanLoadCaseService testPlanLoadCaseService;
private TestPlanService testPlanService;
public TestPlanTestJob() {
this.performanceTestService = CommonBeanFactory.getBean(PerformanceTestService.class);
this.testPlanScenarioCaseService = CommonBeanFactory.getBean(TestPlanScenarioCaseService.class);
this.testPlanApiCaseService = CommonBeanFactory.getBean(TestPlanApiCaseService.class);
this.apiTestCaseService = CommonBeanFactory.getBean(ApiTestCaseService.class);
this.testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
this.testPlanLoadCaseService = CommonBeanFactory.getBean(TestPlanLoadCaseService.class);
// this.performanceTestService = CommonBeanFactory.getBean(PerformanceTestService.class);
// this.testPlanScenarioCaseService = CommonBeanFactory.getBean(TestPlanScenarioCaseService.class);
// this.testPlanApiCaseService = CommonBeanFactory.getBean(TestPlanApiCaseService.class);
// this.apiTestCaseService = CommonBeanFactory.getBean(ApiTestCaseService.class);
// this.testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
// this.testPlanLoadCaseService = CommonBeanFactory.getBean(TestPlanLoadCaseService.class);
this.testPlanService = CommonBeanFactory.getBean(TestPlanService.class);
@ -67,100 +65,14 @@ public class TestPlanTestJob extends MsScheduleJob {
this.expression = jobDataMap.getString("expression");
this.projectID = jobDataMap.getString("projectId");
planScenarioIdMap = new LinkedHashMap<>();
apiTestCaseIdMap = new LinkedHashMap<>();
performanceIdMap = new LinkedHashMap<>();
List<TestPlanApiScenario> testPlanApiScenarioList = testPlanScenarioCaseService.getCasesByPlanId(this.resourceId);
for (TestPlanApiScenario model :testPlanApiScenarioList) {
planScenarioIdMap.put(model.getApiScenarioId(),model.getId());
}
List<TestPlanApiCase> testPlanApiCaseList = testPlanApiCaseService.getCasesByPlanId(this.resourceId);
for (TestPlanApiCase model :
testPlanApiCaseList) {
apiTestCaseIdMap.put(model.getApiCaseId(),model.getId());
}
LoadCaseRequest loadCaseRequest = new LoadCaseRequest();
loadCaseRequest.setTestPlanId(this.resourceId);
loadCaseRequest.setProjectId(this.projectID);
List<TestPlanLoadCaseDTO> testPlanLoadCaseDTOList = testPlanLoadCaseService.list(loadCaseRequest);
for (TestPlanLoadCaseDTO dto : testPlanLoadCaseDTOList) {
performanceIdMap.put(dto.getId(),dto.getLoadCaseId());
}
businessExecute(context);
}
@Override
void businessExecute(JobExecutionContext context) {
LogUtil.info("-------------- start testplan schedule ----------");
//首先创建testPlanReport然后返回的ID重新赋值为resourceID作为后续的参数
TestPlanReport testPlanReport = testPlanReportService.genTestPlanReport(this.resourceId,this.userId,ReportTriggerMode.SCHEDULE.name());
//执行接口案例任务
for (Map.Entry<String,String> entry: this.apiTestCaseIdMap.entrySet()) {
String apiCaseID = entry.getKey();
String planCaseID = entry.getValue();
ApiTestCaseWithBLOBs blobs = apiTestCaseService.get(apiCaseID);
//需要更新这里来保证PlanCase的状态能正常更改
apiTestCaseService.run(blobs,UUID.randomUUID().toString(),testPlanReport.getId(),this.resourceId,ApiRunMode.SCHEDULE_API_PLAN.name());
}
//执行场景执行任务
if(!planScenarioIdMap.isEmpty()){
LogUtil.info("-------------- testplan schedule ---------- api case over -----------------");
SchedulePlanScenarioExecuteRequest scenarioRequest = new SchedulePlanScenarioExecuteRequest();
String senarionReportID = UUID.randomUUID().toString();
scenarioRequest.setId(senarionReportID);
scenarioRequest.setReportId(senarionReportID);
scenarioRequest.setProjectId(projectID);
scenarioRequest.setTriggerMode(ReportTriggerMode.SCHEDULE.name());
scenarioRequest.setExecuteType(ExecuteType.Saved.name());
Map<String, Map<String,String>> testPlanScenarioIdMap = new HashMap<>();
testPlanScenarioIdMap.put(resourceId, this.planScenarioIdMap);
scenarioRequest.setTestPlanScenarioIDMap(testPlanScenarioIdMap);
scenarioRequest.setReportUserID(this.userId);
scenarioRequest.setTestPlanID(this.resourceId);
scenarioRequest.setRunMode(ApiRunMode.SCHEDULE_SCENARIO_PLAN.name());
scenarioRequest.setTestPlanReportId(testPlanReport.getId());
testPlanService.runScenarioCase(scenarioRequest);
LogUtil.info("-------------- testplan schedule ---------- scenario case over -----------------");
}
//执行性能测试任务
List<String> performaneReportIDList = new ArrayList<>();
for (Map.Entry<String,String> entry: this.performanceIdMap.entrySet()) {
String id = entry.getKey();
String caseID = entry.getValue();
RunTestPlanRequest performanceRequest = new RunTestPlanRequest();
performanceRequest.setId(caseID);
performanceRequest.setTestPlanLoadId(caseID);
performanceRequest.setTriggerMode(ReportTriggerMode.TEST_PLAN_SCHEDULE.name());
String reportId = null;
try {
reportId = performanceTestService.run(performanceRequest);
if(reportId!=null){
performaneReportIDList.add(reportId);
TestPlanLoadCase testPlanLoadCase = new TestPlanLoadCase();
testPlanLoadCase.setId(performanceRequest.getTestPlanLoadId());
testPlanLoadCase.setLoadReportId(reportId);
testPlanLoadCaseService.update(testPlanLoadCase);
}
}catch (Exception e){
e.printStackTrace();
}
//更新关联处的报告
TestPlanLoadCase loadCase = new TestPlanLoadCaseDTO();
loadCase.setId(id);
loadCase.setLoadReportId(reportId);
testPlanLoadCaseService.update(loadCase);
}
if(!performaneReportIDList.isEmpty()){
//性能测试时保存性能测试报告ID在结果返回时用于捕捉并进行
testPlanReportService.updatePerformanceInfo(testPlanReport,performaneReportIDList,ReportTriggerMode.SCHEDULE.name());
}
testPlanService.run(this.resourceId,this.projectID,this.userId,ReportTriggerMode.SCHEDULE.name());
}
public static JobKey getJobKey(String testId) {

View File

@ -15,6 +15,7 @@ import io.metersphere.track.dto.TestPlanDTOWithMetric;
import io.metersphere.track.request.testcase.PlanCaseRelevanceRequest;
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
import io.metersphere.track.request.testplan.AddTestPlanRequest;
import io.metersphere.track.request.testplan.TestplanRunRequest;
import io.metersphere.track.request.testplancase.TestCaseRelevanceRequest;
import io.metersphere.track.service.TestPlanProjectService;
import io.metersphere.track.service.TestPlanService;
@ -136,4 +137,8 @@ public class TestPlanController {
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
return PageUtils.setPageInfo(page, testPlanProjectService.getProjectByPlanId(request));
}
@PostMapping("/testplan/jenkins")
public void runJenkins(@RequestBody TestplanRunRequest testplanRunRequest){
testPlanService.run(testplanRunRequest.getTestPlanID(),testplanRunRequest.getProjectID(),testplanRunRequest.getUserId(),testplanRunRequest.getTriggerMode());
}
}

View File

@ -0,0 +1,15 @@
package io.metersphere.track.request.testplan;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class TestplanRunRequest {
private String testPlanID;
private String projectID;
private String userId;
private String triggerMode;
}

View File

@ -362,8 +362,12 @@ public class TestPlanReportService {
testPlan.setStatus(TestPlanStatus.Completed.name());
testPlanMapper.updateByPrimaryKeySelective(testPlan);
}
//发送通知
sendMessage(report);
if(StringUtils.equalsAny(report.getTriggerMode(),ReportTriggerMode.SCHEDULE.name())){
//发送通知
sendMessage(report);
}
} catch (Exception e) {
}
@ -401,11 +405,20 @@ public class TestPlanReportService {
paramMap.put("type", "testPlan");
paramMap.put("url", url);
paramMap.put("status", testPlanReport.getStatus());
String successfulMailTemplate = "";
String errfoMailTemplate = "";
if(StringUtils.equals(testPlanReport.getTriggerMode(),ReportTriggerMode.SCHEDULE.name())){
successfulMailTemplate = "TestPlanSuccessfulNotification";
errfoMailTemplate = "TestPlanFailedNotification";
}
NoticeModel noticeModel = NoticeModel.builder()
.successContext(successContext)
.successMailTemplate("TestPlanSuccessfulNotification")
.successMailTemplate(successfulMailTemplate)
.failedContext(failedContext)
.failedMailTemplate("TestPlanFailedNotification")
.failedMailTemplate(errfoMailTemplate)
.testId(testPlan.getId())
.status(testPlanReport.getStatus())
.event(event)

View File

@ -7,16 +7,14 @@ import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.automation.ApiScenarioDTO;
import io.metersphere.api.dto.automation.ScenarioStatus;
import io.metersphere.api.dto.automation.SchedulePlanScenarioExecuteRequest;
import io.metersphere.api.dto.automation.TestPlanScenarioRequest;
import io.metersphere.api.dto.automation.*;
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
import io.metersphere.api.dto.definition.request.*;
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.service.ApiAutomationService;
import io.metersphere.api.service.ApiTestCaseService;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.*;
@ -28,6 +26,7 @@ import io.metersphere.dto.BaseSystemConfigDTO;
import io.metersphere.i18n.Translator;
import io.metersphere.notice.sender.NoticeModel;
import io.metersphere.notice.service.NoticeSendService;
import io.metersphere.performance.service.PerformanceTestService;
import io.metersphere.service.ScheduleService;
import io.metersphere.service.SystemParameterService;
import io.metersphere.track.Factory.ReportComponentFactory;
@ -37,6 +36,7 @@ import io.metersphere.track.request.testcase.PlanCaseRelevanceRequest;
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
import io.metersphere.track.request.testplan.AddTestPlanRequest;
import io.metersphere.track.request.testplan.LoadCaseRequest;
import io.metersphere.track.request.testplan.RunTestPlanRequest;
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
@ -109,6 +109,10 @@ public class TestPlanService {
private ExtTestPlanLoadCaseMapper extTestPlanLoadCaseMapper;
@Resource
private ExtTestPlanScenarioCaseMapper extTestPlanScenarioCaseMapper;
@Resource
private ApiTestCaseService apiTestCaseService;
@Resource
private PerformanceTestService performanceTestService;
public synchronized void addTestPlan(AddTestPlanRequest testPlan) {
if (getTestPlanByName(testPlan.getName()).size() > 0) {
@ -858,4 +862,100 @@ public class TestPlanService {
jMeterService.runDefinition(request.getId(), jmeterHashTree, request.getReportId(), runMode);
return request.getId();
}
public void run(String testPlanID,String projectID,String userId,String triggerMode){
Map<String,String> planScenarioIdMap;
Map<String,String> apiTestCaseIdMap;
Map<String,String> performanceIdMap;
planScenarioIdMap = new LinkedHashMap<>();
apiTestCaseIdMap = new LinkedHashMap<>();
performanceIdMap = new LinkedHashMap<>();
List<TestPlanApiScenario> testPlanApiScenarioList = testPlanScenarioCaseService.getCasesByPlanId(testPlanID);
for (TestPlanApiScenario model :testPlanApiScenarioList) {
planScenarioIdMap.put(model.getApiScenarioId(),model.getId());
}
List<TestPlanApiCase> testPlanApiCaseList = testPlanApiCaseService.getCasesByPlanId(testPlanID);
for (TestPlanApiCase model :
testPlanApiCaseList) {
apiTestCaseIdMap.put(model.getApiCaseId(),model.getId());
}
LoadCaseRequest loadCaseRequest = new LoadCaseRequest();
loadCaseRequest.setTestPlanId(testPlanID);
loadCaseRequest.setProjectId(projectID);
List<TestPlanLoadCaseDTO> testPlanLoadCaseDTOList = testPlanLoadCaseService.list(loadCaseRequest);
for (TestPlanLoadCaseDTO dto : testPlanLoadCaseDTOList) {
performanceIdMap.put(dto.getId(),dto.getLoadCaseId());
}
LogUtil.info("-------------- start testplan schedule ----------");
TestPlanReportService testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
//首先创建testPlanReport然后返回的ID重新赋值为resourceID作为后续的参数
TestPlanReport testPlanReport = testPlanReportService.genTestPlanReport(testPlanID,userId,triggerMode);
//执行接口案例任务
for (Map.Entry<String,String> entry: apiTestCaseIdMap.entrySet()) {
String apiCaseID = entry.getKey();
String planCaseID = entry.getValue();
ApiTestCaseWithBLOBs blobs = apiTestCaseService.get(apiCaseID);
//需要更新这里来保证PlanCase的状态能正常更改
apiTestCaseService.run(blobs,UUID.randomUUID().toString(),testPlanReport.getId(),testPlanID,ApiRunMode.SCHEDULE_API_PLAN.name());
}
//执行场景执行任务
if(!planScenarioIdMap.isEmpty()){
LogUtil.info("-------------- testplan schedule ---------- api case over -----------------");
SchedulePlanScenarioExecuteRequest scenarioRequest = new SchedulePlanScenarioExecuteRequest();
String senarionReportID = UUID.randomUUID().toString();
scenarioRequest.setId(senarionReportID);
scenarioRequest.setReportId(senarionReportID);
scenarioRequest.setProjectId(projectID);
scenarioRequest.setTriggerMode(ReportTriggerMode.SCHEDULE.name());
scenarioRequest.setExecuteType(ExecuteType.Saved.name());
Map<String, Map<String,String>> testPlanScenarioIdMap = new HashMap<>();
testPlanScenarioIdMap.put(testPlanID, planScenarioIdMap);
scenarioRequest.setTestPlanScenarioIDMap(testPlanScenarioIdMap);
scenarioRequest.setReportUserID(userId);
scenarioRequest.setTestPlanID(testPlanID);
scenarioRequest.setRunMode(ApiRunMode.SCHEDULE_SCENARIO_PLAN.name());
scenarioRequest.setTestPlanReportId(testPlanReport.getId());
this.runScenarioCase(scenarioRequest);
LogUtil.info("-------------- testplan schedule ---------- scenario case over -----------------");
}
//执行性能测试任务
List<String> performaneReportIDList = new ArrayList<>();
for (Map.Entry<String,String> entry: performanceIdMap.entrySet()) {
String id = entry.getKey();
String caseID = entry.getValue();
RunTestPlanRequest performanceRequest = new RunTestPlanRequest();
performanceRequest.setId(caseID);
performanceRequest.setTestPlanLoadId(caseID);
performanceRequest.setTriggerMode(ReportTriggerMode.TEST_PLAN_SCHEDULE.name());
String reportId = null;
try {
reportId = performanceTestService.run(performanceRequest);
if(reportId!=null){
performaneReportIDList.add(reportId);
TestPlanLoadCase testPlanLoadCase = new TestPlanLoadCase();
testPlanLoadCase.setId(performanceRequest.getTestPlanLoadId());
testPlanLoadCase.setLoadReportId(reportId);
testPlanLoadCaseService.update(testPlanLoadCase);
}
}catch (Exception e){
e.printStackTrace();
}
//更新关联处的报告
TestPlanLoadCase loadCase = new TestPlanLoadCaseDTO();
loadCase.setId(id);
loadCase.setLoadReportId(reportId);
testPlanLoadCaseService.update(loadCase);
}
if(!performaneReportIDList.isEmpty()){
//性能测试时保存性能测试报告ID在结果返回时用于捕捉并进行
testPlanReportService.updatePerformanceInfo(testPlanReport,performaneReportIDList,ReportTriggerMode.SCHEDULE.name());
}
}
}

View File

@ -1,15 +1,17 @@
<template>
<el-card class="api-component">
<div class="header" @click="active(data)">
<fieldset :disabled="data.disabled" class="ms-fieldset">
<slot name="beforeHeaderLeft">
<div v-if="data.index" class="el-step__icon is-text" style="margin-right: 10px;" :style="{'color': color, 'background-color': backgroundColor}">
<div class="el-step__icon-inner">{{data.index}}</div>
</div>
<el-button class="ms-left-buttion" size="small" :style="{'color': color, 'background-color': backgroundColor}">{{title}}</el-button>
</slot>
<div class="header" @click="active(data)">
<span @click.stop>
<slot name="beforeHeaderLeft">
<div v-if="data.index" class="el-step__icon is-text" style="margin-right: 10px;" :style="{'color': color, 'background-color': backgroundColor}">
<div class="el-step__icon-inner">{{data.index}}</div>
</div>
<el-button class="ms-left-buttion" size="small" :style="{'color': color, 'background-color': backgroundColor}">{{title}}</el-button>
</slot>
<span @click.stop>
<slot name="headerLeft">
<i class="icon el-icon-arrow-right" :class="{'is-active': data.active}"
@click="active(data)" v-if="data.type!='scenario'"/>
@ -17,36 +19,35 @@
@blur="isShowInput = false" :placeholder="$t('commons.input_name')" ref="nameEdit"/>
<span v-else>
{{data.name}}
<i class="el-icon-edit" style="cursor:pointer" @click="editName" v-tester v-if="data.referenced!='REF'"/>
<i class="el-icon-edit" style="cursor:pointer" @click="editName" v-tester v-if="data.referenced!='REF' && !data.disabled"/>
</span>
</slot>
<slot name="behindHeaderLeft"></slot>
</span>
<div class="header-right" @click.stop>
<slot name="message"></slot>
<el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top">
<el-switch v-model="data.enable" class="enable-switch"/>
</el-tooltip>
<slot name="button"></slot>
<el-tooltip content="Copy" placement="top">
<el-button size="mini" icon="el-icon-copy-document" circle @click="copyRow"/>
</el-tooltip>
<el-tooltip :content="$t('commons.remove')" placement="top">
<el-button size="mini" icon="el-icon-delete" type="danger" circle @click="remove"/>
</el-tooltip>
<div class="header-right" @click.stop>
<slot name="message"></slot>
<el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top">
<el-switch v-model="data.enable" class="enable-switch"/>
</el-tooltip>
<slot name="button"></slot>
<el-tooltip content="Copy" placement="top">
<el-button size="mini" icon="el-icon-copy-document" circle @click="copyRow"/>
</el-tooltip>
<el-tooltip :content="$t('commons.remove')" placement="top">
<el-button size="mini" icon="el-icon-delete" type="danger" circle @click="remove"/>
</el-tooltip>
</div>
</div>
</div>
<div class="header">
<el-collapse-transition>
<div v-if="data.active && showCollapse" :draggable="draggable">
<fieldset :disabled="data.disabled" class="ms-fieldset">
<div class="header">
<el-collapse-transition>
<div v-if="data.active && showCollapse" :draggable="draggable">
<el-divider></el-divider>
<slot></slot>
</fieldset>
</div>
</el-collapse-transition>
</div>
</div>
</el-collapse-transition>
</div>
</fieldset>
</el-card>
</template>
@ -150,6 +151,7 @@
.enable-switch {
margin-right: 10px;
}
fieldset {
padding: 0px;
margin: 0px;

View File

@ -107,6 +107,15 @@
this.request.url = undefined;
}
}
// auth
if (this.request.hashTree) {
for (let index in this.request.hashTree) {
if (this.request.hashTree[index].type == 'AuthManager') {
this.request.authManager = this.request.hashTree[index];
this.request.hashTree.splice(index, 1);
}
}
}
}
},
computed: {

View File

@ -70,6 +70,8 @@
case ELEMENT_TYPE.scenario:
name = "MsApiScenarioComponent";
break;
case "AuthManager":
break;
default:
name = "MsApiComponent";
break;
@ -107,7 +109,7 @@
suggestClick(node) {
this.$emit('suggestClick', node);
},
refReload(){
refReload() {
this.$emit('refReload');
}
}

View File

@ -59,6 +59,7 @@
<div v-else-if="item.type=== 'ADD'" class="ms-api-div">
<ms-api-config :syncTabs="syncTabs" @runTest="runTest" @saveApi="saveApi" @createRootModel="createRootModel" ref="apiConfig"
:current-api="item.api"
:project-id="projectId"
:currentProtocol="currentProtocol"
:moduleOptions="moduleOptions"/>
</div>
@ -76,14 +77,14 @@
<!-- 测试-->
<div v-else-if="item.type=== 'TEST'" class="ms-api-div">
<ms-run-test-http-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi"
@refresh="refresh" v-if="currentProtocol==='HTTP'"/>
<ms-run-test-tcp-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi"
@refresh="refresh" v-if="currentProtocol==='TCP'"/>
<ms-run-test-sql-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi"
@refresh="refresh" v-if="currentProtocol==='SQL'"/>
<ms-run-test-dubbo-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi"
@refresh="refresh" v-if="currentProtocol==='DUBBO'"/>
<ms-run-test-http-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" :project-id="projectId"
@saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='HTTP'"/>
<ms-run-test-tcp-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" :project-id="projectId"
@saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='TCP'"/>
<ms-run-test-sql-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" :project-id="projectId"
@saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='SQL'"/>
<ms-run-test-dubbo-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" :project-id="projectId"
@saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='DUBBO'"/>
</div>
</el-tab-pane>
@ -186,8 +187,12 @@
}],
isApiListEnable: true,
syncTabs: [],
projectId: ""
}
},
mounted() {
this.projectId = getCurrentProjectID();
},
watch: {
currentProtocol() {
this.handleCommand("CLOSE_ALL");
@ -248,7 +253,7 @@
}
},
handleTabAdd(e) {
if (!getCurrentProjectID()) {
if (!this.projectId) {
this.$warning(this.$t('commons.check_project_tip'));
return;
}
@ -286,7 +291,7 @@
this.$refs.nodeTree.createRootModel();
},
handleTabsEdit(targetName, action, api) {
if (!getCurrentProjectID()) {
if (!this.projectId) {
this.$warning(this.$t('commons.check_project_tip'));
return;
}
@ -325,7 +330,7 @@
this.$warning('用例列表暂不支持导出,请切换成接口列表');
return;
}
let obj = {projectName: getCurrentProjectID(), protocol: this.currentProtocol}
let obj = {projectName: this.projectId, protocol: this.currentProtocol}
if (this.$refs.apiList[0].selectRows && this.$refs.apiList[0].selectRows.size > 0) {
let arr = Array.from(this.$refs.apiList[0].selectRows);
obj.data = arr;
@ -339,7 +344,7 @@
["status", ["Prepare", "Underway", "Completed"]],
]
);
condition.projectId = getCurrentProjectID();
condition.projectId = this.projectId;
this.$post(url, condition, response => {
obj.data = response.data;
this.buildApiPath(obj.data);

View File

@ -38,7 +38,6 @@
request: Sampler,
config: {},
response: {},
projectId: "",
maintainerOptions: [],
}
},
@ -47,9 +46,9 @@
moduleOptions: {},
currentProtocol: String,
syncTabs: Array,
projectId: String
},
created() {
this.projectId = getCurrentProjectID();
this.getMaintainerOptions();
switch (this.currentProtocol) {
case Request.TYPES.SQL:

View File

@ -3,7 +3,7 @@
<!-- 认证-->
<el-tab-pane :label="$t('api_test.definition.request.verified')" name="verified">
<el-form :model="authConfig" size="small" :rules="rule" ref="authConfig">
<el-form :model="authConfig" :rules="rule" ref="authConfig" label-position="right" label-width="80px">
<el-form-item :label="$t('api_test.definition.request.verification_method')" prop="verification">
<el-select v-model="authConfig.verification" @change="change"
:placeholder="$t('api_test.definition.request.verification_method')" filterable size="small">
@ -50,9 +50,7 @@
</el-select>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
</template>
@ -66,11 +64,17 @@
request: {},
},
created() {
for (let index in this.request.hashTree) {
if (this.request.hashTree[index].type == 'AuthManager') {
this.authConfig = this.request.hashTree[index];
if (this.request.hashTree) {
for (let index in this.request.hashTree) {
if (this.request.hashTree[index].type == 'AuthManager') {
this.request.authManager = this.request.hashTree[index];
this.request.hashTree.splice(index, 1);
}
}
}
if (this.request.authManager) {
this.authConfig = this.request.authManager;
}
},
data() {
return {

View File

@ -147,7 +147,6 @@
saveApiAndCase(api) {
this.visible = true;
this.api = api;
console.log(api)
this.addCase();
},
setEnvironment(environment) {

View File

@ -198,22 +198,18 @@
},
urlChange() {
if (!this.debugForm.url) return;
let url = this.getURL(this.addProtocol(this.debugForm.url));
if (url) {
let url = this.getURL(this.debugForm.url);
if (url && url.pathname) {
if (this.debugForm.url.indexOf('?') != -1) {
this.debugForm.url = decodeURIComponent(this.debugForm.url.substr(0, this.debugForm.url.indexOf("?")));
}
this.debugForm.path = url.pathname;
} else {
this.debugForm.path = url;
}
},
addProtocol(url) {
if (url) {
if (!url.toLowerCase().startsWith("https") && !url.toLowerCase().startsWith("http")) {
return "https://" + url;
}
}
return url;
},
getURL(urlStr) {
try {
let url = new URL(urlStr);
@ -224,7 +220,7 @@
});
return url;
} catch (e) {
this.$error(this.$t('api_test.request.url_invalid'), 2000);
return urlStr;
}
},
}

View File

@ -44,7 +44,7 @@
</template>
<script>
import {downloadFile, getUUID, getCurrentProjectID} from "@/common/js/utils";
import {downloadFile, getUUID} from "@/common/js/utils";
import MsApiCaseList from "../case/ApiCaseList";
import MsContainer from "../../../../common/components/MsContainer";
import MsBottomContainer from "../BottomContainer";
@ -89,7 +89,7 @@
reportId: "",
}
},
props: {apiData: {}, currentProtocol: String,syncTabs: Array},
props: {apiData: {}, currentProtocol: String,syncTabs: Array, projectId: String},
methods: {
handleCommand(e) {
switch (e) {
@ -187,7 +187,7 @@
}
},
getEnvironments() {
this.$get('/api/environment/list/' + getCurrentProjectID(), response => {
this.$get('/api/environment/list/' + this.projectId, response => {
this.environments = response.data;
this.environments.forEach(environment => {
parseEnvironment(environment);
@ -207,7 +207,7 @@
});
},
openEnvironmentConfig() {
this.$refs.environmentConfig.open(getCurrentProjectID());
this.$refs.environmentConfig.open(this.projectId);
},
environmentChange(value) {
for (let i in this.environments) {

View File

@ -110,10 +110,9 @@
},
runData: [],
reportId: "",
projectId: "",
}
},
props: {apiData: {}, currentProtocol: String, syncTabs: Array},
props: {apiData: {}, currentProtocol: String, syncTabs: Array, projectId: String},
methods: {
handleCommand(e) {
switch (e) {
@ -232,7 +231,6 @@
}
},
created() {
this.projectId = getCurrentProjectID();
//
this.api = JSON.parse(JSON.stringify(this.apiData));
this.api.protocol = this.currentProtocol;

View File

@ -44,7 +44,7 @@
</template>
<script>
import {downloadFile, getUUID, getCurrentProjectID} from "@/common/js/utils";
import {downloadFile, getUUID} from "@/common/js/utils";
import MsApiCaseList from "../case/ApiCaseList";
import MsContainer from "../../../../common/components/MsContainer";
import MsBottomContainer from "../BottomContainer";
@ -89,7 +89,7 @@
reportId: "",
}
},
props: {apiData: {}, currentProtocol: String,syncTabs: Array},
props: {apiData: {}, currentProtocol: String,syncTabs: Array, projectId: String},
methods: {
handleCommand(e) {
switch (e) {
@ -186,7 +186,7 @@
}
},
getEnvironments() {
this.$get('/api/environment/list/' + getCurrentProjectID(), response => {
this.$get('/api/environment/list/' + this.projectId, response => {
this.environments = response.data;
this.environments.forEach(environment => {
parseEnvironment(environment);
@ -206,7 +206,7 @@
});
},
openEnvironmentConfig() {
this.$refs.environmentConfig.open(getCurrentProjectID());
this.$refs.environmentConfig.open(this.projectId);
},
environmentChange(value) {
for (let i in this.environments) {

View File

@ -96,10 +96,9 @@
},
runData: [],
reportId: "",
projectId: ""
}
},
props: {apiData: {}, currentProtocol: String,syncTabs: Array},
props: {apiData: {}, currentProtocol: String,syncTabs: Array, projectId: String},
methods: {
handleCommand(e) {
switch (e) {
@ -214,7 +213,6 @@
this.api = JSON.parse(JSON.stringify(this.apiData));
this.api.protocol = this.currentProtocol;
this.currentRequest = this.api.request;
this.projectId = getCurrentProjectID();
this.getResult();
}
}

View File

@ -143,7 +143,12 @@
copyRow(row) {
let obj = JSON.parse(JSON.stringify(row));
obj.id = getUUID();
this.request.hashTree.push(obj);
const index = this.request.hashTree.findIndex(d => d.id === row.id);
if (index != -1) {
this.request.hashTree.splice(index, 0, obj);
} else {
this.request.hashTree.push(obj);
}
this.reload();
},
reload() {

View File

@ -530,7 +530,7 @@ export default {
request: {
grade_info: "Filter by rank",
grade_order_asc: "from high to low by use case level",
grade_order_desc: "from high to low by use case level,",
grade_order_desc: "from low to high by use case level,",
create_time_order_asc: "by creation time from front to back",
create_time_order_desc: "from back to front by creation time,",
update_time_order_asc: "by update time from front to back",

View File

@ -530,7 +530,7 @@ export default {
request: {
grade_info: "按等级筛选",
grade_order_asc: "按用例等级从高到低",
grade_order_desc: "按用例等级从高到低",
grade_order_desc: "按用例等级从到高",
create_time_order_asc: "按创建时间从前到后",
create_time_order_desc: "按创建时间从后到前",
update_time_order_asc: "按更新时间从前到后",

View File

@ -529,7 +529,7 @@ export default {
request: {
grade_info: "按等級篩選",
grade_order_asc: "按用例等級從高到低",
grade_order_desc: "按用例等級從高到低",
grade_order_desc: "按用例等級從到高",
create_time_order_asc: "按創建時間從前到後",
create_time_order_desc: "按創建時間從後到前",
update_time_order_asc: "按更新時間從前到後",