Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MeterSphere
metersphere
提交
509e5c9f
M
metersphere
项目概览
MeterSphere
/
metersphere
上一次同步 大约 3 年
通知
25
Star
1
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
metersphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
509e5c9f
编写于
8月 18, 2020
作者:
W
wenyann
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(LDAP): 测试报告导出
上级
1cff9c1d
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
499 addition
and
379 deletion
+499
-379
frontend/package.json
frontend/package.json
+1
-0
frontend/src/business/components/api/report/ApiReportView.vue
...tend/src/business/components/api/report/ApiReportView.vue
+36
-3
frontend/src/business/components/common/components/MsPieChart.vue
.../src/business/components/common/components/MsPieChart.vue
+2
-1
frontend/src/business/components/performance/report/PerformanceReportView.vue
...s/components/performance/report/PerformanceReportView.vue
+261
-233
frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/ExportTestCaseReport.vue
...monents/report/TemplateComponent/ExportTestCaseReport.vue
+15
-0
frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultChartComponent.vue
...nts/report/TemplateComponent/TestResultChartComponent.vue
+2
-0
frontend/src/business/components/track/plan/view/comonents/report/TestCaseReportView.vue
...s/track/plan/view/comonents/report/TestCaseReportView.vue
+179
-142
frontend/src/i18n/en-US.js
frontend/src/i18n/en-US.js
+1
-0
frontend/src/i18n/zh-CN.js
frontend/src/i18n/zh-CN.js
+1
-0
frontend/src/i18n/zh-TW.js
frontend/src/i18n/zh-TW.js
+1
-0
未找到文件。
frontend/package.json
浏览文件 @
509e5c9f
...
...
@@ -38,6 +38,7 @@
"babel-eslint"
:
"^10.0.3"
,
"eslint"
:
"^5.16.0"
,
"eslint-plugin-vue"
:
"^5.0.0"
,
"file-writer"
:
"^1.0.2"
,
"vue-template-compiler"
:
"^2.6.10"
,
"vue2-ace-editor"
:
"0.0.15"
},
...
...
frontend/src/business/components/api/report/ApiReportView.vue
浏览文件 @
509e5c9f
...
...
@@ -4,9 +4,17 @@
<el-card>
<section
class=
"report-container"
v-if=
"this.report.testId"
>
<header
class=
"report-header"
>
<span>
{{
report
.
projectName
}}
/
</span>
<router-link
:to=
"path"
>
{{
report
.
testName
}}
</router-link>
<span
class=
"time"
>
{{
report
.
createTime
|
timestampFormatDate
}}
</span>
<el-row>
<el-col>
<span>
{{
report
.
projectName
}}
/
</span>
<router-link
:to=
"path"
>
{{
report
.
testName
}}
</router-link>
<span
class=
"time"
>
{{
report
.
createTime
|
timestampFormatDate
}}
</span>
<el-button
plain
type=
"primary"
size=
"mini"
@
click=
"handleExport(report.name)"
style=
"margin-left: 1200px"
>
{{
$t
(
'
test_track.plan_view.export_report
'
)
}}
</el-button>
</el-col>
</el-row>
</header>
<main
v-if=
"this.isNotRunning"
>
<ms-metric-chart
:content=
"content"
:totalTime=
"totalTime"
/>
...
...
@@ -43,6 +51,8 @@
import
MsMetricChart
from
"
./components/MetricChart
"
;
import
MsScenarioResults
from
"
./components/ScenarioResults
"
;
import
{
Scenario
}
from
"
../test/model/ScenarioModel
"
;
import
writer
from
"
file-writer
"
;
import
ResumeCss
from
"
../../../../common/css/main.css
"
;
export
default
{
name
:
"
MsApiReportView
"
,
...
...
@@ -62,6 +72,29 @@
},
methods
:
{
handleExport
(
name
)
{
let
html
=
this
.
getHtml
();
writer
(
`
${
name
}
.html`
,
html
,
'
utf-8
'
);
},
getHtml
()
{
const
template
=
this
.
$refs
.
resume
.
innerHTML
let
html
=
`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>html</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style>
${
ResumeCss
}
</style>
</head>
<body>
<div style="margin:0 auto;width:1200px">
${
template
}
</div>
</body>
</html>`
return
html
},
init
()
{
this
.
loading
=
true
;
this
.
report
=
{};
...
...
frontend/src/business/components/common/components/MsPieChart.vue
浏览文件 @
509e5c9f
...
...
@@ -43,7 +43,8 @@
type
:
'
pie
'
,
radius
:
[
'
40%
'
,
'
70%
'
],
// roseType: 'angle',
data
:
this
.
data
data
:
this
.
data
,
animation
:
false
}
]
},
...
...
frontend/src/business/components/performance/report/PerformanceReportView.vue
浏览文件 @
509e5c9f
...
...
@@ -22,9 +22,10 @@
@
click=
"rerun(testId)"
>
{{
$t
(
'
report.test_execute_again
'
)
}}
</el-button>
<
!--
<el-button
:disabled=
"isReadOnly"
type=
"info"
plain
size=
"mini
"
>
<
el-button
:disabled=
"isReadOnly"
type=
"info"
plain
size=
"mini"
@
click=
"exports(reportName)
"
>
{{
$t
(
'
report.export
'
)
}}
</el-button>
<!--
<el-button
:disabled=
"isReadOnly"
type=
"warning"
plain
size=
"mini"
>
{{
$t
(
'
report.compare
'
)
}}
</el-button>
-->
...
...
@@ -44,24 +45,26 @@
</el-row>
<el-divider/>
<div
ref=
"resume"
>
<el-tabs
v-model=
"active"
type=
"border-card"
:stretch=
"true"
>
<el-tab-pane
:label=
"$t('load_test.pressure_config')"
>
<ms-performance-pressure-config
:is-read-only=
"true"
:report=
"report"
/>
</el-tab-pane>
<el-tab-pane
:label=
"$t('report.test_overview')"
>
<ms-report-test-overview
:report=
"report"
ref=
"testOverview"
/>
</el-tab-pane>
<el-tab-pane
:label=
"$t('report.test_request_statistics')"
>
<ms-report-request-statistics
:report=
"report"
/>
</el-tab-pane>
<el-tab-pane
:label=
"$t('report.test_error_log')"
>
<ms-report-error-log
:report=
"report"
/>
</el-tab-pane>
<el-tab-pane
:label=
"$t('report.test_log_details')"
>
<ms-report-log-details
:report=
"report"
/>
</el-tab-pane>
</el-tabs>
</div>
<el-tabs
v-model=
"active"
type=
"border-card"
:stretch=
"true"
>
<el-tab-pane
:label=
"$t('load_test.pressure_config')"
>
<ms-performance-pressure-config
:is-read-only=
"true"
:report=
"report"
/>
</el-tab-pane>
<el-tab-pane
:label=
"$t('report.test_overview')"
>
<ms-report-test-overview
:report=
"report"
ref=
"testOverview"
/>
</el-tab-pane>
<el-tab-pane
:label=
"$t('report.test_request_statistics')"
>
<ms-report-request-statistics
:report=
"report"
/>
</el-tab-pane>
<el-tab-pane
:label=
"$t('report.test_error_log')"
>
<ms-report-error-log
:report=
"report"
/>
</el-tab-pane>
<el-tab-pane
:label=
"$t('report.test_log_details')"
>
<ms-report-log-details
:report=
"report"
/>
</el-tab-pane>
</el-tabs>
</el-card>
<el-dialog
:title=
"$t('report.test_stop_now_confirm')"
:visible.sync=
"dialogFormVisible"
width=
"30%"
>
...
...
@@ -79,250 +82,275 @@
</
template
>
<
script
>
import
MsReportErrorLog
from
'
./components/ErrorLog
'
;
import
MsReportLogDetails
from
'
./components/LogDetails
'
;
import
MsReportRequestStatistics
from
'
./components/RequestStatistics
'
;
import
MsReportTestOverview
from
'
./components/TestOverview
'
;
import
MsPerformancePressureConfig
from
"
./components/PerformancePressureConfig
"
;
import
MsContainer
from
"
../../common/components/MsContainer
"
;
import
MsMainContainer
from
"
../../common/components/MsMainContainer
"
;
import
MsReportErrorLog
from
'
./components/ErrorLog
'
;
import
MsReportLogDetails
from
'
./components/LogDetails
'
;
import
MsReportRequestStatistics
from
'
./components/RequestStatistics
'
;
import
MsReportTestOverview
from
'
./components/TestOverview
'
;
import
MsPerformancePressureConfig
from
"
./components/PerformancePressureConfig
"
;
import
MsContainer
from
"
../../common/components/MsContainer
"
;
import
MsMainContainer
from
"
../../common/components/MsMainContainer
"
;
import
{
checkoutTestManagerOrTestUser
}
from
"
@/common/js/utils
"
;
import
{
checkoutTestManagerOrTestUser
}
from
"
@/common/js/utils
"
;
import
writer
from
"
file-writer
"
;
import
ResumeCss
from
"
../../../../common/css/main.css
"
;
export
default
{
name
:
"
PerformanceReportView
"
,
components
:
{
MsReportErrorLog
,
MsReportLogDetails
,
MsReportRequestStatistics
,
MsReportTestOverview
,
MsContainer
,
MsMainContainer
,
MsPerformancePressureConfig
},
data
()
{
return
{
result
:
{},
active
:
'
1
'
,
reportId
:
''
,
status
:
''
,
reportName
:
''
,
testId
:
''
,
testName
:
''
,
projectId
:
''
,
projectName
:
''
,
startTime
:
'
0
'
,
endTime
:
'
0
'
,
minutes
:
'
0
'
,
seconds
:
'
0
'
,
title
:
'
Logging
'
,
report
:
{},
isReadOnly
:
false
,
websocket
:
null
,
dialogFormVisible
:
false
,
testPlan
:
{
testResourcePoolId
:
null
}
}
},
methods
:
{
initBreadcrumb
()
{
if
(
this
.
reportId
)
{
this
.
result
=
this
.
$get
(
"
/performance/report/test/pro/info/
"
+
this
.
reportId
,
res
=>
{
let
data
=
res
.
data
;
if
(
data
)
{
this
.
reportName
=
data
.
name
;
this
.
testId
=
data
.
testId
;
this
.
testName
=
data
.
testName
;
this
.
projectId
=
data
.
projectId
;
this
.
projectName
=
data
.
projectName
;
}
})
export
default
{
name
:
"
PerformanceReportView
"
,
components
:
{
MsReportErrorLog
,
MsReportLogDetails
,
MsReportRequestStatistics
,
MsReportTestOverview
,
MsContainer
,
MsMainContainer
,
MsPerformancePressureConfig
},
data
()
{
return
{
result
:
{},
active
:
'
1
'
,
reportId
:
''
,
status
:
''
,
reportName
:
''
,
testId
:
''
,
testName
:
''
,
projectId
:
''
,
projectName
:
''
,
startTime
:
'
0
'
,
endTime
:
'
0
'
,
minutes
:
'
0
'
,
seconds
:
'
0
'
,
title
:
'
Logging
'
,
report
:
{},
isReadOnly
:
false
,
websocket
:
null
,
dialogFormVisible
:
false
,
testPlan
:
{
testResourcePoolId
:
null
}
}
},
initReportTimeInfo
()
{
if
(
this
.
reportId
)
{
this
.
result
=
this
.
$get
(
"
/performance/report/content/report_time/
"
+
this
.
reportId
)
.
then
(
res
=>
{
let
data
=
res
.
data
.
data
;
methods
:
{
exports
(
name
)
{
let
html
=
this
.
getHtml
();
writer
(
`
${
name
}
.html`
,
html
,
'
utf-8
'
);
},
getHtml
()
{
const
template
=
this
.
$refs
.
resume
.
innerHTML
let
html
=
`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>html</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style></style>
</head>
<body>
<div style="margin:0 auto;width:1200px">
${
template
}
</div>
</body>
</html>`
return
html
},
initBreadcrumb
()
{
if
(
this
.
reportId
)
{
this
.
result
=
this
.
$get
(
"
/performance/report/test/pro/info/
"
+
this
.
reportId
,
res
=>
{
let
data
=
res
.
data
;
if
(
data
)
{
this
.
startTime
=
data
.
startTi
me
;
this
.
endTime
=
data
.
endTime
;
let
duration
=
data
.
duration
;
this
.
minutes
=
Math
.
floor
(
duration
/
60
)
;
this
.
seconds
=
duration
%
60
;
this
.
reportName
=
data
.
na
me
;
this
.
testId
=
data
.
testId
;
this
.
testName
=
data
.
testName
;
this
.
projectId
=
data
.
projectId
;
this
.
projectName
=
data
.
projectName
;
}
}).
catch
(()
=>
{
this
.
clearData
();
})
}
},
initReportTimeInfo
()
{
if
(
this
.
reportId
)
{
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
();
})
}
},
initWebSocket
()
{
let
protocol
=
"
ws://
"
;
if
(
window
.
location
.
protocol
===
'
https:
'
)
{
protocol
=
"
wss://
"
;
}
const
uri
=
protocol
+
window
.
location
.
host
+
"
/performance/report/
"
+
this
.
reportId
;
this
.
websocket
=
new
WebSocket
(
uri
);
this
.
websocket
.
onmessage
=
this
.
onMessage
;
this
.
websocket
.
onopen
=
this
.
onOpen
;
this
.
websocket
.
onerror
=
this
.
onError
;
this
.
websocket
.
onclose
=
this
.
onClose
;
},
checkReportStatus
(
status
)
{
switch
(
status
)
{
case
'
Error
'
:
this
.
$warning
(
this
.
$t
(
'
report.generation_error
'
));
break
;
case
'
Starting
'
:
this
.
$alert
(
this
.
$t
(
'
report.start_status
'
));
break
;
case
'
Reporting
'
:
case
'
Running
'
:
case
'
Completed
'
:
default
:
break
;
}
},
clearData
()
{
this
.
startTime
=
'
0
'
;
this
.
endTime
=
'
0
'
;
this
.
minutes
=
'
0
'
;
this
.
seconds
=
'
0
'
;
},
stopTest
(
forceStop
)
{
this
.
result
=
this
.
$get
(
'
/performance/stop/
'
+
this
.
reportId
+
'
/
'
+
forceStop
,
()
=>
{
this
.
$success
(
this
.
$t
(
'
report.test_stop_success
'
));
if
(
forceStop
)
{
this
.
$router
.
push
(
'
/performance/report/all
'
);
}
else
{
this
.
report
.
status
=
'
Completed
'
;
}
});
this
.
dialogFormVisible
=
false
;
},
rerun
(
testId
)
{
this
.
$confirm
(
this
.
$t
(
'
report.test_rerun_confirm
'
),
''
,
{
confirmButtonText
:
this
.
$t
(
'
commons.confirm
'
),
cancelButtonText
:
this
.
$t
(
'
commons.cancel
'
),
type
:
'
warning
'
}).
then
(()
=>
{
this
.
result
=
this
.
$post
(
'
/performance/run
'
,
{
id
:
testId
,
triggerMode
:
'
MANUAL
'
},
(
response
)
=>
{
this
.
reportId
=
response
.
data
;
this
.
$router
.
push
({
path
:
'
/performance/report/view/
'
+
this
.
reportId
});
// 注册 socket
this
.
initWebSocket
();
})
}).
catch
(()
=>
{
});
},
onOpen
()
{
window
.
console
.
log
(
"
socket opening.
"
);
},
onError
(
e
)
{
window
.
console
.
error
(
e
)
},
onMessage
(
e
)
{
this
.
$set
(
this
.
report
,
"
refresh
"
,
e
.
data
);
// 触发刷新
this
.
$set
(
this
.
report
,
"
status
"
,
'
Running
'
);
this
.
initReportTimeInfo
();
window
.
console
.
log
(
'
receive a message:
'
,
e
.
data
);
},
onClose
(
e
)
{
this
.
$set
(
this
.
report
,
"
refresh
"
,
Math
.
random
());
// 触发刷新
this
.
$set
(
this
.
report
,
"
status
"
,
'
Completed
'
);
this
.
initReportTimeInfo
();
window
.
console
.
log
(
"
socket closed.
"
);
}
},
initWebSocket
()
{
let
protocol
=
"
ws://
"
;
if
(
window
.
location
.
protocol
===
'
https:
'
)
{
protocol
=
"
wss://
"
;
}
const
uri
=
protocol
+
window
.
location
.
host
+
"
/performance/report/
"
+
this
.
reportId
;
this
.
websocket
=
new
WebSocket
(
uri
);
this
.
websocket
.
onmessage
=
this
.
onMessage
;
this
.
websocket
.
onopen
=
this
.
onOpen
;
this
.
websocket
.
onerror
=
this
.
onError
;
this
.
websocket
.
onclose
=
this
.
onClose
;
},
checkReportStatus
(
status
)
{
switch
(
status
)
{
case
'
Error
'
:
this
.
$warning
(
this
.
$t
(
'
report.generation_error
'
));
break
;
case
'
Starting
'
:
this
.
$alert
(
this
.
$t
(
'
report.start_status
'
));
break
;
case
'
Reporting
'
:
case
'
Running
'
:
case
'
Completed
'
:
default
:
break
;
created
()
{
this
.
isReadOnly
=
false
;
if
(
!
checkoutTestManagerOrTestUser
())
{
this
.
isReadOnly
=
true
;
}
},
clearData
()
{
this
.
startTime
=
'
0
'
;
this
.
endTime
=
'
0
'
;
this
.
minutes
=
'
0
'
;
this
.
seconds
=
'
0
'
;
},
stopTest
(
forceStop
)
{
this
.
result
=
this
.
$get
(
'
/performance/stop/
'
+
this
.
reportId
+
'
/
'
+
forceStop
,
()
=>
{
this
.
$success
(
this
.
$t
(
'
report.test_stop_success
'
));
if
(
forceStop
)
{
this
.
$router
.
push
(
'
/performance/report/all
'
);
this
.
reportId
=
this
.
$route
.
path
.
split
(
'
/
'
)[
4
];
this
.
result
=
this
.
$get
(
"
/performance/report/
"
+
this
.
reportId
,
res
=>
{
let
data
=
res
.
data
;
if
(
data
)
{
this
.
status
=
data
.
status
;
this
.
$set
(
this
.
report
,
"
id
"
,
this
.
reportId
);
this
.
$set
(
this
.
report
,
"
status
"
,
data
.
status
);
this
.
$set
(
this
.
report
,
"
testId
"
,
data
.
testId
);
this
.
$set
(
this
.
report
,
"
loadConfiguration
"
,
data
.
loadConfiguration
);
this
.
checkReportStatus
(
data
.
status
);
if
(
this
.
status
===
"
Completed
"
||
this
.
status
===
"
Running
"
)
{
this
.
initReportTimeInfo
();
}
this
.
initBreadcrumb
();
this
.
initWebSocket
();
}
else
{
this
.
report
.
status
=
'
Completed
'
;
this
.
$error
(
this
.
$t
(
'
report.not_exist
'
))
}
});
this
.
dialogFormVisible
=
false
;
},
rerun
(
testId
)
{
this
.
$confirm
(
this
.
$t
(
'
report.test_rerun_confirm
'
),
''
,
{
confirmButtonText
:
this
.
$t
(
'
commons.confirm
'
),
cancelButtonText
:
this
.
$t
(
'
commons.cancel
'
),
type
:
'
warning
'
}).
then
(()
=>
{
this
.
result
=
this
.
$post
(
'
/performance/run
'
,
{
id
:
testId
,
triggerMode
:
'
MANUAL
'
},
(
response
)
=>
{
this
.
reportId
=
response
.
data
;
this
.
$router
.
push
({
path
:
'
/performance/report/view/
'
+
this
.
reportId
});
// 注册 socket
this
.
initWebSocket
();
})
}).
catch
(()
=>
{
});
},
onOpen
()
{
window
.
console
.
log
(
"
socket opening.
"
);
},
onError
(
e
)
{
window
.
console
.
error
(
e
)
},
onMessage
(
e
)
{
this
.
$set
(
this
.
report
,
"
refresh
"
,
e
.
data
);
// 触发刷新
this
.
$set
(
this
.
report
,
"
status
"
,
'
Running
'
);
this
.
initReportTimeInfo
();
window
.
console
.
log
(
'
receive a message:
'
,
e
.
data
);
beforeDestroy
()
{
this
.
websocket
.
close
()
//离开路由之后断开websocket连接
},
onClose
(
e
)
{
this
.
$set
(
this
.
report
,
"
refresh
"
,
Math
.
random
());
// 触发刷新
this
.
$set
(
this
.
report
,
"
status
"
,
'
Completed
'
);
this
.
initReportTimeInfo
();
window
.
console
.
log
(
"
socket closed.
"
);
}
},
created
()
{
this
.
isReadOnly
=
false
;
if
(
!
checkoutTestManagerOrTestUser
())
{
this
.
isReadOnly
=
true
;
}
this
.
reportId
=
this
.
$route
.
path
.
split
(
'
/
'
)[
4
];
this
.
result
=
this
.
$get
(
"
/performance/report/
"
+
this
.
reportId
,
res
=>
{
let
data
=
res
.
data
;
if
(
data
)
{
this
.
status
=
data
.
status
;
this
.
$set
(
this
.
report
,
"
id
"
,
this
.
reportId
);
this
.
$set
(
this
.
report
,
"
status
"
,
data
.
status
);
this
.
$set
(
this
.
report
,
"
testId
"
,
data
.
testId
);
this
.
$set
(
this
.
report
,
"
loadConfiguration
"
,
data
.
loadConfiguration
);
this
.
checkReportStatus
(
data
.
status
);
if
(
this
.
status
===
"
Completed
"
||
this
.
status
===
"
Running
"
)
{
this
.
initReportTimeInfo
();
}
this
.
initBreadcrumb
();
this
.
initWebSocket
();
}
else
{
this
.
$error
(
this
.
$t
(
'
report.not_exist
'
))
}
});
},
beforeDestroy
()
{
this
.
websocket
.
close
()
//离开路由之后断开websocket连接
},
watch
:
{
'
$route
'
(
to
)
{
if
(
to
.
name
===
"
perReportView
"
)
{
this
.
isReadOnly
=
false
;
if
(
!
checkoutTestManagerOrTestUser
())
{
this
.
isReadOnly
=
true
;
}
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
.
testId
=
data
.
testId
;
this
.
projectName
=
data
.
projectName
;
watch
:
{
'
$route
'
(
to
)
{
if
(
to
.
name
===
"
perReportView
"
)
{
this
.
isReadOnly
=
false
;
if
(
!
checkoutTestManagerOrTestUser
())
{
this
.
isReadOnly
=
true
;
}
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
.
testId
=
data
.
testId
;
this
.
projectName
=
data
.
projectName
;
this
.
$set
(
this
.
report
,
"
id
"
,
reportId
);
this
.
$set
(
this
.
report
,
"
status
"
,
data
.
status
);
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
.
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
();
}
)
}
}
else
{
this
.
clearData
(
);
this
.
$error
(
this
.
$t
(
'
report.not_exist
'
)
);
}
}
else
{
this
.
$error
(
this
.
$t
(
'
report.not_exist
'
));
}
});
});
}
}
}
}
}
}
</
script
>
<
style
scoped
>
.ms-report-view-btns
{
margin-top
:
15px
;
}
.ms-report-view-btns
{
margin-top
:
15px
;
}
.ms-report-time-desc
{
text-align
:
left
;
display
:
block
;
color
:
#5C7878
;
}
.ms-report-time-desc
{
text-align
:
left
;
display
:
block
;
color
:
#5C7878
;
}
</
style
>
frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/ExportTestCaseReport.vue
0 → 100644
浏览文件 @
509e5c9f
<
template
>
<div>
<chart/>
</div>
</
template
>
<
script
>
export
default
{
name
:
"
ExportTestCaseReport
"
}
</
script
>
<
style
scoped
>
</
style
>
frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultChartComponent.vue
浏览文件 @
509e5c9f
...
...
@@ -66,6 +66,8 @@
this
.
charData
.
push
(
data
);
});
this
.
reload
();
},
reload
()
{
this
.
isShow
=
false
;
...
...
frontend/src/business/components/track/plan/view/comonents/report/TestCaseReportView.vue
浏览文件 @
509e5c9f
...
...
@@ -13,18 +13,25 @@
<el-row
type=
"flex"
class=
"head-bar"
>
<el-col
:span=
"12"
>
<div
class=
"name-edit"
>
<el-button
plain
size=
"mini"
icon=
"el-icon-back"
@
click=
"handleClose"
>
{{
$t
(
'
test_track.return
'
)
}}
</el-button>
<el-button
plain
size=
"mini"
icon=
"el-icon-back"
@
click=
"handleClose"
>
{{
$t
(
'
test_track.return
'
)
}}
</el-button>
<span
class=
"title"
>
{{
report
.
name
}}
</span>
</div>
</el-col>
<el-col
:span=
"12"
class=
"head-right"
>
<el-button
:disabled=
"!isTestManagerOrTestUser"
plain
size=
"mini"
@
click=
"handleSave"
>
{{
$t
(
'
commons.save
'
)
}}
</el-button>
<el-button
:disabled=
"!isTestManagerOrTestUser"
plain
size=
"mini"
@
click=
"handleEdit"
>
{{
$t
(
'
test_track.plan_view.edit_component
'
)
}}
</el-button>
<el-button
:disabled=
"!isTestManagerOrTestUser"
plain
size=
"mini"
@
click=
"handleSave"
>
{{
$t
(
'
commons.save
'
)
}}
</el-button>
<el-button
:disabled=
"!isTestManagerOrTestUser"
plain
size=
"mini"
@
click=
"handleEdit"
>
{{
$t
(
'
test_track.plan_view.edit_component
'
)
}}
</el-button>
<el-button
:disabled=
"!isTestManagerOrTestUser"
plain
size=
"mini"
@
click=
"handleExport(report.name)"
>
{{
$t
(
'
test_track.plan_view.export_report
'
)
}}
</el-button>
</el-col>
</el-row>
<div
class=
"container"
>
<div
class=
"container"
ref=
"resume"
>
<el-main>
<div
class=
"preview"
v-for=
"item in previews"
:key=
"item.id"
>
<template-component
:isReportView=
"true"
:metric=
"metric"
:preview=
"item"
/>
...
...
@@ -41,154 +48,184 @@
<
script
>
import
{
checkoutTestManagerOrTestUser
,
jsonToMap
,
mapToJson
}
from
"
../../../../../../../common/js/utils
"
;
import
BaseInfoComponent
from
"
./TemplateComponent/BaseInfoComponent
"
;
import
TestResultChartComponent
from
"
./TemplateComponent/TestResultChartComponent
"
;
import
TestResultComponent
from
"
./TemplateComponent/TestResultComponent
"
;
import
RichTextComponent
from
"
./TemplateComponent/RichTextComponent
"
;
import
TestCaseReportTemplateEdit
from
"
./TestCaseReportTemplateEdit
"
;
import
TemplateComponent
from
"
./TemplateComponent/TemplateComponent
"
;
export
default
{
name
:
"
TestCaseReportView
"
,
components
:
{
TemplateComponent
,
TestCaseReportTemplateEdit
,
RichTextComponent
,
TestResultComponent
,
TestResultChartComponent
,
BaseInfoComponent
},
data
()
{
return
{
result
:
{},
showDialog
:
false
,
previews
:
[],
report
:
{},
reportId
:
''
,
metric
:
{},
planId
:
''
,
componentMap
:
new
Map
(
[
[
1
,
{
name
:
this
.
$t
(
'
test_track.plan_view.base_info
'
),
id
:
1
,
type
:
'
system
'
}],
[
2
,
{
name
:
this
.
$t
(
'
test_track.plan_view.test_result
'
),
id
:
2
,
type
:
'
system
'
}],
[
3
,
{
name
:
this
.
$t
(
'
test_track.plan_view.result_distribution
'
),
id
:
3
,
type
:
'
system
'
}],
[
4
,
{
name
:
this
.
$t
(
'
test_track.plan_view.failure_case
'
),
id
:
4
,
type
:
'
system
'
}],
[
5
,
{
name
:
this
.
$t
(
'
test_track.plan_view.defect_list
'
),
id
:
5
,
type
:
'
system
'
}],
[
6
,
{
name
:
this
.
$t
(
'
test_track.plan_view.custom_component
'
),
id
:
6
,
type
:
'
custom
'
}]
]
),
isTestManagerOrTestUser
:
false
import
BaseInfoComponent
from
"
./TemplateComponent/BaseInfoComponent
"
;
import
TestResultChartComponent
from
"
./TemplateComponent/TestResultChartComponent
"
;
import
TestResultComponent
from
"
./TemplateComponent/TestResultComponent
"
;
import
RichTextComponent
from
"
./TemplateComponent/RichTextComponent
"
;
import
TestCaseReportTemplateEdit
from
"
./TestCaseReportTemplateEdit
"
;
import
TemplateComponent
from
"
./TemplateComponent/TemplateComponent
"
;
import
writer
from
'
file-writer
'
import
ResumeCss
from
"
../../../../../../../common/css/main.css
"
;
export
default
{
name
:
"
TestCaseReportView
"
,
components
:
{
TemplateComponent
,
ResumeCss
,
TestCaseReportTemplateEdit
,
RichTextComponent
,
TestResultComponent
,
TestResultChartComponent
,
BaseInfoComponent
},
data
()
{
return
{
result
:
{},
imgUrl
:
""
,
showDialog
:
false
,
previews
:
[],
report
:
{},
reportId
:
''
,
metric
:
{},
planId
:
''
,
componentMap
:
new
Map
(
[
[
1
,
{
name
:
this
.
$t
(
'
test_track.plan_view.base_info
'
),
id
:
1
,
type
:
'
system
'
}],
[
2
,
{
name
:
this
.
$t
(
'
test_track.plan_view.test_result
'
),
id
:
2
,
type
:
'
system
'
}],
[
3
,
{
name
:
this
.
$t
(
'
test_track.plan_view.result_distribution
'
),
id
:
3
,
type
:
'
system
'
}],
[
4
,
{
name
:
this
.
$t
(
'
test_track.plan_view.failure_case
'
),
id
:
4
,
type
:
'
system
'
}],
[
5
,
{
name
:
this
.
$t
(
'
test_track.plan_view.defect_list
'
),
id
:
5
,
type
:
'
system
'
}],
[
6
,
{
name
:
this
.
$t
(
'
test_track.plan_view.custom_component
'
),
id
:
6
,
type
:
'
custom
'
}]
]
),
isTestManagerOrTestUser
:
false
}
},
mounted
()
{
this
.
isTestManagerOrTestUser
=
checkoutTestManagerOrTestUser
();
},
methods
:
{
listenGoBack
()
{
//监听浏览器返回操作,关闭该对话框
if
(
window
.
history
&&
window
.
history
.
pushState
)
{
history
.
pushState
(
null
,
null
,
document
.
URL
);
window
.
addEventListener
(
'
popstate
'
,
this
.
goBack
,
false
);
}
},
mounted
()
{
this
.
isTestManagerOrTestUser
=
checkoutTestManagerOrTestUser
();
goBack
()
{
this
.
handleClose
();
},
methods
:
{
listenGoBack
()
{
//监听浏览器返回操作,关闭该对话框
if
(
window
.
history
&&
window
.
history
.
pushState
)
{
history
.
pushState
(
null
,
null
,
document
.
URL
);
window
.
addEventListener
(
'
popstate
'
,
this
.
goBack
,
false
);
}
},
goBack
()
{
this
.
handleClose
();
},
open
(
planId
,
id
)
{
this
.
planId
=
planId
;
if
(
id
)
{
this
.
report
Id
=
id
;
open
(
planId
,
id
)
{
this
.
planId
=
planId
;
if
(
id
)
{
this
.
reportId
=
id
;
}
this
.
getReport
(
);
this
.
showDialog
=
true
;
this
.
listenGoBack
();
},
getReport
()
{
this
.
result
=
this
.
$get
(
'
/case/report/get/
'
+
this
.
reportId
,
response
=>
{
this
.
report
=
response
.
data
;
this
.
report
.
content
=
JSON
.
parse
(
response
.
data
.
content
)
;
if
(
this
.
report
.
content
.
customComponent
)
{
this
.
report
.
content
.
customComponent
=
jsonToMap
(
this
.
report
.
content
.
customComponent
)
;
}
this
.
getReport
();
this
.
showDialog
=
true
;
this
.
listenGoBack
();
},
getReport
()
{
this
.
result
=
this
.
$get
(
'
/case/report/get/
'
+
this
.
reportId
,
response
=>
{
this
.
report
=
response
.
data
;
this
.
report
.
content
=
JSON
.
parse
(
response
.
data
.
content
);
this
.
getMetric
();
this
.
initPreviews
();
});
},
initPreviews
()
{
this
.
previews
=
[];
this
.
report
.
content
.
components
.
forEach
(
item
=>
{
let
preview
=
this
.
componentMap
.
get
(
item
);
if
(
preview
&&
preview
.
type
!=
'
custom
'
)
{
this
.
previews
.
push
(
preview
);
}
else
{
if
(
this
.
report
.
content
.
customComponent
)
{
this
.
report
.
content
.
customComponent
=
jsonToMap
(
this
.
report
.
content
.
customComponent
);
}
this
.
getMetric
();
this
.
initPreviews
();
});
},
initPreviews
()
{
this
.
previews
=
[];
this
.
report
.
content
.
components
.
forEach
(
item
=>
{
let
preview
=
this
.
componentMap
.
get
(
item
);
if
(
preview
&&
preview
.
type
!=
'
custom
'
)
{
this
.
previews
.
push
(
preview
);
}
else
{
if
(
this
.
report
.
content
.
customComponent
)
{
let
customComponent
=
this
.
report
.
content
.
customComponent
.
get
(
item
.
toString
());
if
(
customComponent
)
{
this
.
previews
.
push
({
id
:
item
,
title
:
customComponent
.
title
,
content
:
customComponent
.
content
});
}
let
customComponent
=
this
.
report
.
content
.
customComponent
.
get
(
item
.
toString
());
if
(
customComponent
)
{
this
.
previews
.
push
({
id
:
item
,
title
:
customComponent
.
title
,
content
:
customComponent
.
content
});
}
}
});
},
handleClose
()
{
window
.
removeEventListener
(
'
popstate
'
,
this
.
goBack
,
false
);
this
.
$emit
(
'
refresh
'
);
this
.
showDialog
=
false
;
},
handleEdit
()
{
this
.
$refs
.
templateEdit
.
open
(
this
.
reportId
,
true
);
},
handleSave
()
{
let
param
=
{};
this
.
buildParam
(
param
);
this
.
result
=
this
.
$post
(
'
/case/report/edit
'
,
param
,
()
=>
{
this
.
$success
(
this
.
$t
(
'
commons.save_success
'
));
});
},
buildParam
(
param
)
{
let
content
=
{};
content
.
components
=
[];
this
.
previews
.
forEach
(
item
=>
{
content
.
components
.
push
(
item
.
id
);
if
(
!
this
.
componentMap
.
get
(
item
.
id
))
{
content
.
customComponent
=
new
Map
();
content
.
customComponent
.
set
(
item
.
id
,
{
title
:
item
.
title
,
content
:
item
.
content
})
}
});
param
.
name
=
this
.
report
.
name
;
if
(
content
.
customComponent
)
{
content
.
customComponent
=
mapToJson
(
content
.
customComponent
);
}
param
.
content
=
JSON
.
stringify
(
content
);
param
.
id
=
this
.
report
.
id
;
if
(
this
.
metric
.
startTime
)
{
param
.
startTime
=
this
.
metric
.
startTime
.
getTime
();
});
},
handleClose
()
{
window
.
removeEventListener
(
'
popstate
'
,
this
.
goBack
,
false
);
this
.
$emit
(
'
refresh
'
);
this
.
showDialog
=
false
;
},
handleEdit
()
{
this
.
$refs
.
templateEdit
.
open
(
this
.
reportId
,
true
);
},
/*导出报告*/
handleExport
(
name
)
{
let
html
=
this
.
getHtml
();
writer
(
`
${
name
}
.html`
,
html
,
'
utf-8
'
);
},
getHtml
()
{
const
template
=
this
.
$refs
.
resume
.
innerHTML
let
html
=
`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>html</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style>
${
ResumeCss
}
</style>
</head>
<body>
<div style="margin:0 auto;width:1200px">
<img id ='div' :src = "imgUrl" :style=" {width: '1000px', height: '500px'}" />
${
template
}
</div>
</body>
</html>`
return
html
},
handleSave
()
{
let
param
=
{};
this
.
buildParam
(
param
);
this
.
result
=
this
.
$post
(
'
/case/report/edit
'
,
param
,
()
=>
{
this
.
$success
(
this
.
$t
(
'
commons.save_success
'
));
});
},
buildParam
(
param
)
{
let
content
=
{};
content
.
components
=
[];
this
.
previews
.
forEach
(
item
=>
{
content
.
components
.
push
(
item
.
id
);
if
(
!
this
.
componentMap
.
get
(
item
.
id
))
{
content
.
customComponent
=
new
Map
();
content
.
customComponent
.
set
(
item
.
id
,
{
title
:
item
.
title
,
content
:
item
.
content
})
}
});
param
.
name
=
this
.
report
.
name
;
if
(
content
.
customComponent
)
{
content
.
customComponent
=
mapToJson
(
content
.
customComponent
);
}
param
.
content
=
JSON
.
stringify
(
content
);
param
.
id
=
this
.
report
.
id
;
if
(
this
.
metric
.
startTime
)
{
param
.
startTime
=
this
.
metric
.
startTime
.
getTime
();
}
if
(
this
.
metric
.
endTime
)
{
param
.
endTime
=
this
.
metric
.
endTime
.
getTime
();
}
},
getMetric
()
{
this
.
result
=
this
.
$get
(
'
/test/plan/get/metric/
'
+
this
.
planId
,
response
=>
{
this
.
metric
=
response
.
data
;
if
(
!
this
.
metric
.
failureTestCases
)
{
this
.
metric
.
failureTestCases
=
[];
}
if
(
!
this
.
metric
.
executeResult
)
{
this
.
metric
.
executeResult
=
[];
}
if
(
this
.
metric
.
endTime
)
{
param
.
endTime
=
this
.
metric
.
endTime
.
getTime
()
;
if
(
!
this
.
metric
.
moduleExecuteResult
)
{
this
.
metric
.
moduleExecuteResult
=
[]
;
}
},
getMetric
()
{
this
.
result
=
this
.
$get
(
'
/test/plan/get/metric/
'
+
this
.
planId
,
response
=>
{
this
.
metric
=
response
.
data
;
if
(
!
this
.
metric
.
failureTestCases
)
{
this
.
metric
.
failureTestCases
=
[];
}
if
(
!
this
.
metric
.
executeResult
)
{
this
.
metric
.
executeResult
=
[];
}
if
(
!
this
.
metric
.
moduleExecuteResult
)
{
this
.
metric
.
moduleExecuteResult
=
[];
}
/*缺陷列表*/
this
.
metric
.
defectList
=
[];
/*缺陷列表*/
this
.
metric
.
defectList
=
[];
if
(
this
.
report
.
startTime
)
{
this
.
metric
.
startTime
=
new
Date
(
this
.
report
.
startTime
);
}
if
(
this
.
report
.
endTime
)
{
this
.
metric
.
endTime
=
new
Date
(
this
.
report
.
endTime
);
}
});
},
if
(
this
.
report
.
startTime
)
{
this
.
metric
.
startTime
=
new
Date
(
this
.
report
.
startTime
);
}
if
(
this
.
report
.
endTime
)
{
this
.
metric
.
endTime
=
new
Date
(
this
.
report
.
endTime
);
}
});
}
}
}
}
</
script
>
<
style
scoped
>
...
...
@@ -204,7 +241,7 @@
line-height
:
45px
;
padding
:
0
10px
;
border
:
1px
solid
#EBEEF5
;
box-shadow
:
0
0
2px
0
rgba
(
31
,
31
,
31
,
0.15
),
0
1px
2px
0
rgba
(
31
,
31
,
31
,
0.15
);
box-shadow
:
0
0
2px
0
rgba
(
31
,
31
,
31
,
0.15
),
0
1px
2px
0
rgba
(
31
,
31
,
31
,
0.15
);
}
.container
{
...
...
frontend/src/i18n/en-US.js
浏览文件 @
509e5c9f
...
...
@@ -669,6 +669,7 @@ export default {
report_template
:
"
Report template
"
,
test_detail
:
"
Test detail
"
,
failure_case
:
"
Failure case
"
,
export_report
:
"
Export Report
"
}
},
test_resource_pool
:
{
...
...
frontend/src/i18n/zh-CN.js
浏览文件 @
509e5c9f
...
...
@@ -674,6 +674,7 @@ export default {
report_template
:
"
测试报告模版
"
,
test_detail
:
"
测试详情
"
,
failure_case
:
"
失败用例
"
,
export_report
:
"
导出报告
"
}
},
test_resource_pool
:
{
...
...
frontend/src/i18n/zh-TW.js
浏览文件 @
509e5c9f
...
...
@@ -669,6 +669,7 @@ export default {
report_template
:
"
測試報告模版
"
,
test_detail
:
"
測試詳情
"
,
failure_case
:
"
失敗用例
"
,
export_report
:
"
匯出報告
"
}
},
test_resource_pool
:
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录