From 9818ea20fe9b461fe6c06a58db4b8ccadb865d10 Mon Sep 17 00:00:00 2001 From: wenyann <64353056+wenyann@users.noreply.github.com> Date: Fri, 26 Mar 2021 18:59:34 +0800 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20jenkins=E8=A7=A6=E5=8F=91=E7=9A=84?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E5=92=8C=E5=9C=BA=E6=99=AF=E6=8A=A5=E5=91=8A=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/api/jmeter/APIBackendListenerClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java index b7886c9379..b8639fbd0e 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -198,11 +198,11 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl apiDefinitionService.addResult(testResult); //测试计划定时任务-接口执行逻辑的话,需要同步测试计划的报告数据 - if (StringUtils.equals(this.runMode, ApiRunMode.SCHEDULE_API_PLAN.name())) { + if (StringUtils.equalsAny(this.runMode, ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) { apiDefinitionExecResultService.saveApiResultByScheduleTask(testResult, ApiRunMode.SCHEDULE_API_PLAN.name()); List testPlanReportIdList = new ArrayList<>(); testPlanReportIdList.add(debugReportId); - for(String testPlanReportId : testPlanReportIdList) { // 更新每个测试计划的状态 + for (String testPlanReportId : testPlanReportIdList) { // 更新每个测试计划的状态 testPlanReportService.checkTestPlanStatus(testPlanReportId); } testPlanReportService.updateReport(testPlanReportIdList, ApiRunMode.SCHEDULE_API_PLAN.name(), ReportTriggerMode.SCHEDULE.name()); From fd34e063ffba9d3ad1608d566880a478afb35991 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Sat, 27 Mar 2021 19:11:12 +0800 Subject: [PATCH 2/4] =?UTF-8?q?refactor(=E5=9C=BA=E6=99=AF=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=8C=96):=20=E8=BF=90=E8=A1=8C=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../automation/scenario/EditApiScenario.vue | 95 ++++++++++++++----- .../api/automation/scenario/EnvPopover.vue | 7 ++ .../api/automation/scenario/Setting.js | 2 +- .../scenario/maximize/MaximizeScenario.vue | 80 ++++++++++++---- .../scenario/maximize/ScenarioHeader.vue | 2 + 5 files changed, 144 insertions(+), 42 deletions(-) diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index 4ebeeea4c4..78c24f661f 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -116,7 +116,9 @@ + :project-list="projectList" ref="envPopover" + :disabled="scenarioDefinition.length < 1" + :is-read-only="scenarioDefinition.length < 1"/> {{$t('api_test.request.debug')}} @@ -201,7 +203,11 @@ @closePage="close" @unFullScreen="unFullScreen" @showAllBtn="showAllBtn" @runDebug="runDebug" @setProjectEnvMap="setProjectEnvMap" @showScenarioParameters="showScenarioParameters" @setCookieShare="setCookieShare" ref="maximizeHeader"/> - + @@ -310,6 +316,8 @@ projectList: [], debugResult: new Map, drawer: false, + isHaveExec: false, + isExecWithOutEnv: true } }, created() { @@ -580,10 +588,27 @@ if (arr[i].type === ELEMENT_TYPE.LoopController && arr[i].loopType === "LOOP_COUNT" && arr[i].hashTree && arr[i].hashTree.length > 1) { arr[i].countController.proceed = true; } - if (!arr[i].projectId) { - // 如果自身没有ID并且场景有ID则赋值场景ID,否则赋值当前项目ID - arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId; + + let type = arr[i].type; + const canExec = this.checkCanExec(type); + if (!this.isHaveExec) { + // 判断此步骤是否可执行 + this.isHaveExec = canExec; } + if (canExec) { + const execWithOutEnv = this.canExecWithOutEnv(type, arr[i].url); + if (!execWithOutEnv) { + if (!arr[i].projectId) { + // 如果自身没有ID并且场景有ID则赋值场景ID,否则赋值当前项目ID + arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId; + } + this.projectIds.add(arr[i].projectId); + } + } + if (this.isExecWithOutEnv) { + this.isExecWithOutEnv = this.canExecWithOutEnv(type, arr[i].url) + } + if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) { this.recursiveSorting(arr[i].hashTree, arr[i].projectId); } @@ -593,7 +618,21 @@ } } }, + canExecWithOutEnv(type, path) { + return type !== ELEMENT_TYPE.HTTPSamplerProxy ? !this.checkCanExec(type) : this.isHTTPFullPath(path); + }, + isHTTPFullPath(path) { + return path ? path.startsWith("http://") || path.startsWith("https://") : false; + }, + checkCanExec(type) { + const allCanExecType = ELEMENTS.get("AllCanExecType"); + const index = allCanExecType.indexOf(type); + return index !== -1; + }, sort() { + this.projectIds.clear(); + this.isHaveExec = false; + this.isExecWithOutEnv = true; for (let i in this.scenarioDefinition) { // 排序 this.scenarioDefinition[i].index = Number(i) + 1; @@ -606,6 +645,23 @@ if (!this.scenarioDefinition[i].projectId) { this.scenarioDefinition[i].projectId = this.projectId; } + + let type = this.scenarioDefinition[i].type; + const canExec = this.checkCanExec(type); + if (!this.isHaveExec) { + // 判断此步骤是否可执行 + this.isHaveExec = canExec; + } + if (canExec) { + const execWithOutEnv = this.canExecWithOutEnv(type, this.scenarioDefinition[i].url); + if (!execWithOutEnv) { + this.projectIds.add(this.scenarioDefinition[i].projectId); + } + } + if (this.isExecWithOutEnv) { + this.isExecWithOutEnv = this.canExecWithOutEnv(type, this.scenarioDefinition[i].url) + } + if (this.scenarioDefinition[i].hashTree != undefined && this.scenarioDefinition[i].hashTree.length > 0) { this.recursiveSorting(this.scenarioDefinition[i].hashTree, this.scenarioDefinition[i].projectId); } @@ -626,7 +682,6 @@ this.customizeRequest = {}; this.sort(); this.reload(); - this.initProjectIds(); }, addScenario(arr) { if (arr && arr.length > 0) { @@ -649,7 +704,6 @@ this.isBtnHide = false; this.sort(); this.reload(); - this.initProjectIds(); }, setApiParameter(item, refType, referenced) { let request = {}; @@ -691,7 +745,6 @@ this.isBtnHide = false; this.sort(); this.reload(); - this.initProjectIds(); }, getMaintainerOptions() { let workspaceId = localStorage.getItem(WORKSPACE_ID); @@ -718,7 +771,6 @@ hashTree.splice(index, 1); this.sort(); this.reload(); - this.initProjectIds(); } } }); @@ -749,10 +801,19 @@ }, runDebug() { /*触发执行操作*/ - let sign = this.$refs.envPopover.checkEnv(); - if (!sign) { + if (!this.isHaveExec) { + this.$warning("无可执行步骤!"); return; } + + // 运行时是否需要检查环境 + if (!this.isExecWithOutEnv) { + let sign = this.$refs.envPopover.checkEnv(); + if (!sign) { + return; + } + } + this.$refs['currentScenario'].validate((valid) => { if (valid) { Promise.all([ @@ -1000,7 +1061,6 @@ } } this.sort(); - this.initProjectIds(); // this.getEnvironments(); }) } @@ -1071,19 +1131,8 @@ }) }, refReload() { - this.initProjectIds(); this.reload(); }, - initProjectIds() { - // 加载环境配置 - this.$nextTick(() => { - this.projectIds.clear(); - this.scenarioDefinition.forEach(data => { - let arr = jsonPath.query(data, "$..projectId"); - arr.forEach(a => this.projectIds.add(a)); - }) - }) - }, detailRefresh(result) { // 把执行结果分发给各个请求 this.debugResult = result; diff --git a/frontend/src/business/components/api/automation/scenario/EnvPopover.vue b/frontend/src/business/components/api/automation/scenario/EnvPopover.vue index f17b968995..bc7296c026 100644 --- a/frontend/src/business/components/api/automation/scenario/EnvPopover.vue +++ b/frontend/src/business/components/api/automation/scenario/EnvPopover.vue @@ -3,6 +3,7 @@ v-model="visible" placement="bottom" width="400" + :disabled="isReadOnly" @show="showPopover" trigger="click"> 1) { arr[i].countController.proceed = true; } - if (!arr[i].projectId) { - arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId; + let type = arr[i].type; + const canExec = this.checkCanExec(type); + if (!this.isHaveExec) { + // 判断此步骤是否可执行 + this.isHaveExec = canExec; + this.$emit("update:isHaveExec", canExec); + } + if (canExec) { + const execWithOutEnv = this.canExecWithOutEnv(type, arr[i].url); + if (!execWithOutEnv) { + if (!arr[i].projectId) { + // 如果自身没有ID并且场景有ID则赋值场景ID,否则赋值当前项目ID + arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId; + } + this.projectIds.add(arr[i].projectId); + this.$emit('update:projectIds', this.projectIds); + } + } + if (this.isExecWithOutEnv) { + this.isExecWithOutEnv = this.canExecWithOutEnv(type, arr[i].url); + this.$emit('update:isExecWithOutEnv', this.canExecWithOutEnv(type, arr[i].url)) } if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) { this.recursiveSorting(arr[i].hashTree, arr[i].projectId); @@ -508,7 +530,24 @@ } } }, + canExecWithOutEnv(type, path) { + return type !== ELEMENT_TYPE.HTTPSamplerProxy ? !this.checkCanExec(type) : this.isHTTPFullPath(path); + }, + isHTTPFullPath(path) { + return path ? path.startsWith("http://") || path.startsWith("https://") : false; + }, + checkCanExec(type) { + const allCanExecType = ELEMENTS.get("AllCanExecType"); + const index = allCanExecType.indexOf(type); + return index !== -1; + }, sort() { + this.projectIds.clear(); + this.$emit('update:projectIds', this.projectIds); + this.isHaveExec = false; + this.isExecWithOutEnv = true; + this.$emit('update:isHaveExec', false); + this.$emit('update:isExecWithOutEnv', true); for (let i in this.scenarioDefinition) { // 排序 this.scenarioDefinition[i].index = Number(i) + 1; @@ -521,6 +560,26 @@ if (!this.scenarioDefinition[i].projectId) { this.scenarioDefinition[i].projectId = this.projectId; } + + let type = this.scenarioDefinition[i].type; + const canExec = this.checkCanExec(type); + if (!this.isHaveExec) { + // 判断此步骤是否可执行 + this.isHaveExec = canExec; + this.$emit('update:isHaveExec', canExec); + } + if (canExec) { + const execWithOutEnv = this.canExecWithOutEnv(type, this.scenarioDefinition[i].url); + if (!execWithOutEnv) { + this.projectIds.add(this.scenarioDefinition[i].projectId); + this.$emit('update:projectIds', this.projectIds); + } + } + if (this.isExecWithOutEnv) { + this.isExecWithOutEnv = this.canExecWithOutEnv(type, this.scenarioDefinition[i].url); + this.$emit('update:isExecWithOutEnv', this.canExecWithOutEnv(type, this.scenarioDefinition[i].url)); + } + if (this.scenarioDefinition[i].hashTree != undefined && this.scenarioDefinition[i].hashTree.length > 0) { this.recursiveSorting(this.scenarioDefinition[i].hashTree, this.scenarioDefinition[i].projectId); } @@ -541,7 +600,6 @@ this.customizeRequest = {}; this.sort(); this.reload(); - this.initProjectIds(); }, addScenario(arr) { if (arr && arr.length > 0) { @@ -559,7 +617,6 @@ } this.sort(); this.reload(); - this.initProjectIds(); this.scenarioVisible = false; }, setApiParameter(item, refType, referenced) { @@ -601,7 +658,6 @@ }); this.sort(); this.reload(); - this.initProjectIds(); }, openTagConfig() { if (!this.projectId) { @@ -622,7 +678,6 @@ hashTree.splice(index, 1); this.sort(); this.reload(); - this.initProjectIds(); } } }); @@ -919,19 +974,8 @@ refReload(data, node) { this.selectedTreeNode = data; this.selectedNode = node; - this.initProjectIds(); this.reload(); }, - initProjectIds() { - // 加载环境配置 - this.$nextTick(() => { - this.projectIds.clear(); - this.scenarioDefinition.forEach(data => { - let arr = jsonPath.query(data, "$..projectId"); - arr.forEach(a => this.projectIds.add(a)); - }) - }) - }, detailRefresh(result) { // 把执行结果分发给各个请求 this.debugResult = result; diff --git a/frontend/src/business/components/api/automation/scenario/maximize/ScenarioHeader.vue b/frontend/src/business/components/api/automation/scenario/maximize/ScenarioHeader.vue index 2588a23bb2..e6382b985c 100644 --- a/frontend/src/business/components/api/automation/scenario/maximize/ScenarioHeader.vue +++ b/frontend/src/business/components/api/automation/scenario/maximize/ScenarioHeader.vue @@ -19,6 +19,8 @@ 共享cookie {{$t('api_test.request.debug')}} From 74c1fafb71846862fad4146ee4c0ae70d530b613 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Mon, 29 Mar 2021 10:47:30 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix(=E6=B5=8B=E8=AF=95=E8=B7=9F=E8=B8=AA):?= =?UTF-8?q?=20=E5=8E=BB=E6=8E=89=E8=AF=84=E5=AE=A1=E5=85=B3=E8=81=94?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E6=97=B6=E7=9A=84=E6=9D=83=E9=99=90=E6=8E=A7?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../track/service/TestCaseReviewService.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/backend/src/main/java/io/metersphere/track/service/TestCaseReviewService.java b/backend/src/main/java/io/metersphere/track/service/TestCaseReviewService.java index 3a6d74178e..3582052a02 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestCaseReviewService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestCaseReviewService.java @@ -331,20 +331,6 @@ public class TestCaseReviewService { } public void testReviewRelevance(ReviewRelevanceRequest request) { - String reviewId = request.getReviewId(); - List userIds = getTestCaseReviewerIds(reviewId); - - String creator = ""; - TestCaseReview review = testCaseReviewMapper.selectByPrimaryKey(reviewId); - if (review != null) { - creator = review.getCreator(); - } - - String currentId = SessionUtils.getUser().getId(); - if (!userIds.contains(currentId) && !StringUtils.equals(creator, currentId)) { - MSException.throwException("没有权限,不能关联用例!"); - } - List testCaseIds = request.getTestCaseIds(); if (testCaseIds.isEmpty()) { From c5e977b091e020232d14bcd90281d30ce89a9fc5 Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Mon, 29 Mar 2021 10:56:14 +0800 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20=E5=B0=9D=E8=AF=95=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E5=9B=BA=E5=AE=9A=E5=88=97=E4=B9=8B=E5=90=8E?= =?UTF-8?q?=E9=94=99=E4=B9=B1=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../automation/scenario/ApiScenarioList.vue | 1307 +++++++++-------- .../components/list/ApiCaseSimpleList.vue | 5 +- .../definition/components/list/ApiList.vue | 5 +- .../track/case/components/TestCaseList.vue | 5 +- .../functional/FunctionalTestCaseList.vue | 5 +- 5 files changed, 671 insertions(+), 656 deletions(-) diff --git a/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue b/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue index 038a86345a..a3b7e1afe8 100644 --- a/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue +++ b/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue @@ -69,7 +69,8 @@ diff --git a/frontend/src/business/components/api/definition/components/list/ApiCaseSimpleList.vue b/frontend/src/business/components/api/definition/components/list/ApiCaseSimpleList.vue index 58c29b614b..6eba64260c 100644 --- a/frontend/src/business/components/api/definition/components/list/ApiCaseSimpleList.vue +++ b/frontend/src/business/components/api/definition/components/list/ApiCaseSimpleList.vue @@ -353,7 +353,10 @@ export default { } }) if (this.$refs.caseTable) { - setTimeout(this.$refs.caseTable.doLayout, 200) + setTimeout(() => { + this.$refs.caseTable.doLayout(); + this.result.loading = false; + }, 500) } this.$nextTick(function(){ this.checkTableRowIsSelect(); diff --git a/frontend/src/business/components/api/definition/components/list/ApiList.vue b/frontend/src/business/components/api/definition/components/list/ApiList.vue index 7a183da83b..7a3ba079aa 100644 --- a/frontend/src/business/components/api/definition/components/list/ApiList.vue +++ b/frontend/src/business/components/api/definition/components/list/ApiList.vue @@ -465,7 +465,10 @@ } }) if (this.$refs.apiDefinitionTable) { - setTimeout(this.$refs.apiDefinitionTable.doLayout, 200) + setTimeout(() => { + this.$refs.apiDefinitionTable.doLayout(); + this.result.loading = false; + }, 500) } // nexttick:表格加载完成之后触发。判断是否需要勾选行 this.$nextTick(function(){ diff --git a/frontend/src/business/components/track/case/components/TestCaseList.vue b/frontend/src/business/components/track/case/components/TestCaseList.vue index cf05354822..a1241f5dd7 100644 --- a/frontend/src/business/components/track/case/components/TestCaseList.vue +++ b/frontend/src/business/components/track/case/components/TestCaseList.vue @@ -393,7 +393,10 @@ export default { item.tags = JSON.parse(item.tags); }) if (this.$refs.table) { - setTimeout(this.$refs.table.doLayout, 200) + setTimeout(() => { + this.$refs.table.doLayout(); + this.result.loading = false; + }, 500) } this.$nextTick(function(){ diff --git a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue index 7c21e48f3a..c23f1847a4 100644 --- a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue @@ -476,7 +476,10 @@ export default { } this.selectRows.clear(); if (this.$refs.table) { - setTimeout(this.$refs.table.doLayout, 200) + setTimeout(() => { + this.$refs.table.doLayout(); + this.result.loading = false; + }, 500) } }); }