From dd9b03c206b55b32a23f082d5702738ae4f0b7ee Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Thu, 28 May 2020 23:07:53 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95-?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E6=B5=8B=E8=AF=95=E6=88=96=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=E4=BC=9A=E5=88=B7=E6=96=B0=E9=A1=B5=E9=9D=A2=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../report/PerformanceReportView.vue | 108 ++++++++++++------ .../report/components/ErrorLog.vue | 33 ++++-- .../report/components/LogDetails.vue | 24 ++-- .../report/components/RequestStatistics.vue | 26 +++-- .../report/components/TestOverview.vue | 51 +++++++-- 5 files changed, 170 insertions(+), 72 deletions(-) diff --git a/frontend/src/business/components/performance/report/PerformanceReportView.vue b/frontend/src/business/components/performance/report/PerformanceReportView.vue index 1e06df3e67..a53a0fb150 100644 --- a/frontend/src/business/components/performance/report/PerformanceReportView.vue +++ b/frontend/src/business/components/performance/report/PerformanceReportView.vue @@ -37,16 +37,17 @@ - + + - + - + - + @@ -89,6 +90,7 @@ minutes: '0', seconds: '0', title: 'Logging', + report: {} } }, methods: { @@ -108,8 +110,9 @@ }, initReportTimeInfo() { if (this.reportId) { - this.result = this.$get("/performance/report/content/report_time/" + this.reportId, res => { - let data = res.data; + this.result = this.$get("/performance/report/content/report_time/" + this.reportId) + .then(res => { + let data = res.data.data; if (data) { this.startTime = data.startTime; this.endTime = data.endTime; @@ -117,55 +120,90 @@ this.minutes = Math.floor(duration / 60); this.seconds = duration % 60; } + }).catch(() => { + this.clearData(); }) } }, - }, - mounted() { - this.reportId = this.$route.path.split('/')[4]; - this.result = this.$get("/performance/report/" + this.reportId, res => { - let data = res.data; - this.status = data.status; - switch (data.status) { + checkReportStatus(status) { + switch (status) { case 'Error': this.$warning(this.$t('report.generation_error')); break; case 'Starting': + this.$warning("测试处于开始状态,请稍后查看报告!"); + break; case 'Reporting': this.$info(this.$t('report.being_generated')); break; case 'Running': + this.$warning("测试处于运行状态,请稍后查看报告!"); break; + case 'Completed': default: break; } + }, + clearData() { + this.startTime = '0'; + this.endTime = '0'; + this.minutes = '0'; + this.seconds = '0'; + } + }, + created() { + this.reportId = this.$route.path.split('/')[4]; + this.result = this.$get("/performance/report/" + this.reportId, res => { + let data = res.data; + this.status = data.status; + this.$set(this.report, "id", this.reportId); + this.$set(this.report, "status", data.status); + this.checkReportStatus(data.status); + if (this.status === "Completed") { + this.initReportTimeInfo(); + } }) this.initBreadcrumb(); - this.initReportTimeInfo(); + }, watch: { '$route'(to) { - let reportId = to.path.split('/')[4]; - if (reportId) { - this.$get("/performance/report/test/pro/info/" + reportId, response => { - let data = response.data; - if (data) { - this.reportName = data.name; - this.testName = data.testName; - this.projectName = data.projectName; - } - }); - this.result = this.$get("/performance/report/content/report_time/" + this.reportId, res => { - let data = res.data; - if (data) { - this.startTime = data.startTime; - this.endTime = data.endTime; - let duration = data.duration; - this.minutes = Math.floor(duration / 60); - this.seconds = duration % 60; - } - }) - window.location.reload(); + if (to.name === "perReportView") { + let reportId = to.path.split('/')[4]; + this.reportId = reportId; + if (reportId) { + this.$get("/performance/report/test/pro/info/" + reportId, response => { + let data = response.data; + if (data) { + this.status = data.status; + this.reportName = data.name; + this.testName = data.testName; + this.projectName = data.projectName; + + this.$set(this.report, "id", reportId); + this.$set(this.report, "status", data.status); + + this.checkReportStatus(data.status); + if (this.status === "Completed") { + this.result = this.$get("/performance/report/content/report_time/" + this.reportId).then(res => { + let data = res.data.data; + if (data) { + this.startTime = data.startTime; + this.endTime = data.endTime; + let duration = data.duration; + this.minutes = Math.floor(duration / 60); + this.seconds = duration % 60; + } + }).catch(() => { + this.clearData(); + }) + } else { + this.clearData(); + } + } + }); + + } } } } diff --git a/frontend/src/business/components/performance/report/components/ErrorLog.vue b/frontend/src/business/components/performance/report/components/ErrorLog.vue index b9e5239be3..237b3a9579 100644 --- a/frontend/src/business/components/performance/report/components/ErrorLog.vue +++ b/frontend/src/business/components/performance/report/components/ErrorLog.vue @@ -131,27 +131,40 @@ data() { return { tableData: [], - errorTop5: [] + errorTop5: [], + id: '' } }, methods: { initTableData() { - this.$get("/performance/report/content/errors/" + this.id, res => { - this.tableData = res.data; + this.$get("/performance/report/content/errors/" + this.id).then(res => { + this.tableData = res.data.data; + }).catch(() => { + this.tableData = []; }) - this.$get("/performance/report/content/errors_top5/" + this.id, res => { - this.errorTop5 = res.data; + this.$get("/performance/report/content/errors_top5/" + this.id).then(res => { + this.errorTop5 = res.data.data; + }).catch(() => { + this.errorTop5 = []; }) } }, watch: { - status() { - if ("Completed" === this.status) { - this.initTableData() - } + report: { + handler(val){ + let status = val.status; + this.id = val.id; + if (status === "Completed") { + this.initTableData(); + } else { + this.tableData = []; + this.errorTop5 = []; + } + }, + deep:true } }, - props: ['id','status'] + props: ['report'] } diff --git a/frontend/src/business/components/performance/report/components/LogDetails.vue b/frontend/src/business/components/performance/report/components/LogDetails.vue index 2d17185f00..68e184f184 100644 --- a/frontend/src/business/components/performance/report/components/LogDetails.vue +++ b/frontend/src/business/components/performance/report/components/LogDetails.vue @@ -12,17 +12,19 @@ diff --git a/frontend/src/business/components/performance/report/components/RequestStatistics.vue b/frontend/src/business/components/performance/report/components/RequestStatistics.vue index 419f4e372b..907eb7abea 100644 --- a/frontend/src/business/components/performance/report/components/RequestStatistics.vue +++ b/frontend/src/business/components/performance/report/components/RequestStatistics.vue @@ -95,13 +95,16 @@ name: "RequestStatistics", data() { return { - tableData: [] + tableData: [], + id: '' } }, methods: { initTableData() { - this.$get("/performance/report/content/" + this.id, res => { - this.tableData = res.data; + this.$get("/performance/report/content/" + this.id).then(res => { + this.tableData = res.data.data; + }).catch(() => { + this.tableData = []; }) }, getSummaries(param) { @@ -154,13 +157,20 @@ } }, watch: { - status() { - if ("Completed" === this.status) { - this.initTableData() - } + report: { + handler(val){ + let status = val.status; + this.id = val.id; + if (status === "Completed") { + this.initTableData(); + } else { + this.tableData = []; + } + }, + deep:true } }, - props: ['id', 'status'] + props: ['report'] } diff --git a/frontend/src/business/components/performance/report/components/TestOverview.vue b/frontend/src/business/components/performance/report/components/TestOverview.vue index 8f04a363b4..269823ca8b 100644 --- a/frontend/src/business/components/performance/report/components/TestOverview.vue +++ b/frontend/src/business/components/performance/report/components/TestOverview.vue @@ -80,22 +80,31 @@ responseTime90: "0", avgBandwidth: "0", loadOption: {}, - resOption: {} + resOption: {}, + id: '' } }, methods: { initTableData() { - this.$get("/performance/report/content/testoverview/" + this.id, res => { - let data = res.data; + this.$get("/performance/report/content/testoverview/" + this.id).then(res => { + let data = res.data.data; this.maxUsers = data.maxUsers; this.avgThroughput = data.avgThroughput; this.errors = data.errors; this.avgResponseTime = data.avgResponseTime; this.responseTime90 = data.responseTime90; this.avgBandwidth = data.avgBandwidth; + }).catch(() => { + this.maxUsers = '0'; + this.avgThroughput = '0'; + this.errors = '0'; + this.avgResponseTime = '0'; + this.responseTime90 = '0'; + this.avgBandwidth = '0'; + this.$warning("报告生成错误!") }) - this.$get("/performance/report/content/load_chart/" + this.id, res => { - let data = res.data; + this.$get("/performance/report/content/load_chart/" + this.id).then(res => { + let data = res.data.data; let yAxisList = data.filter(m => m.yAxis2 === -1).map(m => m.yAxis); let yAxis2List = data.filter(m => m.yAxis === -1).map(m => m.yAxis2); let yAxisListMax = this._getChartMax(yAxisList); @@ -166,9 +175,11 @@ setting["series"].splice(0, 0, {name: item, yAxisIndex: '1'}) }) this.loadOption = this.generateOption(loadOption, data, setting); + }).catch(() => { + this.loadOption = {}; }) - this.$get("/performance/report/content/res_chart/" + this.id, res => { - let data = res.data; + this.$get("/performance/report/content/res_chart/" + this.id).then(res => { + let data = res.data.data; let yAxisList = data.filter(m => m.yAxis2 === -1).map(m => m.yAxis); let yAxis2List = data.filter(m => m.yAxis === -1).map(m => m.yAxis2); let yAxisListMax = this._getChartMax(yAxisList); @@ -246,6 +257,8 @@ }) this.resOption = this.generateOption(resOption, data, setting); + }).catch(() => { + this.resOption = {}; }) }, generateOption(option, data, setting) { @@ -310,13 +323,27 @@ } }, watch: { - status() { - if ("Completed" === this.status) { - this.initTableData() - } + report: { + handler(val){ + let status = val.status; + this.id = val.id; + if (status === "Completed") { + this.initTableData(); + } else { + this.maxUsers = '0'; + this.avgThroughput = '0'; + this.errors = '0'; + this.avgResponseTime = '0'; + this.responseTime90 = '0'; + this.avgBandwidth = '0'; + this.loadOption = {}; + this.resOption = {}; + } + }, + deep:true } }, - props: ['id', 'status'] + props: ['report'] } From 12931375411e7f9009cc3b7f11892d5e40186b0a Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Thu, 28 May 2020 23:51:27 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= =?UTF-8?q?=E5=85=B3=E8=81=94=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../track/dto/TestPlanCaseDTO.java | 1 + .../view/comonents/TestPlanTestCaseEdit.vue | 30 +++- .../view/comonents/test/ApiTestDetail.vue | 101 +++++++++++++ .../view/comonents/test/ApiTestResult.vue | 136 ++++++++++++++++++ 4 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 frontend/src/business/components/track/plan/view/comonents/test/ApiTestDetail.vue create mode 100644 frontend/src/business/components/track/plan/view/comonents/test/ApiTestResult.vue diff --git a/backend/src/main/java/io/metersphere/track/dto/TestPlanCaseDTO.java b/backend/src/main/java/io/metersphere/track/dto/TestPlanCaseDTO.java index 77e6f886c9..c22192fd59 100644 --- a/backend/src/main/java/io/metersphere/track/dto/TestPlanCaseDTO.java +++ b/backend/src/main/java/io/metersphere/track/dto/TestPlanCaseDTO.java @@ -15,4 +15,5 @@ public class TestPlanCaseDTO extends TestCaseWithBLOBs { private String planName; private String caseId; private String issues; + private String reportId; } diff --git a/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseEdit.vue b/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseEdit.vue index 42f291ae28..40f7ad7cdb 100644 --- a/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseEdit.vue +++ b/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseEdit.vue @@ -89,11 +89,11 @@ - + - + @@ -203,10 +203,14 @@ import MsApiReportView from "../../../../api/report/ApiReportView"; import EditPerformanceTestPlan from "../../../../performance/test/EditPerformanceTestPlan"; import PerformanceReportView from "../../../../performance/report/PerformanceReportView"; + import ApiTestDetail from "./test/ApiTestDetail"; + import ApiTestResult from "./test/ApiTestResult"; export default { name: "TestPlanTestCaseEdit", components: { + ApiTestResult, + ApiTestDetail, PerformanceReportView, EditPerformanceTestPlan, MsApiReportView, MsApiTestConfig, TestPlanTestCaseStatusButton}, data() { @@ -298,6 +302,27 @@ this.showDialog = true; this.initData(testCase); }, + initTest() { + this.$nextTick(() => { + + if (this.testCase.method == 'auto') { + if (this.$refs.apiTestDetail && this.testCase.type == 'api') { + this.$refs.apiTestDetail.init(); + } + // else if(testCase.type == 'api') { + // this.$refs.apiTestDetail.init(); + // } + } + }); + + }, + apiTestRun(reportId) { + this.testCase.reportId = reportId; + this.saveReport(reportId); + }, + saveReport(reportId) { + this.$post('/test/plan/case/edit', {id: this.testCase.id, reportId: reportId}); + }, updateTestCases(testCase) { this.testCases.forEach(item => { if (testCase.id === item.id) { @@ -313,6 +338,7 @@ this.index = i; this.getTestCase(i); this.getRelatedTest(); + this.initTest(); } } }); diff --git a/frontend/src/business/components/track/plan/view/comonents/test/ApiTestDetail.vue b/frontend/src/business/components/track/plan/view/comonents/test/ApiTestDetail.vue new file mode 100644 index 0000000000..1e3141700a --- /dev/null +++ b/frontend/src/business/components/track/plan/view/comonents/test/ApiTestDetail.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/frontend/src/business/components/track/plan/view/comonents/test/ApiTestResult.vue b/frontend/src/business/components/track/plan/view/comonents/test/ApiTestResult.vue new file mode 100644 index 0000000000..d00894b3f8 --- /dev/null +++ b/frontend/src/business/components/track/plan/view/comonents/test/ApiTestResult.vue @@ -0,0 +1,136 @@ + + + + + + From 670a7dfd11bdf82a2f05301c7b28c85ec7dd5119 Mon Sep 17 00:00:00 2001 From: wenyann <64353056+wenyann@users.noreply.github.com> Date: Fri, 29 May 2020 11:05:08 +0800 Subject: [PATCH 03/10] '' --- frontend/src/common/js/ajax.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/common/js/ajax.js b/frontend/src/common/js/ajax.js index a0d27f10ad..1013b80008 100644 --- a/frontend/src/common/js/ajax.js +++ b/frontend/src/common/js/ajax.js @@ -18,6 +18,8 @@ export default { callback: () => { window.location.href = "/login" } + }).then(r => { + }); }; From a3f97c83624aea7f3472700e75c51ae4bbf4f010 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Fri, 29 May 2020 11:05:49 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=8F=8F=E8=BF=B0?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=95=BF=E5=BA=A6=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business/components/project/MsProject.vue | 17 +++++++++++++---- .../components/settings/system/Organization.vue | 2 +- .../settings/system/SystemWorkspace.vue | 2 +- frontend/src/i18n/en-US.js | 3 ++- frontend/src/i18n/zh-CN.js | 3 ++- frontend/src/i18n/zh-TW.js | 3 ++- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/frontend/src/business/components/project/MsProject.vue b/frontend/src/business/components/project/MsProject.vue index a185d93618..da3598bf48 100644 --- a/frontend/src/business/components/project/MsProject.vue +++ b/frontend/src/business/components/project/MsProject.vue @@ -37,10 +37,10 @@ - + - + @@ -87,8 +87,17 @@ rules: { name: [ {required: true, message: this.$t('project.input_name'), trigger: 'blur'}, - {min: 2, max: 50, message: this.$t('commons.input_limit', [2, 50]), trigger: 'blur'} - ] + {min: 2, max: 25, message: this.$t('commons.input_limit', [2, 25]), trigger: 'blur'}, + { + required: true, + pattern: /^(?!-)(?!.*?-$)[a-zA-Z0-9\u4e00-\u9fa5-]+$/, + message: this.$t('project.special_characters_are_not_supported'), + trigger: 'blur' + } + ], + description: [ + {max: 50, message: this.$t('commons.input_limit', [0, 50]), trigger: 'blur'} + ], }, } }, diff --git a/frontend/src/business/components/settings/system/Organization.vue b/frontend/src/business/components/settings/system/Organization.vue index 0150c7e10c..c64a579a1e 100644 --- a/frontend/src/business/components/settings/system/Organization.vue +++ b/frontend/src/business/components/settings/system/Organization.vue @@ -218,7 +218,7 @@ rule: { name: [ {required: true, message: this.$t('organization.input_name'), trigger: 'blur'}, - {min: 2, max: 20, message: this.$t('commons.input_limit', [2, 20]), trigger: 'blur'}, + {min: 2, max: 25, message: this.$t('commons.input_limit', [2, 25]), trigger: 'blur'}, { required: true, pattern: /^[\u4e00-\u9fa5_a-zA-Z0-9.·-]+$/, diff --git a/frontend/src/business/components/settings/system/SystemWorkspace.vue b/frontend/src/business/components/settings/system/SystemWorkspace.vue index 87a6983ac2..dfb8091e9f 100644 --- a/frontend/src/business/components/settings/system/SystemWorkspace.vue +++ b/frontend/src/business/components/settings/system/SystemWorkspace.vue @@ -447,7 +447,7 @@ rules: { name: [ {required: true, message: this.$t('workspace.input_name'), trigger: 'blur'}, - {min: 2, max: 20, message: this.$t('commons.input_limit', [2, 20]), trigger: 'blur'}, + {min: 2, max: 25, message: this.$t('commons.input_limit', [2, 25]), trigger: 'blur'}, { required: true, pattern: /^(?!-)(?!.*?-$)[a-zA-Z0-9\u4e00-\u9fa5-]+$/, diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 4aa8310390..b6da7a8c52 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -114,7 +114,7 @@ export default { 'input_name': 'Please enter a organization name', 'select_organization': 'Please select organization', 'search_by_name': 'Search by name', - 'special_characters_are_not_supported': 'Special characters are not supported', + 'special_characters_are_not_supported': 'Incorrect format (special characters are not supported and cannot end with \'-\')', 'none': 'None Organization', 'select': 'Select Organization', }, @@ -129,6 +129,7 @@ export default { 'input_name': 'Please enter a workspace name', 'owning_workspace': 'Owning Workspace', 'please_choose_workspace': 'Please select Workspace', + 'special_characters_are_not_supported': 'Incorrect format (special characters are not supported and cannot end with \'-\')', }, member: { 'create': 'Create', diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index c0bd508f19..d88a306271 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -113,7 +113,7 @@ export default { 'input_name': '请输入组织名称', 'select_organization': '请选择组织', 'search_by_name': '根据名称搜索', - 'special_characters_are_not_supported': '不支持特殊字符', + 'special_characters_are_not_supported': '格式错误(不支持特殊字符,且不能以\'-\'开头结尾)', 'none': '无组织', 'select': '选择组织', }, @@ -127,6 +127,7 @@ export default { 'input_name': '请输入项目名称', 'owning_workspace': '所属工作空间', 'please_choose_workspace': '请选择工作空间', + 'special_characters_are_not_supported': '格式错误(不支持特殊字符,且不能以\'-\'开头结尾)', }, member: { 'create': '添加成员', diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 44f50b2114..be2a853c98 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -113,7 +113,7 @@ export default { 'input_name': '請輸入組織名稱', 'select_organization': '請選擇組織', 'search_by_name': '根據名稱搜索', - 'special_characters_are_not_supported': '不支持特殊字符', + 'special_characters_are_not_supported': 'Incorrect format (special characters are not supported and cannot end with \'-\')', 'none': '無組織', 'select': '選擇組織', }, @@ -127,6 +127,7 @@ export default { 'input_name': '請輸入項目名稱', 'owning_workspace': '所屬工作空間', 'please_choose_workspace': '請選擇工作空間', + 'special_characters_are_not_supported': '格式錯誤(不支持特殊字符,且不能以\'-\'開頭結尾)', }, member: { 'create': '添加成員', From a07e58e54f173f570f6f8f56670e4ff29887a567 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Fri, 29 May 2020 11:24:00 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=8C=89=E7=85=A7?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=97=B6=E9=97=B4=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/metersphere/base/mapper/ext/ExtProjectMapper.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtProjectMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtProjectMapper.xml index 98874d7480..2ccd8dede8 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtProjectMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtProjectMapper.xml @@ -15,6 +15,7 @@ and w.id = #{proRequest.workspaceId} + order by p.update_time desc