UNPKG

yapi-plugin-pl-test-dashboard

Version:

YAPI自动化测试结果数据面板插件,支持在YAPI中通过数据可视化的方式查看自动化测试结果。

439 lines (406 loc) 11.5 kB
import { Bar, Column, Pie, StackedColumn } from '@antv/g2plot' import { DatePicker, Radio, Tabs } from 'antd' import 'antd/dist/antd.css' import axios from 'axios' import React, { useEffect, useState } from 'react' import { getCurrentMonth, getCurrentWeek, getProjectId, } from '../../../utils/index' import './index.scss' const { TabPane } = Tabs const { RangePicker } = DatePicker const TODAY = new Date(new Date().setHours(0, 0, 0, 0)) export default function TestResult() { const [sourcePiePlot, setSourcePiePlot] = useState(null) const [sourceBarPlot, setSourceBarPlot] = useState(null) // 集合 const [setRateColumnPlot, setSetRateColumnPlot] = useState(null) const [setCountColumnPlot, setSetCountColumnPlot] = useState(null) // 用例 const [caseRateColumnPlot, setCaseRateColumnPlot] = useState(null) const [caseCountColumnPlot, setCaseCountColumnPlot] = useState(null) const [isSourceDataError, setIsSourceDataError] = useState(false) const [isSetDataError, setIsSetDataError] = useState(false) const [isCaseDataError, setIsCaseDataError] = useState(false) const [selectDate, setSelectDate] = useState('day') const [activeTabKey, setActiveTabKey] = useState('set') const [startTime, setStartTime] = useState(TODAY.toISOString()) const [endTime, setEndTime] = useState(new Date().toISOString()) const [projectId, setProjectId] = useState('32') // // 改变时间 const handleChangeDateType = (e) => { setSelectDate(e.target.value) switch (e.target.value) { case 'day': setStartTime(TODAY.toISOString()) setEndTime(new Date().toISOString()) break case 'week': const weekDate = getCurrentWeek() setStartTime(weekDate[0]) setEndTime(weekDate[1]) break case 'month': const monthDate = getCurrentMonth() setStartTime(monthDate[0]) setEndTime(monthDate[1]) break } } const tabOperations = () => { return ( <div className="operations_content"> <Radio.Group onChange={handleChangeDateType} defaultValue={selectDate} style={{ marginRight: '10px' }} > <Radio.Button value="day">今日</Radio.Button> <Radio.Button value="week">本周</Radio.Button> <Radio.Button value="month">本月</Radio.Button> </Radio.Group> <RangePicker showTime onChange={(value, dateString) => { setSelectDate('') const start = new Date(dateString[0]) const end = new Date(dateString[1]) setStartTime(start.toISOString()) setEndTime(end.toISOString()) }} /> </div> ) } const emptyPage = () => { return ( <div className="empty_page"> <p className="empty_page-text">暂无数据</p> </div> ) } // 初始化数据来源饼图数据 const initSourcePieChart = async () => { setIsSourceDataError(false) if (activeTabKey !== 'source') { return } const result = await axios.get( `/api/plugin/test/dashboard/source?projectId=${getProjectId()}&startTime=${startTime}&endTime=${endTime}` ) if (result.data && result.data.errcode && result.data.errcode === 40011) { setIsSourceDataError(true) return } const { percent, count } = result.data if ((percent && percent.length === 0) || (count && count.length === 0)) { setIsSourceDataError(true) return } if (sourcePiePlot || sourceBarPlot) { sourcePiePlot.destroy() sourceBarPlot.destroy() } const _sourcePiePlot = new Pie(document.getElementById('chartSourcePie'), { forceFit: true, title: { visible: true, text: '数据来源分析(通过率)', }, color: ['#94b2f3', '#90d9b6', '#db8470'], radius: 0.8, data: percent, angleField: 'value', colorField: 'type', label: { visible: true, type: 'inner', formatter: (text, data, index) => { const value = (data.percent * 100).toFixed(1) return `${value}%` }, }, }) _sourcePiePlot.render() setSourcePiePlot(_sourcePiePlot) const _sourceBarPlot = new Bar(document.getElementById('chartSourceBar'), { title: { visible: true, text: '数据来源分析(次数)', }, forceFit: true, data: count, xField: 'value', yField: 'type', barSize: 30, xAxis: { grid: { visible: true, }, }, }) _sourceBarPlot.render() setSourceBarPlot(_sourceBarPlot) } // 初始化测试集合柱状图数据 const initSetBarChart = async () => { setIsSetDataError(false) if (activeTabKey !== 'set') { return } const result = await axios.get( `/api/plugin/test/dashboard/set?projectId=${getProjectId()}&startTime=${startTime}&endTime=${endTime}` ) if (result.data && result.data.errcode && result.data.errcode === 40011) { setIsSetDataError(true) console.log( 'initSetBarChart -> Set data is error or empty', isSetDataError ) return } const { percent, count } = result.data if ((percent && percent.length === 0) || (count && count.length === 0)) { setIsSetDataError(true) console.log( 'initSetBarChart -> Set data is error or empty', isSetDataError ) return } if (setRateColumnPlot || setCountColumnPlot) { setRateColumnPlot.destroy() setCountColumnPlot.destroy() } const _setRateColumnPlot = new Column( document.getElementById('chartSetRateBar'), { title: { visible: true, text: '测试集合分析(通过率)', }, forceFit: true, padding: 'auto', data: percent, xField: 'type', yField: 'value', tooltip: { formatter: (text, data, index) => { const value = (data * 100).toFixed(1) return { name: text, value: `${value}%`, } }, }, yAxis: { label: { visible: true, formatter: (text, data, index) => { const value = (data.value * 100).toFixed(1) return `${value}%` }, }, }, barSize: 30, meta: { type: { alias: '测试集合', }, value: { alias: '通过率(%)', }, }, } ) _setRateColumnPlot.render() setSetRateColumnPlot(_setRateColumnPlot) const _setCountColumnPlot = new StackedColumn( document.getElementById('chartSetStackColumn'), { title: { visible: true, text: '测试集合分析(次数)', }, forceFit: true, data: count, padding: 'auto', xField: 'type', yField: 'value', barSize: 30, yAxis: { min: 0, }, meta: { type: { alias: '测试集合', }, value: { alias: '次数', }, }, stackField: 'series', } ) _setCountColumnPlot.render() setSetCountColumnPlot(_setCountColumnPlot) } // 初始化测试用例柱状图数据 const initAnalysisBarChart = async () => { setIsCaseDataError(false) if (activeTabKey !== 'analysis') { return } const result = await axios.get( `/api/plugin/test/dashboard/case?projectId=${getProjectId()}&startTime=${startTime}&endTime=${endTime}` ) if (result.data && result.data.errcode && result.data.errcode === 40011) { setIsCaseDataError(true) return } const { percent, count } = result.data if ((percent && percent.length === 0) || (count && count.length === 0)) { setIsCaseDataError(true) return } if (caseRateColumnPlot || caseCountColumnPlot) { caseRateColumnPlot.destroy() caseCountColumnPlot.destroy() } const _caseRateColumnPlot = new Column( document.getElementById('chartAnalysisBar'), { title: { visible: true, text: '测试用例分析(通过率)', }, forceFit: true, padding: 'auto', data: percent, xField: 'type', yField: 'value', tooltip: { formatter: (text, data, index) => { const value = (data * 100).toFixed(1) return { name: text, value: `${value}%`, } }, }, yAxis: { label: { visible: true, formatter: (text, data, index) => { const value = (data.value * 100).toFixed(1) return `${value}%` }, }, }, barSize: 30, meta: { type: { alias: '测试用例', }, value: { alias: '通过率(%)', }, }, } ) _caseRateColumnPlot.render() setCaseRateColumnPlot(_caseRateColumnPlot) const _caseCountColumnPlot = new StackedColumn( document.getElementById('chartAnalysisColumn'), { title: { visible: true, text: '测试用例分析(次数)', }, forceFit: true, data: count, padding: 'auto', xField: 'type', yField: 'value', barSize: 30, yAxis: { min: 0, }, meta: { type: { alias: '测试用例', }, value: { alias: '次数', }, }, stackField: 'series', } ) _caseCountColumnPlot.render() setCaseCountColumnPlot(_caseCountColumnPlot) } const initData = () => { switch (activeTabKey) { case 'source': initSourcePieChart() break case 'set': initSetBarChart() break case 'analysis': initAnalysisBarChart() break } } useEffect(() => { initData() }, [activeTabKey, selectDate]) return ( <Tabs tabBarExtraContent={tabOperations()} defaultActiveKey={activeTabKey} activeKey={activeTabKey} onChange={(key) => { setActiveTabKey(key) }} > <TabPane tab="测试集合分析" key="set"> {activeTabKey === 'set' && (isSetDataError ? ( emptyPage() ) : ( <div className="dashboard_content-set"> <div id="chartSetRateBar"></div> <div id="chartSetStackColumn"></div> </div> ))} </TabPane> <TabPane tab="测试用例分析" key="analysis"> {activeTabKey === 'analysis' && (isCaseDataError ? ( emptyPage() ) : ( <div className="dashboard_content-analysis"> <div id="chartAnalysisBar"></div> <div id="chartAnalysisColumn"></div> </div> ))} </TabPane> <TabPane tab="数据来源分析" key="source"> {activeTabKey === 'source' && (isSourceDataError ? ( emptyPage() ) : ( <div className="dashboard_content-source"> <div id="chartSourcePie"></div> <div id="chartSourceBar"></div> </div> ))} </TabPane> </Tabs> ) }