add:UI测试-测试报告列表api,测试报告详情api,自动化列表api

This commit is contained in:
2025-04-27 18:09:51 +08:00
parent d71d5c070e
commit 354a65938a
6 changed files with 362 additions and 97 deletions

View File

@@ -1 +1,45 @@
import request from '@/utils/request'
// 自动化 - 列表查询
export function getAutomationList(query) {
return request({
url: '/test/automation/list',
method: 'get',
params: query
})
}
// 自动化 - 新增
export function addAutomation(data) {
return request({
url: '/test/automation/add',
method: 'post',
data: data
})
}
// 自动化 - 删除
export function deleteAutomation(data) {
return request({
url: '/test/automation/delete/' + data,
method: 'put',
})
}
// 自动化- 编辑
export function updateAutomation(data) {
return request({
url: '/test/automation/update',
method: 'put',
data: data
})
}
// 自动化 - 详情
export function getAutomationDetail(data) {
return request({
url: '/test/automation/getInfo' + data,
method: 'get',
})
}

View File

@@ -11,23 +11,35 @@
</el-dropdown>
<div class="searchInput">
<i class="el-icon-search"></i>
<el-input class="input" v-model="search" placeholder="根据名称搜索"></el-input>
<el-input class="input" v-model="searchForm.keyword" placeholder="根据名称搜索" @blur="searchList"></el-input>
</div>
</div>
<div class="list">
<el-table :data="automationList">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="ID" width="50" align="center" />
<el-table-column prop="performanceName" label="场景名称" width="150" align="center" sortable />
<el-table-column prop="createBy" label="用例等级" width="150" align="center" sortable />
<el-table-column prop="createTime" label="状态" width="150" align="center" sortable />
<el-table-column prop="updateTime" label="标签" width="150" align="center" />
<el-table-column prop="status" label="创建人" width="150" align="center" sortable />
<el-table-column prop="status" label="责任人" width="150" align="center" sortable />
<el-table-column prop="status" label="最后更新时间" width="150" align="center" sortable />
<el-table-column prop="status" label="步骤数" width="80" align="center" />
<el-table-column prop="status" label="执行结果" width="150" align="center" sortable />
<el-table-column prop="status" label="通过率" width="150" align="center" sortable />
<el-table-column prop="name" label="场景名称" min-width="150" align="center" sortable />
<el-table-column prop="caseLevel" label="用例等级" min-width="150" align="center" sortable>
<template slot-scope="scope">
<el-tag v-if="scope.row.caseLevel" :type="priorityColor[scope.row.caseLevel]">{{ scope.row.caseLevel
}}</el-tag>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" min-width="150" align="center" sortable>
<template slot-scope="scope">
<div v-if="scope.row.status === '1'">未开始</div>
<div v-if="scope.row.status === '2'">进行中</div>
<div v-if="scope.row.status === '3'">已完成</div>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="label" label="标签" min-width="150" align="center" />
<el-table-column prop="createBy" label="创建人" min-width="150" align="center" sortable />
<el-table-column prop="dutyBy" label="责任人" min-width="150" align="center" sortable />
<el-table-column prop="updateTime" label="最后更新时间" min-width="180" align="center" sortable />
<el-table-column prop="stepsNumber" label="步骤数" min-width="80" align="center" />
<el-table-column prop="executionResult" label="执行结果" min-width="150" align="center" sortable />
<el-table-column prop="passRate" label="通过率" min-width="150" align="center" sortable />
<el-table-column prop="action" label="操作" align="center" fixed="right" width="200px">
<template slot-scope="scope">
<el-button type="text" icon="el-icon-edit-outline" @click="hadleClickEdit(scope.row)">编辑</el-button>
@@ -46,17 +58,26 @@
<script>
import FolderPage from "@/components/FolderPage/index.vue"
import { getAutomationList, deleteAutomation } from "../../../api/uiTest/automationTest";
export default {
name: "AutomationTest",
components: { FolderPage },
data() {
return {
priorityColor: {
P0: 'danger', // 红色
P1: 'warning', // 黄色
P2: 'info', // 蓝色
P3: 'success', // 绿色
p4: 'success'
},
automationList: [{}],
search: '',
searchForm: {
pageNumber: 1,
pageNum: 1,
pageSize: 10,
keyword: null,
groupId: null,
},
total: 0,
}
@@ -67,10 +88,25 @@ export default {
folderHandleSelected(id) {
if (id) {
// 获取列表
this.searchForm.groupId = id;
this.getAutomationListData();
} else {
this.elementList = [];
this.automationList = [];
}
},
// 获取列表
getAutomationListData() {
getAutomationList(this.searchForm).then(res => {
if (res.code === 200) {
this.automationList = res.rows
this.total = res.total
}
})
},
// 搜索
searchList() {
this.getAutomationListData();
},
// 创建元素
handleCommand(command) {
this.$tab.openPage("创建场景", "/ui-test/automation/add");
@@ -82,13 +118,27 @@ export default {
// 删除
hadleClickDelete(val) {
this.$modal.confirm('确认删除元素' + '').then(() => {
this.$modal.msgSuccess("删除成功");
deleteAutomation(val.id).then(res => {
if (res.code === 200) {
this.$modal.msgSuccess("删除成功");
this.getAutomationListData();
} else {
this.$modal.msgError("删除失败");
}
})
}).catch(() => { })
},
// 查看
handleClickDetail() { },
handleSizeChange() { },
handleCurrentChange() { },
// 分页
handleSizeChange(val) {
this.searchForm.pageSize = val
this.getAutomationListData();
},
handleCurrentChange(val) {
this.searchForm.pageNum = val
this.getAutomationListData();
},
}
}
@@ -127,5 +177,14 @@ export default {
flex-direction: column;
gap: 20px;
align-items: flex-end;
.caseLevel-wrap {
padding: 0px 5px;
background-color: #F56C6D;
color: white;
font-weight: 500;
border-radius: 4px;
display: inline-block;
}
}
</style>

View File

@@ -75,7 +75,7 @@ export default {
return {
elementList: [],
searchForm: {
pageNumber: 1,
pageNum: 1,
pageSize: 10,
name: null,
groupId: null,
@@ -128,6 +128,7 @@ export default {
getElementList(this.searchForm).then(res => {
if (res.code === 200) {
this.elementList = res.rows
this.total = res.total
}
})
},
@@ -188,8 +189,15 @@ export default {
})
}
},
handleCurrentChange() { },
handleSizeChange() { },
// 分页
handleSizeChange(val) {
this.searchForm.pageSize = val
this.getElementData();
},
handleCurrentChange(val) {
this.searchForm.pageNum = val
this.getElementData();
},
},
}

View File

@@ -3,20 +3,36 @@
<div class="header">
<div class="searchInput">
<i class="el-icon-search"></i>
<el-input class="input" v-model="search" placeholder="根据名称搜索"></el-input>
<el-input class="input" v-model="searchForm.name" placeholder="根据名称搜索" @blur="searchList"></el-input>
</div>
</div>
<div class="list">
<el-table :data="reportList">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="ID" width="50" align="center" />
<el-table-column prop="performanceName" label="名称" min-width="150" align="center" sortable />
<el-table-column prop="createBy" label="报告类型" min-width="150" align="center" />
<el-table-column prop="createTime" label="创建人" min-width="150" align="center" sortable />
<el-table-column prop="updateTime" label="创建时间" align="center" min-width="150" sortable />
<el-table-column prop="status" label="结束时间" align="center" min-width="150" sortable />
<el-table-column prop="status" label="触发方式" min-width="150" align="center" />
<el-table-column prop="status" label="状态" min-width="150" align="center" />
<el-table-column prop="name" label="名称" min-width="150" align="center" sortable />
<el-table-column prop="reportType" label="报告类型" min-width="150" align="center" />
<el-table-column prop="createBy" label="创建人" min-width="150" align="center" sortable />
<el-table-column prop="createTime" label="创建时间" align="center" min-width="180" sortable />
<el-table-column prop="updateTime" label="结束时间" align="center" min-width="180" sortable />
<el-table-column prop="triggerMode" label="触发方式" min-width="150" align="center">
<template slot-scope="scope">
<div v-if="scope.row.triggerMode === '1'">手动</div>
<div v-if="scope.row.triggerMode === '2'">批量执行</div>
<div v-if="scope.row.triggerMode === '3'">定时任务</div>
<div v-if="scope.row.triggerMode === '4'">API调用</div>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" min-width="150" align="center">
<template slot-scope="scope">
<div v-if="scope.row.status === 1">Running</div>
<div v-if="scope.row.status === 2">Error</div>
<div v-if="scope.row.status === 3">Success</div>
<div v-if="scope.row.status === 4">Stopped</div>
<div v-if="scope.row.status === 5">Pending</div>
<div v-if="scope.row.status === 6">Timeout</div>
</template>
</el-table-column>
<el-table-column prop="action" label="操作" align="center" fixed="right" width="150px">
<template slot-scope="scope">
<el-button type="text" icon="el-icon-view" @click="handleClickDetail(scope.row)"
@@ -31,44 +47,72 @@
</div>
</div>
</template>
<script>
import { getTestReportList, deleteTestReport } from '../../../api/uiTest/testReport';
export default {
name: "TestReport",
data() {
return {
search: '',
reportList: [{}],
reportList: [],
searchForm: {
pageNumber: 1,
pageNum: 1,
pageSize: 10,
name: null,
},
total: 0,
}
},
mounted() {
this.getReportListData()
},
methods: {
// 获取报告列表
getReportListData() {
getTestReportList(this.searchForm).then(res => {
if (res.code === 200) {
this.reportList = res.rows
this.total = res.total
}
})
},
// 搜索
searchList() {
this.getReportListData()
},
// 删除
hadleClickDelete(val) {
this.$modal.confirm('确认删除元素' + '').then(() => {
this.$modal.msgSuccess("删除成功");
deleteTestReport(val.id).then(res => {
if (res.code === 200) {
this.$modal.msgSuccess("删除成功");
this.getReportListData()
} else {
this.$modal.msgSuccess("删除失败");
}
})
}).catch(() => { })
},
// 查看
handleClickDetail(val) {
this.$tab.openPage("测试报告详情", "/ui-test/report/detail", { id: val.id });
},
handleSizeChange() { },
handleCurrentChange() { },
// 分页
handleSizeChange(val) {
this.searchForm.pageSize = val
this.getReportListData()
},
handleCurrentChange(val) {
this.searchForm.pageNum = val
this.getReportListData()
},
}
}
</script>
<style scoped lang="scss">
.report {
padding: 20px;

View File

@@ -1,9 +1,9 @@
<template>
<div class="report-detail">
<div class="header">
<div class="header-title">登录 开始时间 结束时间</div>
<div class="header-title">开始时间{{ detailData.createTime }} 结束时间{{ detailData.updateTime }}</div>
<div class="header-content">
<div class="content-title">42.28s</div>
<div class="content-title">{{ detailData.take }}</div>
<div class="left-wrap">
<!-- 环形图 -->
<div>
@@ -11,60 +11,75 @@
<div class="left-count">
<div class="left-count-show">
<div class="green-wrap"></div>
<div style="font-weight: 600;">4 成功</div>
<div style="font-weight: 600;">{{ detailData.stepsSucceedNumber }} 成功</div>
</div>
<el-divider></el-divider>
<div class="left-count-show">
<div class="red-wrap"></div>
<div style="font-weight: 600;">0 失败</div>
<div style="font-weight: 600;">{{ detailData.stepsErrorNumber }} 失败</div>
</div>
<el-divider></el-divider>
<div class="left-count-show">
<div class="gray-wrap"></div>
<div style="font-weight: 600;">{{ detailData.stepsNotNumber }} 未执行</div>
</div>
</div>
</div>
<div class="middle-wrap">
<div class="wrap-show">
<div class="middle-wrap">
<div class="title">1</div>
<div class="title">{{ detailData.scenesNumber }}</div>
<div>场景</div>
</div>
<div class="green-wrap"></div>
<div class="middle-wrap">
<div class="title">1</div>
<div class="title">{{ detailData.scenesErrorNumber }}</div>
<div>失败</div>
</div>
<div class="red-wrap"></div>
<div class="middle-wrap">
<div class="title">1</div>
<div class="title">{{ detailData.scenesSucceedNumber }}</div>
<div>成功</div>
</div>
<div class="gray-wrap"></div>
<div class="middle-wrap">
<div class="title">{{ detailData.scenesNotNumber }}</div>
<div>未执行</div>
</div>
</div>
<el-divider></el-divider>
<div class="wrap-show">
<div class="middle-wrap">
<div class="title">1</div>
<div class="title">{{ detailData.stepsNumber }}</div>
<div>步骤</div>
</div>
<div class="green-wrap"></div>
<div class="middle-wrap">
<div class="title">1</div>
<div class="title">{{ detailData.stepsErrorNumber }}</div>
<div>失败</div>
</div>
<div class="red-wrap"></div>
<div class="middle-wrap">
<div class="title">1</div>
<div class="title">{{ detailData.stepsSucceedNumber }}</div>
<div>成功</div>
</div>
<div class="gray-wrap"></div>
<div class="middle-wrap">
<div class="title">{{ detailData.stepsNotNumber }}</div>
<div>未执行</div>
</div>
</div>
<div></div>
</div>
<div class="right-wrap">
<div class="error-wrap">
<i class="el-icon-warning-outline" style="color: red; font-size: 30px;"></i>
<div class="show-title">0%</div>
<div class="show-title">{{ detailData.faiiRate ? detailData.faiiRate : '0' }}%</div>
<div class="show-sub">失败</div>
</div>
<div class="error-wrap">
<i class="el-icon-document-checked" style="font-size: 30px;"></i>
<div class="show-title">0-0</div>
<div class="show-title">{{ detailData.successAssertion ? detailData.successAssertion : '0/0' }}</div>
<div class="show-sub">成功断言</div>
</div>
</div>
@@ -75,28 +90,40 @@
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="全部" name="first">
<el-collapse accordion>
<el-collapse-item v-for="(item, index) in allList">
<el-collapse-item>
<template slot="title">
<div class="list-title">{{ index + 1 }}</div>
{{ item.title }}
<div style="margin-left: 10px;">{{ detailData.name }}</div>
</template>
<div class="list-sub-wrap">
<el-collapse accordion>
<el-collapse-item v-for="(row, index) in item.contentList">
<el-collapse-item v-for="(item, index) in uiSceneStepsAllReportVOList">
<template slot="title">
<div class="sub-title">{{ index + 1 }}</div>
<div class="sub-content">
<div>----打开网页</div>
<div>1231ms</div>
<el-button size="mini" type="text" @click.native.stop="clickHandleScreenshot">截图</el-button>
<div>成功</div>
<div class="sub-collapse">
<div class="left-collapse">
<div class="sub-title">{{ index + 1 }}</div>
<div>{{ item.name }}</div>
</div>
<div class="right-collapse">
<div>{{ item.take }}</div>
<el-button size="mini" type="text" @click.native.stop="clickHandleScreenshot">截图</el-button>
<div class="collapse-status">
<div v-if="item.executionFlag === '1'">成功</div>
<div v-if="item.executionFlag === '0'">未执行</div>
<div v-if="item.executionFlag === '2'">执行失败</div>
</div>
</div>
</div>
</template>
<div style="display: flex; justify-content: flex-end;">开始时间---- ---- --- 结束时间 ---- ---- --</div>
<el-tabs v-model="active" @tab-click="handleClick" style="margin-left: 20px;">
<el-tab-pane label="日志" name="first">日志</el-tab-pane>
<el-tab-pane label="断言" name="second">断言</el-tab-pane>
<el-tab-pane label="提取" name="third">提取</el-tab-pane>
<el-tab-pane label="日志" name="first">
<div class="tab-content">{{ item.logInfo }}</div>
</el-tab-pane>
<el-tab-pane label="断言" name="second">
<div class="tab-content">{{ item.assertionJson }}</div>
</el-tab-pane>
<el-tab-pane label="提取" name="third">
<div class="tab-content">{{ item.extractionDataJson }}</div>
</el-tab-pane>
</el-tabs>
</el-collapse-item>
</el-collapse>
@@ -106,28 +133,40 @@
</el-tab-pane>
<el-tab-pane label="失败" name="second">
<el-collapse accordion>
<el-collapse-item v-for="(item, index) in failureList">
<el-collapse-item>
<template slot="title">
<div class="list-title">{{ index + 1 }}</div>
{{ item.title }}
<div style="margin-left: 10px;">{{ detailData.name }}</div>
</template>
<div class="list-sub-wrap">
<el-collapse accordion>
<el-collapse-item v-for="(row, index) in item.contentList">
<el-collapse-item v-for="(item, index) in uiSceneStepsErrorReportVOList">
<template slot="title">
<div class="sub-title">{{ index + 1 }}</div>
<div class="sub-content">
<div>----打开网页</div>
<div>1231ms</div>
<el-button size="mini" type="text" @click.native.stop="clickHandleScreenshot">截图</el-button>
<div>成功</div>
<div class="sub-collapse">
<div class="left-collapse">
<div class="sub-title">{{ index + 1 }}</div>
<div>{{ item.name }}</div>
</div>
<div class="right-collapse">
<div>{{ item.take }}</div>
<el-button size="mini" type="text" @click.native.stop="clickHandleScreenshot">截图</el-button>
<div class="collapse-status">
<div v-if="item.executionFlag === '1'">成功</div>
<div v-if="item.executionFlag === '0'">未执行</div>
<div v-if="item.executionFlag === '2'">执行失败</div>
</div>
</div>
</div>
</template>
<div style="display: flex; justify-content: flex-end;">开始时间---- ---- --- 结束时间 ---- ---- --</div>
<el-tabs v-model="active" @tab-click="handleClick" style="margin-left: 20px;">
<el-tab-pane label="日志" name="first">日志</el-tab-pane>
<el-tab-pane label="断言" name="second">断言</el-tab-pane>
<el-tab-pane label="提取" name="third">提取</el-tab-pane>
<el-tab-pane label="日志" name="first">
<div class="tab-content">{{ item.logInfo }}</div>
</el-tab-pane>
<el-tab-pane label="断言" name="second">
<div class="tab-content">{{ item.assertionJson }}</div>
</el-tab-pane>
<el-tab-pane label="提取" name="third">
<div class="tab-content">{{ item.extractionDataJson }}</div>
</el-tab-pane>
</el-tabs>
</el-collapse-item>
</el-collapse>
@@ -137,28 +176,40 @@
</el-tab-pane>
<el-tab-pane label="未执行" name="third">
<el-collapse accordion>
<el-collapse-item v-for="(item, index) in unexecutedList">
<el-collapse-item>
<template slot="title">
<div class="list-title">{{ index + 1 }}</div>
{{ item.title }}
<div style="margin-left: 10px;">{{ detailData.name }}</div>
</template>
<div class="list-sub-wrap">
<el-collapse accordion>
<el-collapse-item v-for="(row, index) in item.contentList">
<el-collapse-item v-for="(item, index) in uiSceneStepsNotReportVOList">
<template slot="title">
<div class="sub-title">{{ index + 1 }}</div>
<div class="sub-content">
<div>----打开网页</div>
<div>1231ms</div>
<el-button size="mini" type="text" @click.native.stop="clickHandleScreenshot">截图</el-button>
<div>成功</div>
<div class="sub-collapse">
<div class="left-collapse">
<div class="sub-title">{{ index + 1 }}</div>
<div>{{ item.name }}</div>
</div>
<div class="right-collapse">
<div>{{ item.take }}</div>
<el-button size="mini" type="text" @click.native.stop="clickHandleScreenshot">截图</el-button>
<div class="collapse-status">
<div v-if="item.executionFlag === '1'">成功</div>
<div v-if="item.executionFlag === '0'">未执行</div>
<div v-if="item.executionFlag === '2'">执行失败</div>
</div>
</div>
</div>
</template>
<div style="display: flex; justify-content: flex-end;">开始时间---- ---- --- 结束时间 ---- ---- --</div>
<el-tabs v-model="active" @tab-click="handleClick" style="margin-left: 20px;">
<el-tab-pane label="日志" name="first">日志</el-tab-pane>
<el-tab-pane label="断言" name="second">断言</el-tab-pane>
<el-tab-pane label="提取" name="third">提取</el-tab-pane>
<el-tab-pane label="日志" name="first">
<div class="tab-content">{{ item.logInfo }}</div>
</el-tab-pane>
<el-tab-pane label="断言" name="second">
<div class="tab-content">{{ item.assertionJson }}</div>
</el-tab-pane>
<el-tab-pane label="提取" name="third">
<div class="tab-content">{{ item.extractionDataJson }}</div>
</el-tab-pane>
</el-tabs>
</el-collapse-item>
</el-collapse>
@@ -173,22 +224,37 @@
<script>
import * as echarts from 'echarts';
import { getTestReportDetail } from '../../../api/uiTest/testReport';
export default {
name: "TestReportDetail",
components: { echarts },
data() {
return {
activeName: 'first',
allList: [{ title: 'aaa', contentList: [{}, {}] }, { title: 'bbb', contentList: [{}, {}] }], // 全部
failureList: [{ title: 'aaa', contentList: [{}, {}] }, { title: 'bbb', contentList: [{}, {}] }], // 失败
unexecutedList: [{ title: 'aaa', contentList: [{}, {}] }, { title: 'bbb', contentList: [{}, {}] }], // 未执行
active: 'first'
uiSceneStepsAllReportVOList: [], // 全部
uiSceneStepsErrorReportVOList: [{ title: 'aaa', contentList: [{}, {}] }, { title: 'bbb', contentList: [{}, {}] }], // 失败
uiSceneStepsNotReportVOList: [{ title: 'aaa', contentList: [{}, {}] }, { title: 'bbb', contentList: [{}, {}] }], // 未执行
active: 'first',
detailData: {}, // 详情内容
}
},
mounted() {
this.getDetailDAta()
},
methods: {
handleClick() { },
// 获取详情
getDetailDAta() {
getTestReportDetail(this.$route.query.id).then(res => {
if (res.code === 200) {
this.detailData = res.data
this.uiSceneStepsAllReportVOList = res.data.uiSceneStepsAllReportVOList
this.uiSceneStepsErrorReportVOList = res.data.uiSceneStepsErrorReportVOList
this.uiSceneStepsNotReportVOList = res.data.uiSceneStepsNotReportVOList
}
})
},
// 截图
clickHandleScreenshot() {
console.log('截图')
@@ -224,6 +290,13 @@ export default {
border-radius: 5px;
}
.gray-wrap {
width: 10px;
height: 10px;
background-color: gray;
border-radius: 5px;
}
.header-content {
display: flex;
align-items: center;
@@ -316,7 +389,33 @@ export default {
}
.list-sub-wrap {
margin-left: 20px;
margin-left: 40px;
.sub-collapse {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding-right: 20px;
.left-collapse {
display: flex;
align-items: center;
gap: 10px;
}
.right-collapse {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 10px;
.collapse-status {
width: 60px;
text-align: center;
}
}
}
.sub-title {
margin-right: 10px;
@@ -336,6 +435,17 @@ export default {
gap: 30px;
}
}
.tab-content {
padding: 0px 10px;
}
}
}
::v-deep .el-divider--horizontal {
display: block;
height: 1px;
width: 100%;
margin: 10px 0;
}
</style>

View File

@@ -35,7 +35,7 @@ module.exports = {
proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://ah.qyyh.net:1371/prod-api/`,
target: `http://47.99.93.74:8012/prod-api/`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''