提交 c247de85 authored 作者: 陈泽健's avatar 陈泽健

feat(script): 实现服务自检报告的 Markdown 导出功能

- 新增 Markdown 报告生成功能,支持将检测结果导出为 .md 文件
- 优化报告目录创建逻辑,增加临时目录 fallback 机制
- 完善各类检测项的 Markdown 内容生成,包括系统类型、服务状态、资源信息等
- 修复 NTP 时间检测逻辑,移除硬编码时区偏移
- 更新文件权限检测路径,调整部分中文路径配置
- 增强文件权限检测输出结构,返回更详细的摘要信息
- 移除冗余 HTML 报告文件,统一使用 Markdown 格式输出
上级 5af4f8bd
<!DOCTYPE html>
<html>
<head>
<title>兰州中石化项目测试报告</title>
<meta charset="UTF-8">
<style>body {
font-family: consolas, Verdana, sans-serif;
font-size: 1.2em;
color: #696e71;
display: grid;
grid-template-columns: 1fr 5rem;
}
.main_section {
width: 90%;
margin: 0 auto;
}
#float_menu{
position:fixed;
top:0;
right:0;
text-align: center;
}
#float_menu .menu-item {
cursor: pointer;
padding: .5em;
margin: .5em 0;
color: #c08580;
background-color: #f8f0ef;
font-size: 1.2em;
}
.result{
display: flex;
}
.result_table{
border-collapse: collapse;
border: 1px solid #f0e0e5;
width: 30em;
text-align: center;
font-size: 1.0em;
}
.result_table td{
border: 1px solid #f0e0e5;
padding: .3em;
}
.result_barchart{
width: 30em;
margin: 0 5em 0 5em;
}
.barchar_item{
margin: 2.5rem 0;
}
.barchart_barbox {
margin: 0.5em 0;
width: 100%;
background-color: #fff;
border: 1px solid #86c2dd;
border-radius: .2em;
}
.barchart_bar {
text-align: right;
height: 1.2rem;
}
.h3_button {
margin: 1.5em;
cursor: pointer;
color: #03a9f4;
}
.info
{
white-space:pre-wrap;
margin: .8em 1.5em;
}
.error-info
{
color: #a64747
}
.suite_dir {
margin: 1em .2em;
padding: .3em;
/* background-color: #dfeff6; */
border: 1px solid #bcd8e4;
}
.suite_file {
margin: 1em .2em;
padding: .3em;
border: 1px solid #bcd8e4;
}
.case {
margin: 1em .2em;
/* padding: .3em; */
border: 1px solid #e7d4d4;
}
.case_class_path{
margin: 0em 1em;
}
.folder_header {
padding: .2em .7em;
background-color: #fffaf9;
cursor: pointer;
}
.setup{
margin: .2em;
/* padding: .3em; */
/* border: 1px solid #e7d4d4; */
}
.teardown{
margin: .2em;
/* padding: .3em;*/
/* border: 1px solid #e7d4d4; */
}
.test_steps{
margin: .2em;
padding: .3em;
/* border: 1px solid #e7d4d4; */
}
.label {
display: inline-block;
padding: .1em .5em;
font-size: .88em;
letter-spacing: 1px;
white-space: nowrap;
color: #0d6ebc;
border-radius: .2em;
min-width: 5em;
margin-right: 2em;
font-family: consolas;
}
/* .suite_setup .label{
color: #219e26 ;
}
.suite_teardown .label{
color: #219e26;
} */
/* .case.pass .casename{
color: #329132 ;
} */
.case.pass .caselabel{
color: white;
background-color: #3b9e3f;
}
/* .case.fail .casename{
color: #a64747;
} */
.case.fail .caselabel{
color: white;
background-color: #a64747;
}
/* .case.abort .casename{
color: #953ab7;
} */
.case.abort .caselabel{
color: white;
background-color: #9c27b0;
}
.case_step {
margin: .8em;
}
.checkpoint_pass {
margin: .8em;
}
.checkpoint_fail {
margin: .8em;
}
.case_step .tag{
color: #2196f3;;
margin: .3em 1em .3em 0;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_pass .tag{
color: #009806;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_fail .tag{
color: #9c2020;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.screenshot {
border: 1px solid #86c2dd;
}
.executetime {
float: right;
}
/* 模态框内容 */
.modal-content {
margin: auto;
display: block;
width: 95%;
max-width: 700px;
max-height: 80vh; /* 设置最大高度为视口高度的80% */
object-fit: contain; /* 保持图片的宽高比 */
zoom: 3;
}
/* 模态框 */
.modal {
display: none; /* 隐藏 */
position: fixed; /* 固定位置 */
z-index: 1; /* 坐在顶部 */
padding-top: 40px; /* 在图片上方添加一些内边距 */
left: 0;
top: 0;
width: 100%; /* 宽度 */
height: 100%; /* 高度 */
overflow: auto; /* 启用滚动 */
background-color: rgb(0,0,0); /* 背景颜色 */
background-color: rgba(0,0,0,0.9); /* 黑色背景半透明 */
}
/* 关闭按钮 */
.close {
position: absolute; /* 定义元素的定位方式为绝对定位 */
top: 10px; /* 距离最近的已定位祖先元素顶部15像素 */
right: 30px; /* 距离最近的已定位祖先元素右侧35像素 */
color: #f1f1f1; /* 文本颜色为浅灰色 */
font-size: 15px; /* 字体大小为40像素 */
font-weight: bold; /* 字体加粗 */
transition: 0.3s; /* 过渡效果,0.3秒内完成 */
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
</style>
<script type="text/javascript">var FOLDER_ALL_CASES = false; // 是否为精简模式的标记
var ERROR_INFOS = []; // 错误信息列表
var current_error_idx = -1;
// 页面加载后执行的函数
window.addEventListener("load", function(){
// 所有 .folder_header 添加点击事件处理
let folderHeaderEles = document.querySelectorAll(".folder_header");
folderHeaderEles.forEach(function(ele) {
ele.addEventListener("click", function(event) {
let fb = event.target.closest('.folder_header').nextElementSibling;
fb.style.display = fb.style.display === 'none' ? 'block' : 'none';
});
});
// 找到所有的错误信息对象
ERROR_INFOS = document.querySelectorAll(".error-info");
// 获取所有图片元素
let images = document.querySelectorAll('.modal-image');
// 获取模态框元素
let modal = document.getElementById("imageModal");
// 获取模态框中的图片元素
let modalImg = document.getElementById("img01");
// 获取关闭按钮元素
let span = document.getElementsByClassName("close")[0];
// 为每个图片添加点击事件监听器
images.forEach(function(img) {
img.addEventListener("click", function() {
modal.style.display = "block"; // 显示模态框
modalImg.src = this.src; // 设置模态框中的图片为点击的图片
});
});
// 当点击关闭按钮时,隐藏模态框
span.onclick = function() {
modal.style.display = "none";
};
// 当点击模态框外区域时,隐藏模态框
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
});
function toggle_folder_all_cases(){
let eles = document.querySelectorAll(".folder_body");
FOLDER_ALL_CASES = !FOLDER_ALL_CASES;
document.getElementById('display_mode').innerHTML = FOLDER_ALL_CASES ? "Detail" : "Summary";
for (const ele of eles){
ele.style.display = FOLDER_ALL_CASES ? "none" : "block";
}
}
function previous_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx -= 1;
if (current_error_idx < 0)
current_error_idx = 0;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
function next_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx += 1;
if (current_error_idx > ERROR_INFOS.length - 1)
current_error_idx = ERROR_INFOS.length - 1;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
</script>
</head>
<body>
<div class="modal" id="imageModal">
<div>
<img class="modal-content" id="img01">
<span class="close">关闭</span>
</div>
</div>
<div class="main_section">
<h1 style="font-family: auto">兰州中石化项目测试报告</h1>
<h3>统计结果</h3>
<div class="result">
<table class="result_table">
<tbody>
<tr>
<td>hytest 版本</td>
<td>0.8.12</td>
</tr>
<tr>
<td>开始时间</td>
<td>2025/06/25 09:50:03</td>
</tr>
<tr>
<td>结束时间</td>
<td>2025/06/25 09:51:08</td>
</tr>
<tr>
<td>耗时</td>
<td>64.642 秒</td>
</tr>
<tr>
<td>预备执行用例数量</td>
<td>1</td>
</tr>
<tr>
<td>实际执用例行数量</td>
<td>1</td>
</tr>
<tr>
<td>通过</td>
<td>0</td>
</tr>
<tr>
<td>失败</td>
<td style="color:red">1</td>
</tr>
<tr>
<td>异常</td>
<td style="">0</td>
</tr>
<tr>
<td>阻塞</td>
<td style="">0</td>
</tr>
<tr>
<td>套件初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>套件清除 失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例清除 失败</td>
<td style="">0</td>
</tr>
</tbody>
</table>
<div class="result_barchart">
<div class="barchar_item">
<span>用例通过 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #04AA6D;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例失败 100% : 1 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 100.0%; background-color: #bb4069;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例异常 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #9c27b0;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例阻塞 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #dcbdbd;"></div>
</div>
</div>
</div>
</div>
<div style="margin-top:2em">
<h3 style="display:inline">执行日志</h3>
</div>
<div class="exec_log">
<div class="suite_dir" id="suite_dir cases\">
<div>
<span class="label">进入目录</span>
<span>cases\</span>
</div>
</div>
<div class="suite_dir" id="suite_dir cases\项目定制\兰州中石化项目25-05-24\">
<div>
<span class="label">进入目录</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
</div>
<div class="suite_setup setup" id="suite_setup setup cases\项目定制\兰州中石化项目25-05-24\">
<div class="folder_header">
<span class="label">套件初始化</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
<span class="executetime">2025-06-25 09:50:03</span>
</div>
<div class="folder_body">
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>初始化浏览器</span>
</div>
<div class="info">'----------' 正在初始化浏览器 '----------'</div>
<div class="info">'----------' 浏览器初始化完成 '----------'</div>
<div class="info">输入用户名:admin</div>
<div class="info">输入密码:Ubains@4321</div>
<div class="info">输入验证码:csba</div>
<div class="info">点击登录按钮</div>
</div>
</div>
</div>
<div class="suite_file" id="suite_file cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py">
<div>
<span class="label">进入文件</span>
<span>cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py</span>
</div>
<div class="case fail" id="case_00000001">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">会议申报测试015</span>
<span class="executetime">2025-06-25 09:50:10</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py::LanzhouSinopecProject</span>
<div class="test_steps" id="test_steps 会议申报测试015">
<span class="label">测试步骤</span>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //div[@id='CreateMeeting']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095013175010.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: id、元素定位值: create-meeting-name-input、元素类型: input、元素值: 会议申报测试015、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095015534652.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-start-time-datepicker']、元素类型: input、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095017828422.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //button[@class='el-button el-picker-panel__link-btn el-button--default el-button--mini is-plain']//span[contains(text(),'确定')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095020096921.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-location-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095022347717.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //span[contains(text(),'会议申报会议室015')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095024592779.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@placeholder='请选择主办单位']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095026836919.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: (//div[@class='el-tree-node__content'])[10]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095029090005.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: (//button[@id='tree-selector-confirm'])[3]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095031352340.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-compere-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095033615661.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //div[@x-placement='bottom-start']//span[contains(text(),'范公司主管领导')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095035889982.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-department-leader-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095038167141.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //span[contains(text(),'陈部门领导')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095040429005.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-company-leader-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095042673478.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: (//span[contains(text(),'范公司主管领导')])[3]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095044926003.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //span[contains(text(),'提交')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095047256265.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //p[@class='el-message__content']、元素类型: getTips、元素值: 、预期结果: 请选择会议开始时间</div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095047417632.png" width="50%">
</div>
<div class="info">获取到的提示信息为:会议预定成功</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>获取到的提示信息为:会议预定成功</span>
</div>
<div class="info error-info">
Traceback:
File &quot;E:\GithubData\自动化\ubains-module-test\预定系统\cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py&quot;, line 90, in teststeps
CHECK_POINT(f&quot;获取到的提示信息为:{notify_text}&quot;, expented_result in notify_text)</div>
</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\项目定制\兰州中石化项目25-05-24\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
<span class="executetime">2025-06-25 09:50:49</span>
</div>
<div class="folder_body"></div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\</span>
<span class="executetime">2025-06-25 09:50:51</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
</div>
</div>
</div>
<div id="float_menu">
<div class="menu-item" onclick="document.querySelector(&quot;body&quot;).scrollIntoView()">页首</div>
<div class="menu-item" onclick="window.open(&quot;http://www.byhy.net/tut/auto/hytest/01&quot;, &quot;_blank&quot;); ">帮助</div>
<div class="menu-item" id="display_mode" onclick="toggle_folder_all_cases()">Summary</div>
<div class="error_jumper" display="block">
<div class="menu-item" onclick="previous_error()" title="上一个错误"></div>
<div class="menu-item" onclick="next_error()" title="下一个错误"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>会议预约测试报告</title>
<meta charset="UTF-8">
<style>body {
font-family: consolas, Verdana, sans-serif;
font-size: 1.2em;
color: #696e71;
display: grid;
grid-template-columns: 1fr 5rem;
}
.main_section {
width: 90%;
margin: 0 auto;
}
#float_menu{
position:fixed;
top:0;
right:0;
text-align: center;
}
#float_menu .menu-item {
cursor: pointer;
padding: .5em;
margin: .5em 0;
color: #c08580;
background-color: #f8f0ef;
font-size: 1.2em;
}
.result{
display: flex;
}
.result_table{
border-collapse: collapse;
border: 1px solid #f0e0e5;
width: 30em;
text-align: center;
font-size: 1.0em;
}
.result_table td{
border: 1px solid #f0e0e5;
padding: .3em;
}
.result_barchart{
width: 30em;
margin: 0 5em 0 5em;
}
.barchar_item{
margin: 2.5rem 0;
}
.barchart_barbox {
margin: 0.5em 0;
width: 100%;
background-color: #fff;
border: 1px solid #86c2dd;
border-radius: .2em;
}
.barchart_bar {
text-align: right;
height: 1.2rem;
}
.h3_button {
margin: 1.5em;
cursor: pointer;
color: #03a9f4;
}
.info
{
white-space:pre-wrap;
margin: .8em 1.5em;
}
.error-info
{
color: #a64747
}
.suite_dir {
margin: 1em .2em;
padding: .3em;
/* background-color: #dfeff6; */
border: 1px solid #bcd8e4;
}
.suite_file {
margin: 1em .2em;
padding: .3em;
border: 1px solid #bcd8e4;
}
.case {
margin: 1em .2em;
/* padding: .3em; */
border: 1px solid #e7d4d4;
}
.case_class_path{
margin: 0em 1em;
}
.folder_header {
padding: .2em .7em;
background-color: #fffaf9;
cursor: pointer;
}
.setup{
margin: .2em;
/* padding: .3em; */
/* border: 1px solid #e7d4d4; */
}
.teardown{
margin: .2em;
/* padding: .3em;*/
/* border: 1px solid #e7d4d4; */
}
.test_steps{
margin: .2em;
padding: .3em;
/* border: 1px solid #e7d4d4; */
}
.label {
display: inline-block;
padding: .1em .5em;
font-size: .88em;
letter-spacing: 1px;
white-space: nowrap;
color: #0d6ebc;
border-radius: .2em;
min-width: 5em;
margin-right: 2em;
font-family: consolas;
}
/* .suite_setup .label{
color: #219e26 ;
}
.suite_teardown .label{
color: #219e26;
} */
/* .case.pass .casename{
color: #329132 ;
} */
.case.pass .caselabel{
color: white;
background-color: #3b9e3f;
}
/* .case.fail .casename{
color: #a64747;
} */
.case.fail .caselabel{
color: white;
background-color: #a64747;
}
/* .case.abort .casename{
color: #953ab7;
} */
.case.abort .caselabel{
color: white;
background-color: #9c27b0;
}
.case_step {
margin: .8em;
}
.checkpoint_pass {
margin: .8em;
}
.checkpoint_fail {
margin: .8em;
}
.case_step .tag{
color: #2196f3;;
margin: .3em 1em .3em 0;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_pass .tag{
color: #009806;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_fail .tag{
color: #9c2020;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.screenshot {
border: 1px solid #86c2dd;
}
.executetime {
float: right;
}
/* 模态框内容 */
.modal-content {
margin: auto;
display: block;
width: 95%;
max-width: 700px;
max-height: 80vh; /* 设置最大高度为视口高度的80% */
object-fit: contain; /* 保持图片的宽高比 */
zoom: 3;
}
/* 模态框 */
.modal {
display: none; /* 隐藏 */
position: fixed; /* 固定位置 */
z-index: 1; /* 坐在顶部 */
padding-top: 40px; /* 在图片上方添加一些内边距 */
left: 0;
top: 0;
width: 100%; /* 宽度 */
height: 100%; /* 高度 */
overflow: auto; /* 启用滚动 */
background-color: rgb(0,0,0); /* 背景颜色 */
background-color: rgba(0,0,0,0.9); /* 黑色背景半透明 */
}
/* 关闭按钮 */
.close {
position: absolute; /* 定义元素的定位方式为绝对定位 */
top: 10px; /* 距离最近的已定位祖先元素顶部15像素 */
right: 30px; /* 距离最近的已定位祖先元素右侧35像素 */
color: #f1f1f1; /* 文本颜色为浅灰色 */
font-size: 15px; /* 字体大小为40像素 */
font-weight: bold; /* 字体加粗 */
transition: 0.3s; /* 过渡效果,0.3秒内完成 */
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
</style>
<script type="text/javascript">var FOLDER_ALL_CASES = false; // 是否为精简模式的标记
var ERROR_INFOS = []; // 错误信息列表
var current_error_idx = -1;
// 页面加载后执行的函数
window.addEventListener("load", function(){
// 所有 .folder_header 添加点击事件处理
let folderHeaderEles = document.querySelectorAll(".folder_header");
folderHeaderEles.forEach(function(ele) {
ele.addEventListener("click", function(event) {
let fb = event.target.closest('.folder_header').nextElementSibling;
fb.style.display = fb.style.display === 'none' ? 'block' : 'none';
});
});
// 找到所有的错误信息对象
ERROR_INFOS = document.querySelectorAll(".error-info");
// 获取所有图片元素
let images = document.querySelectorAll('.modal-image');
// 获取模态框元素
let modal = document.getElementById("imageModal");
// 获取模态框中的图片元素
let modalImg = document.getElementById("img01");
// 获取关闭按钮元素
let span = document.getElementsByClassName("close")[0];
// 为每个图片添加点击事件监听器
images.forEach(function(img) {
img.addEventListener("click", function() {
modal.style.display = "block"; // 显示模态框
modalImg.src = this.src; // 设置模态框中的图片为点击的图片
});
});
// 当点击关闭按钮时,隐藏模态框
span.onclick = function() {
modal.style.display = "none";
};
// 当点击模态框外区域时,隐藏模态框
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
});
function toggle_folder_all_cases(){
let eles = document.querySelectorAll(".folder_body");
FOLDER_ALL_CASES = !FOLDER_ALL_CASES;
document.getElementById('display_mode').innerHTML = FOLDER_ALL_CASES ? "Detail" : "Summary";
for (const ele of eles){
ele.style.display = FOLDER_ALL_CASES ? "none" : "block";
}
}
function previous_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx -= 1;
if (current_error_idx < 0)
current_error_idx = 0;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
function next_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx += 1;
if (current_error_idx > ERROR_INFOS.length - 1)
current_error_idx = ERROR_INFOS.length - 1;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
</script>
</head>
<body>
<div class="modal" id="imageModal">
<div>
<img class="modal-content" id="img01">
<span class="close">关闭</span>
</div>
</div>
<div class="main_section">
<h1 style="font-family: auto">会议预约测试报告</h1>
<h3>统计结果</h3>
<div class="result">
<table class="result_table">
<tbody>
<tr>
<td>hytest 版本</td>
<td>0.8.12</td>
</tr>
<tr>
<td>开始时间</td>
<td>2025/03/21 17:18:58</td>
</tr>
<tr>
<td>结束时间</td>
<td>2025/03/21 17:19:49</td>
</tr>
<tr>
<td>耗时</td>
<td>50.609 秒</td>
</tr>
<tr>
<td>预备执行用例数量</td>
<td>1</td>
</tr>
<tr>
<td>实际执用例行数量</td>
<td>1</td>
</tr>
<tr>
<td>通过</td>
<td>1</td>
</tr>
<tr>
<td>失败</td>
<td style="">0</td>
</tr>
<tr>
<td>异常</td>
<td style="">0</td>
</tr>
<tr>
<td>阻塞</td>
<td style="">0</td>
</tr>
<tr>
<td>套件初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>套件清除 失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例清除 失败</td>
<td style="">0</td>
</tr>
</tbody>
</table>
<div class="result_barchart">
<div class="barchar_item">
<span>用例通过 100% : 1 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 100.0%; background-color: #04AA6D;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例失败 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #bb4069;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例异常 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #9c27b0;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例阻塞 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #dcbdbd;"></div>
</div>
</div>
</div>
</div>
<div style="margin-top:2em">
<h3 style="display:inline">执行日志</h3>
</div>
<div class="exec_log">
<div class="suite_dir" id="suite_dir cases\主流程功能\">
<div>
<span class="label">进入目录</span>
<span>cases\主流程功能\</span>
</div>
<div class="suite_setup setup" id="suite_setup setup cases\主流程功能\">
<div class="folder_header">
<span class="label">套件初始化</span>
<span>cases\主流程功能\</span>
<span class="executetime">2025-03-21 17:18:58</span>
</div>
<div class="folder_body">
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>初始化浏览器</span>
</div>
<div class="info">'----------' 正在初始化浏览器 '----------'</div>
<div class="info">'----------' 浏览器初始化完成 '----------'</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>登录系统</span>
</div>
</div>
</div>
</div>
<div class="suite_file" id="suite_file cases\主流程功能\04调试创建会议.py">
<div>
<span class="label">进入文件</span>
<span>cases\主流程功能\04调试创建会议.py</span>
</div>
<div class="case pass" id="case_00000001">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">Unified_Platform_0001</span>
<span class="executetime">2025-03-21 17:19:31</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\主流程功能\04调试创建会议.py::Unified_Platform_0001</span>
<div class="test_steps" id="test_steps Unified_Platform_0001">
<span class="label">测试步骤</span>
</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\主流程功能\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\主流程功能\</span>
<span class="executetime">2025-03-21 17:19:46</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
</div>
</div>
</div>
<div id="float_menu">
<div class="menu-item" onclick="document.querySelector(&quot;body&quot;).scrollIntoView()">页首</div>
<div class="menu-item" onclick="window.open(&quot;http://www.byhy.net/tut/auto/hytest/01&quot;, &quot;_blank&quot;); ">帮助</div>
<div class="menu-item" id="display_mode" onclick="toggle_folder_all_cases()">Summary</div>
<div class="error_jumper" display="none">
<div class="menu-item" onclick="previous_error()" title="上一个错误"></div>
<div class="menu-item" onclick="next_error()" title="下一个错误"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>会议预约测试报告</title>
<meta charset="UTF-8">
<style>body {
font-family: consolas, Verdana, sans-serif;
font-size: 1.2em;
color: #696e71;
display: grid;
grid-template-columns: 1fr 5rem;
}
.main_section {
width: 90%;
margin: 0 auto;
}
#float_menu{
position:fixed;
top:0;
right:0;
text-align: center;
}
#float_menu .menu-item {
cursor: pointer;
padding: .5em;
margin: .5em 0;
color: #c08580;
background-color: #f8f0ef;
font-size: 1.2em;
}
.result{
display: flex;
}
.result_table{
border-collapse: collapse;
border: 1px solid #f0e0e5;
width: 30em;
text-align: center;
font-size: 1.0em;
}
.result_table td{
border: 1px solid #f0e0e5;
padding: .3em;
}
.result_barchart{
width: 30em;
margin: 0 5em 0 5em;
}
.barchar_item{
margin: 2.5rem 0;
}
.barchart_barbox {
margin: 0.5em 0;
width: 100%;
background-color: #fff;
border: 1px solid #86c2dd;
border-radius: .2em;
}
.barchart_bar {
text-align: right;
height: 1.2rem;
}
.h3_button {
margin: 1.5em;
cursor: pointer;
color: #03a9f4;
}
.info
{
white-space:pre-wrap;
margin: .8em 1.5em;
}
.error-info
{
color: #a64747
}
.suite_dir {
margin: 1em .2em;
padding: .3em;
/* background-color: #dfeff6; */
border: 1px solid #bcd8e4;
}
.suite_file {
margin: 1em .2em;
padding: .3em;
border: 1px solid #bcd8e4;
}
.case {
margin: 1em .2em;
/* padding: .3em; */
border: 1px solid #e7d4d4;
}
.case_class_path{
margin: 0em 1em;
}
.folder_header {
padding: .2em .7em;
background-color: #fffaf9;
cursor: pointer;
}
.setup{
margin: .2em;
/* padding: .3em; */
/* border: 1px solid #e7d4d4; */
}
.teardown{
margin: .2em;
/* padding: .3em;*/
/* border: 1px solid #e7d4d4; */
}
.test_steps{
margin: .2em;
padding: .3em;
/* border: 1px solid #e7d4d4; */
}
.label {
display: inline-block;
padding: .1em .5em;
font-size: .88em;
letter-spacing: 1px;
white-space: nowrap;
color: #0d6ebc;
border-radius: .2em;
min-width: 5em;
margin-right: 2em;
font-family: consolas;
}
/* .suite_setup .label{
color: #219e26 ;
}
.suite_teardown .label{
color: #219e26;
} */
/* .case.pass .casename{
color: #329132 ;
} */
.case.pass .caselabel{
color: white;
background-color: #3b9e3f;
}
/* .case.fail .casename{
color: #a64747;
} */
.case.fail .caselabel{
color: white;
background-color: #a64747;
}
/* .case.abort .casename{
color: #953ab7;
} */
.case.abort .caselabel{
color: white;
background-color: #9c27b0;
}
.case_step {
margin: .8em;
}
.checkpoint_pass {
margin: .8em;
}
.checkpoint_fail {
margin: .8em;
}
.case_step .tag{
color: #2196f3;;
margin: .3em 1em .3em 0;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_pass .tag{
color: #009806;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_fail .tag{
color: #9c2020;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.screenshot {
border: 1px solid #86c2dd;
}
.executetime {
float: right;
}
/* 模态框内容 */
.modal-content {
margin: auto;
display: block;
width: 95%;
max-width: 700px;
max-height: 80vh; /* 设置最大高度为视口高度的80% */
object-fit: contain; /* 保持图片的宽高比 */
zoom: 3;
}
/* 模态框 */
.modal {
display: none; /* 隐藏 */
position: fixed; /* 固定位置 */
z-index: 1; /* 坐在顶部 */
padding-top: 40px; /* 在图片上方添加一些内边距 */
left: 0;
top: 0;
width: 100%; /* 宽度 */
height: 100%; /* 高度 */
overflow: auto; /* 启用滚动 */
background-color: rgb(0,0,0); /* 背景颜色 */
background-color: rgba(0,0,0,0.9); /* 黑色背景半透明 */
}
/* 关闭按钮 */
.close {
position: absolute; /* 定义元素的定位方式为绝对定位 */
top: 10px; /* 距离最近的已定位祖先元素顶部15像素 */
right: 30px; /* 距离最近的已定位祖先元素右侧35像素 */
color: #f1f1f1; /* 文本颜色为浅灰色 */
font-size: 15px; /* 字体大小为40像素 */
font-weight: bold; /* 字体加粗 */
transition: 0.3s; /* 过渡效果,0.3秒内完成 */
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
</style>
<script type="text/javascript">var FOLDER_ALL_CASES = false; // 是否为精简模式的标记
var ERROR_INFOS = []; // 错误信息列表
var current_error_idx = -1;
// 页面加载后执行的函数
window.addEventListener("load", function(){
// 所有 .folder_header 添加点击事件处理
let folderHeaderEles = document.querySelectorAll(".folder_header");
folderHeaderEles.forEach(function(ele) {
ele.addEventListener("click", function(event) {
let fb = event.target.closest('.folder_header').nextElementSibling;
fb.style.display = fb.style.display === 'none' ? 'block' : 'none';
});
});
// 找到所有的错误信息对象
ERROR_INFOS = document.querySelectorAll(".error-info");
// 获取所有图片元素
let images = document.querySelectorAll('.modal-image');
// 获取模态框元素
let modal = document.getElementById("imageModal");
// 获取模态框中的图片元素
let modalImg = document.getElementById("img01");
// 获取关闭按钮元素
let span = document.getElementsByClassName("close")[0];
// 为每个图片添加点击事件监听器
images.forEach(function(img) {
img.addEventListener("click", function() {
modal.style.display = "block"; // 显示模态框
modalImg.src = this.src; // 设置模态框中的图片为点击的图片
});
});
// 当点击关闭按钮时,隐藏模态框
span.onclick = function() {
modal.style.display = "none";
};
// 当点击模态框外区域时,隐藏模态框
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
});
function toggle_folder_all_cases(){
let eles = document.querySelectorAll(".folder_body");
FOLDER_ALL_CASES = !FOLDER_ALL_CASES;
document.getElementById('display_mode').innerHTML = FOLDER_ALL_CASES ? "Detail" : "Summary";
for (const ele of eles){
ele.style.display = FOLDER_ALL_CASES ? "none" : "block";
}
}
function previous_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx -= 1;
if (current_error_idx < 0)
current_error_idx = 0;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
function next_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx += 1;
if (current_error_idx > ERROR_INFOS.length - 1)
current_error_idx = ERROR_INFOS.length - 1;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
</script>
</head>
<body>
<div class="modal" id="imageModal">
<div>
<img class="modal-content" id="img01">
<span class="close">关闭</span>
</div>
</div>
<div class="main_section">
<h1 style="font-family: auto">会议预约测试报告</h1>
<h3>统计结果</h3>
<div class="result">
<table class="result_table">
<tbody>
<tr>
<td>hytest 版本</td>
<td>0.8.12</td>
</tr>
<tr>
<td>开始时间</td>
<td>2025/03/21 17:20:06</td>
</tr>
<tr>
<td>结束时间</td>
<td>2025/03/21 17:20:28</td>
</tr>
<tr>
<td>耗时</td>
<td>22.699 秒</td>
</tr>
<tr>
<td>预备执行用例数量</td>
<td>1</td>
</tr>
<tr>
<td>实际执用例行数量</td>
<td>1</td>
</tr>
<tr>
<td>通过</td>
<td>1</td>
</tr>
<tr>
<td>失败</td>
<td style="">0</td>
</tr>
<tr>
<td>异常</td>
<td style="">0</td>
</tr>
<tr>
<td>阻塞</td>
<td style="">0</td>
</tr>
<tr>
<td>套件初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>套件清除 失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例清除 失败</td>
<td style="">0</td>
</tr>
</tbody>
</table>
<div class="result_barchart">
<div class="barchar_item">
<span>用例通过 100% : 1 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 100.0%; background-color: #04AA6D;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例失败 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #bb4069;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例异常 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #9c27b0;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例阻塞 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #dcbdbd;"></div>
</div>
</div>
</div>
</div>
<div style="margin-top:2em">
<h3 style="display:inline">执行日志</h3>
</div>
<div class="exec_log">
<div class="suite_dir" id="suite_dir cases\主流程功能\">
<div>
<span class="label">进入目录</span>
<span>cases\主流程功能\</span>
</div>
<div class="suite_setup setup" id="suite_setup setup cases\主流程功能\">
<div class="folder_header">
<span class="label">套件初始化</span>
<span>cases\主流程功能\</span>
<span class="executetime">2025-03-21 17:20:06</span>
</div>
<div class="folder_body">
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>初始化浏览器</span>
</div>
<div class="info">'----------' 正在初始化浏览器 '----------'</div>
<div class="info">'----------' 浏览器初始化完成 '----------'</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>登录系统</span>
</div>
</div>
</div>
</div>
<div class="suite_file" id="suite_file cases\主流程功能\04调试创建会议.py">
<div>
<span class="label">进入文件</span>
<span>cases\主流程功能\04调试创建会议.py</span>
</div>
<div class="case pass" id="case_00000001">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">Unified_Platform_0001</span>
<span class="executetime">2025-03-21 17:20:14</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\主流程功能\04调试创建会议.py::Unified_Platform_0001</span>
<div class="test_steps" id="test_steps Unified_Platform_0001">
<span class="label">测试步骤</span>
</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\主流程功能\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\主流程功能\</span>
<span class="executetime">2025-03-21 17:20:26</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
</div>
</div>
</div>
<div id="float_menu">
<div class="menu-item" onclick="document.querySelector(&quot;body&quot;).scrollIntoView()">页首</div>
<div class="menu-item" onclick="window.open(&quot;http://www.byhy.net/tut/auto/hytest/01&quot;, &quot;_blank&quot;); ">帮助</div>
<div class="menu-item" id="display_mode" onclick="toggle_folder_all_cases()">Summary</div>
<div class="error_jumper" display="none">
<div class="menu-item" onclick="previous_error()" title="上一个错误"></div>
<div class="menu-item" onclick="next_error()" title="下一个错误"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>会议预约测试报告</title>
<meta charset="UTF-8">
<style>body {
font-family: consolas, Verdana, sans-serif;
font-size: 1.2em;
color: #696e71;
display: grid;
grid-template-columns: 1fr 5rem;
}
.main_section {
width: 90%;
margin: 0 auto;
}
#float_menu{
position:fixed;
top:0;
right:0;
text-align: center;
}
#float_menu .menu-item {
cursor: pointer;
padding: .5em;
margin: .5em 0;
color: #c08580;
background-color: #f8f0ef;
font-size: 1.2em;
}
.result{
display: flex;
}
.result_table{
border-collapse: collapse;
border: 1px solid #f0e0e5;
width: 30em;
text-align: center;
font-size: 1.0em;
}
.result_table td{
border: 1px solid #f0e0e5;
padding: .3em;
}
.result_barchart{
width: 30em;
margin: 0 5em 0 5em;
}
.barchar_item{
margin: 2.5rem 0;
}
.barchart_barbox {
margin: 0.5em 0;
width: 100%;
background-color: #fff;
border: 1px solid #86c2dd;
border-radius: .2em;
}
.barchart_bar {
text-align: right;
height: 1.2rem;
}
.h3_button {
margin: 1.5em;
cursor: pointer;
color: #03a9f4;
}
.info
{
white-space:pre-wrap;
margin: .8em 1.5em;
}
.error-info
{
color: #a64747
}
.suite_dir {
margin: 1em .2em;
padding: .3em;
/* background-color: #dfeff6; */
border: 1px solid #bcd8e4;
}
.suite_file {
margin: 1em .2em;
padding: .3em;
border: 1px solid #bcd8e4;
}
.case {
margin: 1em .2em;
/* padding: .3em; */
border: 1px solid #e7d4d4;
}
.case_class_path{
margin: 0em 1em;
}
.folder_header {
padding: .2em .7em;
background-color: #fffaf9;
cursor: pointer;
}
.setup{
margin: .2em;
/* padding: .3em; */
/* border: 1px solid #e7d4d4; */
}
.teardown{
margin: .2em;
/* padding: .3em;*/
/* border: 1px solid #e7d4d4; */
}
.test_steps{
margin: .2em;
padding: .3em;
/* border: 1px solid #e7d4d4; */
}
.label {
display: inline-block;
padding: .1em .5em;
font-size: .88em;
letter-spacing: 1px;
white-space: nowrap;
color: #0d6ebc;
border-radius: .2em;
min-width: 5em;
margin-right: 2em;
font-family: consolas;
}
/* .suite_setup .label{
color: #219e26 ;
}
.suite_teardown .label{
color: #219e26;
} */
/* .case.pass .casename{
color: #329132 ;
} */
.case.pass .caselabel{
color: white;
background-color: #3b9e3f;
}
/* .case.fail .casename{
color: #a64747;
} */
.case.fail .caselabel{
color: white;
background-color: #a64747;
}
/* .case.abort .casename{
color: #953ab7;
} */
.case.abort .caselabel{
color: white;
background-color: #9c27b0;
}
.case_step {
margin: .8em;
}
.checkpoint_pass {
margin: .8em;
}
.checkpoint_fail {
margin: .8em;
}
.case_step .tag{
color: #2196f3;;
margin: .3em 1em .3em 0;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_pass .tag{
color: #009806;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_fail .tag{
color: #9c2020;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.screenshot {
border: 1px solid #86c2dd;
}
.executetime {
float: right;
}
/* 模态框内容 */
.modal-content {
margin: auto;
display: block;
width: 95%;
max-width: 700px;
max-height: 80vh; /* 设置最大高度为视口高度的80% */
object-fit: contain; /* 保持图片的宽高比 */
zoom: 3;
}
/* 模态框 */
.modal {
display: none; /* 隐藏 */
position: fixed; /* 固定位置 */
z-index: 1; /* 坐在顶部 */
padding-top: 40px; /* 在图片上方添加一些内边距 */
left: 0;
top: 0;
width: 100%; /* 宽度 */
height: 100%; /* 高度 */
overflow: auto; /* 启用滚动 */
background-color: rgb(0,0,0); /* 背景颜色 */
background-color: rgba(0,0,0,0.9); /* 黑色背景半透明 */
}
/* 关闭按钮 */
.close {
position: absolute; /* 定义元素的定位方式为绝对定位 */
top: 10px; /* 距离最近的已定位祖先元素顶部15像素 */
right: 30px; /* 距离最近的已定位祖先元素右侧35像素 */
color: #f1f1f1; /* 文本颜色为浅灰色 */
font-size: 15px; /* 字体大小为40像素 */
font-weight: bold; /* 字体加粗 */
transition: 0.3s; /* 过渡效果,0.3秒内完成 */
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
</style>
<script type="text/javascript">var FOLDER_ALL_CASES = false; // 是否为精简模式的标记
var ERROR_INFOS = []; // 错误信息列表
var current_error_idx = -1;
// 页面加载后执行的函数
window.addEventListener("load", function(){
// 所有 .folder_header 添加点击事件处理
let folderHeaderEles = document.querySelectorAll(".folder_header");
folderHeaderEles.forEach(function(ele) {
ele.addEventListener("click", function(event) {
let fb = event.target.closest('.folder_header').nextElementSibling;
fb.style.display = fb.style.display === 'none' ? 'block' : 'none';
});
});
// 找到所有的错误信息对象
ERROR_INFOS = document.querySelectorAll(".error-info");
// 获取所有图片元素
let images = document.querySelectorAll('.modal-image');
// 获取模态框元素
let modal = document.getElementById("imageModal");
// 获取模态框中的图片元素
let modalImg = document.getElementById("img01");
// 获取关闭按钮元素
let span = document.getElementsByClassName("close")[0];
// 为每个图片添加点击事件监听器
images.forEach(function(img) {
img.addEventListener("click", function() {
modal.style.display = "block"; // 显示模态框
modalImg.src = this.src; // 设置模态框中的图片为点击的图片
});
});
// 当点击关闭按钮时,隐藏模态框
span.onclick = function() {
modal.style.display = "none";
};
// 当点击模态框外区域时,隐藏模态框
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
});
function toggle_folder_all_cases(){
let eles = document.querySelectorAll(".folder_body");
FOLDER_ALL_CASES = !FOLDER_ALL_CASES;
document.getElementById('display_mode').innerHTML = FOLDER_ALL_CASES ? "Detail" : "Summary";
for (const ele of eles){
ele.style.display = FOLDER_ALL_CASES ? "none" : "block";
}
}
function previous_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx -= 1;
if (current_error_idx < 0)
current_error_idx = 0;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
function next_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx += 1;
if (current_error_idx > ERROR_INFOS.length - 1)
current_error_idx = ERROR_INFOS.length - 1;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
</script>
</head>
<body>
<div class="modal" id="imageModal">
<div>
<img class="modal-content" id="img01">
<span class="close">关闭</span>
</div>
</div>
<div class="main_section">
<h1 style="font-family: auto">会议预约测试报告</h1>
<h3>统计结果</h3>
<div class="result">
<table class="result_table">
<tbody>
<tr>
<td>hytest 版本</td>
<td>0.8.12</td>
</tr>
<tr>
<td>开始时间</td>
<td>2025/03/21 17:23:09</td>
</tr>
<tr>
<td>结束时间</td>
<td>2025/03/21 17:23:28</td>
</tr>
<tr>
<td>耗时</td>
<td>19.511 秒</td>
</tr>
<tr>
<td>预备执行用例数量</td>
<td>1</td>
</tr>
<tr>
<td>实际执用例行数量</td>
<td>1</td>
</tr>
<tr>
<td>通过</td>
<td>0</td>
</tr>
<tr>
<td>失败</td>
<td style="">0</td>
</tr>
<tr>
<td>异常</td>
<td style="color:red">1</td>
</tr>
<tr>
<td>阻塞</td>
<td style="">0</td>
</tr>
<tr>
<td>套件初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>套件清除 失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例清除 失败</td>
<td style="">0</td>
</tr>
</tbody>
</table>
<div class="result_barchart">
<div class="barchar_item">
<span>用例通过 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #04AA6D;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例失败 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #bb4069;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例异常 100% : 1 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 100.0%; background-color: #9c27b0;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例阻塞 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #dcbdbd;"></div>
</div>
</div>
</div>
</div>
<div style="margin-top:2em">
<h3 style="display:inline">执行日志</h3>
</div>
<div class="exec_log">
<div class="suite_dir" id="suite_dir cases\主流程功能\">
<div>
<span class="label">进入目录</span>
<span>cases\主流程功能\</span>
</div>
<div class="suite_setup setup" id="suite_setup setup cases\主流程功能\">
<div class="folder_header">
<span class="label">套件初始化</span>
<span>cases\主流程功能\</span>
<span class="executetime">2025-03-21 17:23:09</span>
</div>
<div class="folder_body">
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>初始化浏览器</span>
</div>
<div class="info">'----------' 正在初始化浏览器 '----------'</div>
<div class="info">'----------' 浏览器初始化完成 '----------'</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>登录系统</span>
</div>
</div>
</div>
</div>
<div class="suite_file" id="suite_file cases\主流程功能\04调试创建会议.py">
<div>
<span class="label">进入文件</span>
<span>cases\主流程功能\04调试创建会议.py</span>
</div>
<div class="case abort" id="case_00000001">
<div class="folder_header">
<span class="label caselabel">用例 ABORT</span>
<span class="casename">Unified_Platform_0001</span>
<span class="executetime">2025-03-21 17:23:20</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\主流程功能\04调试创建会议.py::Unified_Platform_0001</span>
<div class="test_steps" id="test_steps Unified_Platform_0001">
<span class="label">测试步骤</span>
<div class="info error-info">Message: no such window: target window already closed
from unknown error: web view not found
(Session info: chrome=131.0.6778.264)
Stacktrace:
GetHandleVerifier [0x010AFD53+23747]
(No symbol) [0x01037D54]
(No symbol) [0x00F0BE53]
(No symbol) [0x00EED91B]
(No symbol) [0x00F77EFF]
(No symbol) [0x00F8AD49]
(No symbol) [0x00F71B96]
(No symbol) [0x00F43F3C]
(No symbol) [0x00F44EBD]
GetHandleVerifier [0x0138AC73+3017699]
GetHandleVerifier [0x0139B93B+3086507]
GetHandleVerifier [0x013940F2+3055714]
GetHandleVerifier [0x01145AF0+637536]
(No symbol) [0x01040A5D]
(No symbol) [0x0103DA28]
(No symbol) [0x0103DBC5]
(No symbol) [0x010307F0]
BaseThreadInitThunk [0x765E7BA9+25]
RtlInitializeExceptionChain [0x77B6C28B+107]
RtlClearBits [0x77B6C20F+191]
Traceback:
File &quot;D:\GithubData\自动化\ubains-module-test\统一平台\cases\主流程功能\04调试创建会议.py&quot;, line 27, in teststeps
safe_click((By.XPATH, &quot;//p[contains(text(),'新建会议')]&quot;), wd)
File &quot;D:\GithubData\自动化\ubains-module-test\统一平台\base\bases.py&quot;, line 239, in safe_click
element = WebDriverWait(wd, 5).until(EC.visibility_of_element_located(element_locator))
File &quot;C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\support\wait.py&quot;, line 96, in until
value = method(self._driver)
File &quot;C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\support\expected_conditions.py&quot;, line 156, in _predicate
return _element_if_visible(driver.find_element(*locator))
File &quot;C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py&quot;, line 770, in find_element
return self.execute(Command.FIND_ELEMENT, {&quot;using&quot;: by, &quot;value&quot;: value})[&quot;value&quot;]
File &quot;C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py&quot;, line 384, in execute
self.error_handler.check_response(response)
File &quot;C:\Users\29194\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py&quot;, line 232, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchWindowException: Message: no such window: target window already closed
from unknown error: web view not found
(Session info: chrome=131.0.6778.264)
Stacktrace:
GetHandleVerifier [0x010AFD53+23747]
(No symbol) [0x01037D54]
(No symbol) [0x00F0BE53]
(No symbol) [0x00EED91B]
(No symbol) [0x00F77EFF]
(No symbol) [0x00F8AD49]
(No symbol) [0x00F71B96]
(No symbol) [0x00F43F3C]
(No symbol) [0x00F44EBD]
GetHandleVerifier [0x0138AC73+3017699]
GetHandleVerifier [0x0139B93B+3086507]
GetHandleVerifier [0x013940F2+3055714]
GetHandleVerifier [0x01145AF0+637536]
(No symbol) [0x01040A5D]
(No symbol) [0x0103DA28]
(No symbol) [0x0103DBC5]
(No symbol) [0x010307F0]
BaseThreadInitThunk [0x765E7BA9+25]
RtlInitializeExceptionChain [0x77B6C28B+107]
RtlClearBits [0x77B6C20F+191]
</div>
</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\主流程功能\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\主流程功能\</span>
<span class="executetime">2025-03-21 17:23:26</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
</div>
</div>
</div>
<div id="float_menu">
<div class="menu-item" onclick="document.querySelector(&quot;body&quot;).scrollIntoView()">页首</div>
<div class="menu-item" onclick="window.open(&quot;http://www.byhy.net/tut/auto/hytest/01&quot;, &quot;_blank&quot;); ">帮助</div>
<div class="menu-item" id="display_mode" onclick="toggle_folder_all_cases()">Summary</div>
<div class="error_jumper" display="block">
<div class="menu-item" onclick="previous_error()" title="上一个错误"></div>
<div class="menu-item" onclick="next_error()" title="下一个错误"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
......@@ -224,4 +224,4 @@
最后将/home/bakup目录压缩成tar.gz格式文件并导出,文件命名补充时间戳,导出完成后清理/home目录下的这个备份文件。
##### 服务自检报告输出(✅ 已实现):
将服务自检的所有操作步骤与结果输出到日志文件中!
\ No newline at end of file
将服务自检的所有操作步骤与结果输出到日志文件中!自检报告需要补充成md格式!
\ No newline at end of file
......@@ -1520,13 +1520,41 @@ function Show-HealthReport {
[hashtable]$NTPResults,
[hashtable]$FilePermResults
)
# Markdown 报告初始化(健壮性与回退)
if (-not $SCRIPT_DIR -or [string]::IsNullOrWhiteSpace($SCRIPT_DIR)) {
$SCRIPT_DIR = (Get-Location).Path
}
$reportDir = Join-Path $SCRIPT_DIR "Reports"
try {
if (-not (Test-Path $reportDir)) { New-Item -ItemType Directory -Path $reportDir -Force | Out-Null }
} catch {
$reportDir = Join-Path $env:TEMP "ubains_reports"
if (-not (Test-Path $reportDir)) { New-Item -ItemType Directory -Path $reportDir -Force | Out-Null }
}
$ts = Get-Date -Format "yyyyMMdd_HHmmss"
$safeIp = if ($Server -and $Server.IP) { ($Server.IP -replace '[^\w\.\-]', '_') } else { 'unknown' }
$mdFile = Join-Path $reportDir "health_report_${safeIp}_${ts}.md"
if (-not $mdFile -or [string]::IsNullOrWhiteSpace($mdFile)) {
$mdFile = Join-Path $reportDir ("health_report_" + $ts + ".md")
}
$md = @()
$md += "# 服务自检报告"
$md += ""
$md += "- 服务器地址: $($Server.IP)"
$md += "- 服务器描述: $($Server.Desc)"
$md += "- 平台类型: $(if ($PlatformType -eq 'new') { '新统一平台' } else { '传统平台' })"
$md += "- 检测时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
$md += ""
# 控制台抬头
Write-Host ""
Write-Host "==================================================================" -ForegroundColor Cyan
Write-Host " 服务自检报告" -ForegroundColor Cyan
Write-Host "==================================================================" -ForegroundColor Cyan
Write-Host ""
# 基本信息
Write-Host "【基本信息】" -ForegroundColor Yellow
Write-Host " 服务器地址: $($Server.IP)"
......@@ -1534,220 +1562,254 @@ function Show-HealthReport {
Write-Host " 平台类型: $(if ($PlatformType -eq 'new') { '新统一平台' } else { '传统平台' })"
Write-Host " 检测时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Write-Host ""
# 系统类型
Write-Host "【系统类型识别】" -ForegroundColor Yellow
if ($SystemInfo.HasUjava) {
Write-Host " 会议预定系统 (ujava): 已部署 [$($SystemInfo.UjavaContainer)]" -ForegroundColor Green
}
if ($SystemInfo.HasUpython) {
Write-Host " 运维集控系统 (upython): 已部署 [$($SystemInfo.UpythonContainer)]" -ForegroundColor Green
}
if ($SystemInfo.HasUpythonVoice) {
Write-Host " 转录系统 (upython_voice): 已部署 [$($SystemInfo.UpythonVoiceContainer)]" -ForegroundColor Green
}
if (-not $SystemInfo.HasUjava -and -not $SystemInfo.HasUpython -and -not $SystemInfo.HasUpythonVoice) {
Write-Host " 未检测到已知系统容器" -ForegroundColor Yellow
}
Write-Host ""
# 系统类型识别
$md += "## 系统类型识别"
if ($SystemInfo.HasUjava) { $md += "- 会议预定系统 (ujava): 已部署 [$($SystemInfo.UjavaContainer)]" }
if ($SystemInfo.HasUpython) { $md += "- 运维集控系统 (upython): 已部署 [$($SystemInfo.UpythonContainer)]" }
if ($SystemInfo.HasUpythonVoice) { $md += "- 转录系统 (upython_voice): 已部署 [$($SystemInfo.UpythonVoiceContainer)]" }
if (-not $SystemInfo.HasUjava -and -not $SystemInfo.HasUpython -and -not $SystemInfo.HasUpythonVoice) { $md += "- 未检测到已知系统容器" }
$md += ""
# 统计信息
$totalServices = 0
$runningServices = 0
$failedServices = 0
# ujava 容器服务统计
# ujava 容器内服务
if ($UjavaContainerResults -and $UjavaContainerResults.Count -gt 0) {
Write-Host "【ujava 容器内服务状态】" -ForegroundColor Yellow
$md += "## ujava 容器内服务状态"
foreach ($r in $UjavaContainerResults) {
$totalServices++
if ($r.Running) {
$runningServices++
Write-Host " [OK] $($r.Service): $($r.Status)" -ForegroundColor Green
}
else {
} else {
$failedServices++
Write-Host " [FAIL] $($r.Service): $($r.Status)" -ForegroundColor Red
}
$md += "- $($r.Service) ($($r.Pattern)): $($r.Status)"
}
$md += ""
Write-Host ""
}
# ujava 宿主机服务统计
# ujava 宿主机服务
if ($UjavaHostResults -and $UjavaHostResults.Count -gt 0) {
Write-Host "【ujava 宿主机服务状态】" -ForegroundColor Yellow
$md += "## ujava 宿主机服务状态"
foreach ($r in $UjavaHostResults) {
$totalServices++
if ($r.Running) {
$runningServices++
Write-Host " [OK] $($r.Service): $($r.Status)" -ForegroundColor Green
}
else {
} else {
$failedServices++
Write-Host " [FAIL] $($r.Service): $($r.Status)" -ForegroundColor Red
}
$md += "- $($r.Service) ($($r.Pattern)): $($r.Status)"
}
$md += ""
Write-Host ""
}
# upython 服务统计
if ($UpythonResults -and $UpythonResults.Count -gt
0) {
# upython 容器服务
if ($UpythonResults -and $UpythonResults.Count -gt 0) {
Write-Host "【upython 容器服务状态】" -ForegroundColor Yellow
$md += "## upython 容器服务状态"
foreach ($r in $UpythonResults) {
$totalServices++
if ($r.Listening) {
$runningServices++
Write-Host " [OK] 端口 $($r.Port) ($($r.Description)): $($r.Status)" -ForegroundColor Green
}
else {
} else {
$failedServices++
Write-Host " [FAIL] 端口 $($r.Port) ($($r.Description)): $($r.Status)" -ForegroundColor Red
}
$md += "- 端口 $($r.Port) ($($r.Description)): $($r.Status)"
}
$md += ""
Write-Host ""
}
# upython_voice 服务统计
# upython_voice 容器服务
if ($UpythonVoiceResults -and $UpythonVoiceResults.Count -gt 0) {
Write-Host "【upython_voice 容器服务状态】" -ForegroundColor Yellow
$md += "## upython_voice 容器服务状态"
foreach ($r in $UpythonVoiceResults) {
$totalServices++
if ($r.Listening) {
$runningServices++
Write-Host " [OK] 端口 $($r.Port) ($($r.Description)): $($r.Status)" -ForegroundColor Green
}
else {
} else {
$failedServices++
Write-Host " [FAIL] 端口 $($r.Port) ($($r.Description)): $($r.Status)" -ForegroundColor Red
}
$md += "- 端口 $($r.Port) ($($r.Description)): $($r.Status)"
}
$md += ""
Write-Host ""
}
# DNS 检测结果统计
# DNS 检测
if ($DNSResults -and $DNSResults.Count -gt 0) {
Write-Host "【DNS 解析检测结果】" -ForegroundColor Yellow
$md += "## DNS 解析检测结果"
foreach ($r in $DNSResults) {
$statusColor = if ($r.Success) { "Green" } else { "Red" }
$statusIcon = if ($r.Success) { "[OK]" } else { "[FAIL]" }
Write-Host " $statusIcon $($r.Check): $($r.Status)" -ForegroundColor $statusColor
if ($r.Details) {
Write-Host " 详情: $($r.Details)" -ForegroundColor Gray
}
$statusIcon = if ($r.Success) { "OK" } else { "FAIL" }
Write-Host " [$statusIcon] $($r.Check): $($r.Status)"
$line = "- $($r.Check): $($r.Status)"
if ($r.Details) { $line += ",$($r.Details)" }
$md += $line
}
$md += ""
Write-Host ""
}
# 服务器资源分析结果
# 服务器资源
if ($ResourceResults) {
Write-Host "【服务器资源分析】" -ForegroundColor Yellow
# 操作系统信息
$md += "## 服务器资源分析"
if ($ResourceResults.OS) {
Write-Host " 操作系统: $($ResourceResults.OS.Info)" -ForegroundColor Cyan
$md += "- 操作系统: $($ResourceResults.OS.Info)"
}
# 架构信息
if ($ResourceResults.Architecture) {
Write-Host " 系统架构: $($ResourceResults.Architecture.Arch) | 内核: $($ResourceResults.Architecture.Kernel)" -ForegroundColor Cyan
$md += "- 系统架构: $($ResourceResults.Architecture.Arch) | 内核: $($ResourceResults.Architecture.Kernel)"
}
# CPU 使用情况
if ($ResourceResults.CPU) {
$cpuColor = if ($ResourceResults.CPU.Success) { "Green" } else { "Red" }
Write-Host " CPU 使用率: $($ResourceResults.CPU.Usage)% (核心数: $($ResourceResults.CPU.Cores)) [$($ResourceResults.CPU.Status)]" -ForegroundColor $cpuColor
Write-Host " CPU 使用率: $($ResourceResults.CPU.Usage)% (核心数: $($ResourceResults.CPU.Cores)) [$($ResourceResults.CPU.Status)]"
$md += "- CPU 使用率: $($ResourceResults.CPU.Usage)% (核心数: $($ResourceResults.CPU.Cores)) [$($ResourceResults.CPU.Status)]"
}
# 内存使用情况
if ($ResourceResults.Memory) {
$memColor = if ($ResourceResults.Memory.Success) { "Green" } else { "Red" }
Write-Host " 内存使用: $($ResourceResults.Memory.Used)GB / $($ResourceResults.Memory.Total)GB ($($ResourceResults.Memory.Percent)%) [$($ResourceResults.Memory.Status)]" -ForegroundColor $memColor
Write-Host " 内存使用: $($ResourceResults.Memory.Used)GB / $($ResourceResults.Memory.Total)GB ($($ResourceResults.Memory.Percent)%) [$($ResourceResults.Memory.Status)]"
$md += "- 内存使用: $($ResourceResults.Memory.Used)GB / $($ResourceResults.Memory.Total)GB ($($ResourceResults.Memory.Percent)%) [$($ResourceResults.Memory.Status)]"
}
# 磁盘使用情况
if ($ResourceResults.Disk -and $ResourceResults.Disk.Count -gt 0) {
Write-Host " 磁盘使用情况:" -ForegroundColor Cyan
Write-Host " 磁盘使用情况:"
$md += "- 磁盘使用:"
foreach ($disk in $ResourceResults.Disk) {
$diskColor = if ($disk.Percent -lt 70) { "Green" } elseif ($disk.Percent -lt 90) { "Yellow" } else { "Red" }
Write-Host " $($disk.MountPoint): $($disk.Used)/$($disk.Size) ($($disk.Percent)%) [$($disk.Status)]" -ForegroundColor $diskColor
Write-Host " $($disk.MountPoint): $($disk.Used)/$($disk.Size) ($($disk.Percent)%) [$($disk.Status)]"
$md += " - $($disk.MountPoint): $($disk.Used)/$($disk.Size) ($($disk.Percent)%) [$($disk.Status)]"
}
}
# 防火墙状态
if ($ResourceResults.Firewall) {
$fwColor = if ($ResourceResults.Firewall.Active) { "Green" } else { "Yellow" }
Write-Host " 防火墙状态: $($ResourceResults.Firewall.Status) ($($ResourceResults.Firewall.Type))" -ForegroundColor $fwColor
Write-Host " 防火墙状态: $($ResourceResults.Firewall.Status) ($($ResourceResults.Firewall.Type))"
$md += "- 防火墙状态: $($ResourceResults.Firewall.Status) ($($ResourceResults.Firewall.Type))"
if ($ResourceResults.Firewall.OpenPorts -and $ResourceResults.Firewall.Active) {
Write-Host " 开放端口/服务: $($ResourceResults.Firewall.OpenPorts)" -ForegroundColor Gray
Write-Host " 开放端口/服务: $($ResourceResults.Firewall.OpenPorts)"
$md += " - 开放端口/服务: $($ResourceResults.Firewall.OpenPorts)"
}
}
$md += ""
Write-Host ""
}
# 服务器NTP服务分析结果
# NTP 服务
Write-Host "【NTP 服务检测】" -ForegroundColor Yellow
if ($NTPResults) { Write-Host " $($NTPResults.Status): $($NTPResults.Detail)" } else { Write-Host " 未执行" -ForegroundColor Yellow }
$md += "## NTP 服务检测"
if ($NTPResults) {
Write-Host " $($NTPResults.Status): $($NTPResults.Detail)"
$md += "- 状态: $($NTPResults.Status)"
if ($NTPResults.Detail) { $md += "- 详情: $($NTPResults.Detail)" }
} else {
Write-Host " 未执行" -ForegroundColor Yellow
$md += "- 未执行"
}
$md += ""
Write-Host ""
# 配置文件权限检测
# 文件权限
Write-Host "【文件权限检测】" -ForegroundColor Yellow
if ($FilePermResults) { Write-Host " $($FilePermResults.Summary)" } else { Write-Host " 未执行" -ForegroundColor Yellow }
Write-Host ""
$md += "## 文件权限检测"
if ($FilePermResults) {
Write-Host " $($FilePermResults.Summary)"
$md += "- 总结: $($FilePermResults.Summary)"
if ($FilePermResults.Lines) {
$md += "- 明细:"
foreach ($l in $FilePermResults.Lines) { $md += " - $l" }
}
} else {
Write-Host " 未执行" -ForegroundColor Yellow
$md += "- 未执行"
}
$md += ""
# 总结
Write-Host "==================================================================" -ForegroundColor Cyan
Write-Host "【检测总结】" -ForegroundColor Yellow
Write-Host " 总服务数: $totalServices"
Write-Host " 正常运行: $runningServices" -ForegroundColor Green
Write-Host " 异常服务: $failedServices" -ForegroundColor $(if ($failedServices -gt 0) { "Red" } else { "Green" })
$md += "## 检测总结"
$md += "- 总服务数: $totalServices"
$md += "- 正常运行: $runningServices"
$md += "- 异常服务: $failedServices"
if ($failedServices -eq 0 -and $totalServices -gt 0) {
Write-Host ""
Write-Host " 所有服务运行正常!" -ForegroundColor Green
}
elseif ($failedServices -gt 0) {
$md += "- 结论: 所有服务运行正常!"
} elseif ($failedServices -gt 0) {
Write-Host ""
Write-Host " 存在异常服务,请及时处理!" -ForegroundColor Red
}
elseif ($totalServices -eq 0) {
$md += "- 结论: 存在异常服务,请及时处理!"
} elseif ($totalServices -eq 0) {
Write-Host ""
Write-Host " 未检测到任何服务" -ForegroundColor Yellow
$md += "- 结论: 未检测到任何服务"
}
# 日志导出结果
# 日志导出
if ($LogExportResults) {
Write-Host "【日志导出结果】" -ForegroundColor Yellow
$md += ""
$md += "## 服务日志导出"
if ($LogExportResults.Success -and $LogExportResults.ExportedFiles.Count -gt 0) {
Write-Host " 导出状态: 成功" -ForegroundColor Green
Write-Host " 导出目录: $($LogExportResults.ExportDir)" -ForegroundColor Cyan
Write-Host " 成功导出 $($LogExportResults.ExportedFiles.Count) 个文件:" -ForegroundColor Green
$md += "- 导出状态: 成功"
$md += "- 导出目录: $($LogExportResults.ExportDir)"
$md += "- 成功文件:"
foreach ($file in $LogExportResults.ExportedFiles) {
$sizeKB = [math]::Round($file.Size / 1024, 2)
Write-Host " - $($file.Name) ($sizeKB KB)" -ForegroundColor Gray
$md += " - $($file.Name) ($sizeKB KB)"
}
}
elseif ($LogExportResults.ExportedFiles.Count -eq 0 -and $LogExportResults.FailedFiles.Count -eq 0) {
} elseif ($LogExportResults.ExportedFiles.Count -eq 0 -and $LogExportResults.FailedFiles.Count -eq 0) {
Write-Host " 导出状态: 无需导出的日志文件" -ForegroundColor Yellow
}
else {
$md += "- 导出状态: 无需导出的日志文件"
} else {
Write-Host " 导出状态: 部分失败" -ForegroundColor Yellow
}
if ($LogExportResults.FailedFiles.Count -gt 0) {
Write-Host " 失败 $($LogExportResults.FailedFiles.Count) 个文件:" -ForegroundColor Red
foreach ($file in $LogExportResults.FailedFiles) {
Write-Host " - $($file.Name): $($file.Reason)" -ForegroundColor Gray
$md += "- 导出状态: 部分失败"
if ($LogExportResults.FailedFiles.Count -gt 0) {
$md += "- 失败文件:"
foreach ($file in $LogExportResults.FailedFiles) {
$md += " - $($file.Name): $($file.Reason)"
}
}
}
Write-Host ""
}
Write-Host "==================================================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "日志文件: $LOG_FILE"
Write-Host ""
# 写入 Markdown 文件(带异常处理)
try {
$content = ($md -join "`r`n")
$content | Out-File -FilePath $mdFile -Encoding utf8
Write-Log -Level "SUCCESS" -Message "Markdown 报告已生成: $mdFile"
} catch {
Write-Log -Level "ERROR" -Message "Markdown 写入失败: $($_.Exception.Message)"
Write-Log -Level "ERROR" -Message "报告目录: $reportDir"
Write-Log -Level "ERROR" -Message "文件路径: $mdFile"
}
}
# ================================
......@@ -1899,7 +1961,6 @@ function Check-NTPService {
Write-Host "开始检测目标服务器的NTP服务..." -ForegroundColor Yellow
# 检测是否安装了 NTP 或 Chrony 服务
Write-Log -Level "INFO" -Message "[NTP] 检测服务是否安装 (ntp/chronyd)"
$Command = "systemctl list-units --type=service | grep -E 'ntp|chronyd'"
$Result = Invoke-SSHCommand -HostName $ServerIP -User $Username -Pass $Password -Command $Command
......@@ -1914,17 +1975,34 @@ function Check-NTPService {
$ServerTimeResult = Invoke-SSHCommand -HostName $ServerIP -User $Username -Pass $Password -Command $TimeCommand
Write-Log -Level "INFO" -Message "[NTP] 服务器时间戳: $([string]::Join(' ', $ServerTimeResult.Output))"
if ($ServerTimeResult.ExitCode -eq 0) {
$ServerTimeUTC = [int]$ServerTimeResult.Output.Trim(); $ServerTime = $ServerTimeUTC + (8 * 3600)
$LocalTime = [int](Get-Date -UFormat %s); $TimeDifference = [math]::Abs($ServerTime - $LocalTime)
$ServerTimeUTC = [int]($ServerTimeResult.Output | Select-Object -First 1).Trim()
# 不再手动加8小时,直接比较时间戳
$LocalTime = [int](Get-Date -UFormat %s)
$TimeDifference = [math]::Abs($ServerTimeUTC - $LocalTime)
Write-Log -Level "INFO" -Message "[NTP] 本地时间戳: $LocalTime, 差值: $TimeDifference 秒"
if ($TimeDifference -le 5) { Write-Log -Level "SUCCESS" -Message "[NTP] 服务器时间与北京时间一致" }
else { Write-Log -Level "WARN" -Message "[NTP] 时间偏差 ${TimeDifference} 秒" }
} else { Write-Log -Level "ERROR" -Message "[NTP] 获取服务器时间失败" }
} else { Write-Log -Level "ERROR" -Message "[NTP] timedatectl 不可用" }
if ($TimeDifference -le 5) {
Write-Log -Level "SUCCESS" -Message "[NTP] 服务器时间与本地时间一致"
$summary.Status = '正常'
$summary.Detail = "时间差 ${TimeDifference}s"
} else {
Write-Log -Level "WARN" -Message "[NTP] 时间偏差 ${TimeDifference} 秒"
$summary.Status = '偏差'
$summary.Detail = "时间差 ${TimeDifference}s"
}
} else {
Write-Log -Level "ERROR" -Message "[NTP] 获取服务器时间失败"
$summary.Status = '异常'; $summary.Detail = '获取服务器时间失败'
}
} else {
Write-Log -Level "ERROR" -Message "[NTP] timedatectl 不可用"
$summary.Status = '异常'; $summary.Detail = 'timedatectl 不可用'
}
} else {
Write-Log -Level "WARN" -Message "[NTP] 未检测到 NTP/Chrony 服务"
$summary.Status = '未安装'; $summary.Detail = '未检测到 ntp/chronyd'
}
Write-Log -Level "INFO" -Message "[NTP] 检测结束"
return $summary
}
# ================================
......@@ -1956,13 +2034,11 @@ function Check-FilePermissions {
"/data/third_party/paperless/run.sh",
"/data/third_party/paperless/start.sh",
"/data/third_party/wifi-local/config.ini",
"/data/third_party/wifi-local/startDB.sh",
"/data/第三方/wifi-local/startDB.sh",
"/data/third_party/wifi-local/wifi*",
"/etc/rc.d/rc.local",
"/data/middleware/nginx/config/*.conf",
"/data/middleware/emqx/config/*.conf"
)
$targets += @(
"/data/middleware/emqx/config/*.conf",
"/data/services/api/python-cmdb/*.sh",
"/data/services/api/python-voice/*.sh"
)
......@@ -1991,7 +2067,7 @@ function Check-FilePermissions {
$cmd = "if ls -l $path 2>/dev/null; then echo '__PERM_OK__'; else echo '__PERM_MISS__ $path'; fi"
Write-Log -Level "INFO" -Message "[PERM] 执行: $cmd"
$res = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $cmd
$out = ($res.Output -join " ")
$out = if ($res.Output) { ($res.Output -join " ") } else { "" }
Write-Log -Level "INFO" -Message "[PERM] 输出: $out"
if ($out -match "__PERM_OK__") {
($res.Output) | Where-Object { $_ -match "^[-dl]" } | ForEach-Object {
......@@ -2000,6 +2076,9 @@ function Check-FilePermissions {
} else { Write-Log -Level 'ERROR' -Message "[PERM] 未找到: $path"; $lines += "MISS $path" }
}
Write-Log -Level "INFO" -Message "[PERM] 检测结束: 共 $($lines.Count) 项"
$summaryText = if ($lines.Count -gt 0) { "已检查 $($lines.Count) 项" } else { "未找到任何匹配项" }
return @{ Summary = $summaryText; Lines = $lines }
}
# ================================
......
<!DOCTYPE html>
<html>
<head>
<title>兰州中石化项目测试报告</title>
<meta charset="UTF-8">
<style>body {
font-family: consolas, Verdana, sans-serif;
font-size: 1.2em;
color: #696e71;
display: grid;
grid-template-columns: 1fr 5rem;
}
.main_section {
width: 90%;
margin: 0 auto;
}
#float_menu{
position:fixed;
top:0;
right:0;
text-align: center;
}
#float_menu .menu-item {
cursor: pointer;
padding: .5em;
margin: .5em 0;
color: #c08580;
background-color: #f8f0ef;
font-size: 1.2em;
}
.result{
display: flex;
}
.result_table{
border-collapse: collapse;
border: 1px solid #f0e0e5;
width: 30em;
text-align: center;
font-size: 1.0em;
}
.result_table td{
border: 1px solid #f0e0e5;
padding: .3em;
}
.result_barchart{
width: 30em;
margin: 0 5em 0 5em;
}
.barchar_item{
margin: 2.5rem 0;
}
.barchart_barbox {
margin: 0.5em 0;
width: 100%;
background-color: #fff;
border: 1px solid #86c2dd;
border-radius: .2em;
}
.barchart_bar {
text-align: right;
height: 1.2rem;
}
.h3_button {
margin: 1.5em;
cursor: pointer;
color: #03a9f4;
}
.info
{
white-space:pre-wrap;
margin: .8em 1.5em;
}
.error-info
{
color: #a64747
}
.suite_dir {
margin: 1em .2em;
padding: .3em;
/* background-color: #dfeff6; */
border: 1px solid #bcd8e4;
}
.suite_file {
margin: 1em .2em;
padding: .3em;
border: 1px solid #bcd8e4;
}
.case {
margin: 1em .2em;
/* padding: .3em; */
border: 1px solid #e7d4d4;
}
.case_class_path{
margin: 0em 1em;
}
.folder_header {
padding: .2em .7em;
background-color: #fffaf9;
cursor: pointer;
}
.setup{
margin: .2em;
/* padding: .3em; */
/* border: 1px solid #e7d4d4; */
}
.teardown{
margin: .2em;
/* padding: .3em;*/
/* border: 1px solid #e7d4d4; */
}
.test_steps{
margin: .2em;
padding: .3em;
/* border: 1px solid #e7d4d4; */
}
.label {
display: inline-block;
padding: .1em .5em;
font-size: .88em;
letter-spacing: 1px;
white-space: nowrap;
color: #0d6ebc;
border-radius: .2em;
min-width: 5em;
margin-right: 2em;
font-family: consolas;
}
/* .suite_setup .label{
color: #219e26 ;
}
.suite_teardown .label{
color: #219e26;
} */
/* .case.pass .casename{
color: #329132 ;
} */
.case.pass .caselabel{
color: white;
background-color: #3b9e3f;
}
/* .case.fail .casename{
color: #a64747;
} */
.case.fail .caselabel{
color: white;
background-color: #a64747;
}
/* .case.abort .casename{
color: #953ab7;
} */
.case.abort .caselabel{
color: white;
background-color: #9c27b0;
}
.case_step {
margin: .8em;
}
.checkpoint_pass {
margin: .8em;
}
.checkpoint_fail {
margin: .8em;
}
.case_step .tag{
color: #2196f3;;
margin: .3em 1em .3em 0;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_pass .tag{
color: #009806;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_fail .tag{
color: #9c2020;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.screenshot {
border: 1px solid #86c2dd;
}
.executetime {
float: right;
}
/* 模态框内容 */
.modal-content {
margin: auto;
display: block;
width: 95%;
max-width: 700px;
max-height: 80vh; /* 设置最大高度为视口高度的80% */
object-fit: contain; /* 保持图片的宽高比 */
zoom: 3;
}
/* 模态框 */
.modal {
display: none; /* 隐藏 */
position: fixed; /* 固定位置 */
z-index: 1; /* 坐在顶部 */
padding-top: 40px; /* 在图片上方添加一些内边距 */
left: 0;
top: 0;
width: 100%; /* 宽度 */
height: 100%; /* 高度 */
overflow: auto; /* 启用滚动 */
background-color: rgb(0,0,0); /* 背景颜色 */
background-color: rgba(0,0,0,0.9); /* 黑色背景半透明 */
}
/* 关闭按钮 */
.close {
position: absolute; /* 定义元素的定位方式为绝对定位 */
top: 10px; /* 距离最近的已定位祖先元素顶部15像素 */
right: 30px; /* 距离最近的已定位祖先元素右侧35像素 */
color: #f1f1f1; /* 文本颜色为浅灰色 */
font-size: 15px; /* 字体大小为40像素 */
font-weight: bold; /* 字体加粗 */
transition: 0.3s; /* 过渡效果,0.3秒内完成 */
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
</style>
<script type="text/javascript">var FOLDER_ALL_CASES = false; // 是否为精简模式的标记
var ERROR_INFOS = []; // 错误信息列表
var current_error_idx = -1;
// 页面加载后执行的函数
window.addEventListener("load", function(){
// 所有 .folder_header 添加点击事件处理
let folderHeaderEles = document.querySelectorAll(".folder_header");
folderHeaderEles.forEach(function(ele) {
ele.addEventListener("click", function(event) {
let fb = event.target.closest('.folder_header').nextElementSibling;
fb.style.display = fb.style.display === 'none' ? 'block' : 'none';
});
});
// 找到所有的错误信息对象
ERROR_INFOS = document.querySelectorAll(".error-info");
// 获取所有图片元素
let images = document.querySelectorAll('.modal-image');
// 获取模态框元素
let modal = document.getElementById("imageModal");
// 获取模态框中的图片元素
let modalImg = document.getElementById("img01");
// 获取关闭按钮元素
let span = document.getElementsByClassName("close")[0];
// 为每个图片添加点击事件监听器
images.forEach(function(img) {
img.addEventListener("click", function() {
modal.style.display = "block"; // 显示模态框
modalImg.src = this.src; // 设置模态框中的图片为点击的图片
});
});
// 当点击关闭按钮时,隐藏模态框
span.onclick = function() {
modal.style.display = "none";
};
// 当点击模态框外区域时,隐藏模态框
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
});
function toggle_folder_all_cases(){
let eles = document.querySelectorAll(".folder_body");
FOLDER_ALL_CASES = !FOLDER_ALL_CASES;
document.getElementById('display_mode').innerHTML = FOLDER_ALL_CASES ? "Detail" : "Summary";
for (const ele of eles){
ele.style.display = FOLDER_ALL_CASES ? "none" : "block";
}
}
function previous_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx -= 1;
if (current_error_idx < 0)
current_error_idx = 0;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
function next_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx += 1;
if (current_error_idx > ERROR_INFOS.length - 1)
current_error_idx = ERROR_INFOS.length - 1;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
</script>
</head>
<body>
<div class="modal" id="imageModal">
<div>
<img class="modal-content" id="img01">
<span class="close">关闭</span>
</div>
</div>
<div class="main_section">
<h1 style="font-family: auto">兰州中石化项目测试报告</h1>
<h3>统计结果</h3>
<div class="result">
<table class="result_table">
<tbody>
<tr>
<td>hytest 版本</td>
<td>0.8.12</td>
</tr>
<tr>
<td>开始时间</td>
<td>2025/06/25 09:50:03</td>
</tr>
<tr>
<td>结束时间</td>
<td>2025/06/25 09:51:08</td>
</tr>
<tr>
<td>耗时</td>
<td>64.642 秒</td>
</tr>
<tr>
<td>预备执行用例数量</td>
<td>1</td>
</tr>
<tr>
<td>实际执用例行数量</td>
<td>1</td>
</tr>
<tr>
<td>通过</td>
<td>0</td>
</tr>
<tr>
<td>失败</td>
<td style="color:red">1</td>
</tr>
<tr>
<td>异常</td>
<td style="">0</td>
</tr>
<tr>
<td>阻塞</td>
<td style="">0</td>
</tr>
<tr>
<td>套件初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>套件清除 失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例清除 失败</td>
<td style="">0</td>
</tr>
</tbody>
</table>
<div class="result_barchart">
<div class="barchar_item">
<span>用例通过 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #04AA6D;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例失败 100% : 1 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 100.0%; background-color: #bb4069;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例异常 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #9c27b0;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例阻塞 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #dcbdbd;"></div>
</div>
</div>
</div>
</div>
<div style="margin-top:2em">
<h3 style="display:inline">执行日志</h3>
</div>
<div class="exec_log">
<div class="suite_dir" id="suite_dir cases\">
<div>
<span class="label">进入目录</span>
<span>cases\</span>
</div>
</div>
<div class="suite_dir" id="suite_dir cases\项目定制\兰州中石化项目25-05-24\">
<div>
<span class="label">进入目录</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
</div>
<div class="suite_setup setup" id="suite_setup setup cases\项目定制\兰州中石化项目25-05-24\">
<div class="folder_header">
<span class="label">套件初始化</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
<span class="executetime">2025-06-25 09:50:03</span>
</div>
<div class="folder_body">
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>初始化浏览器</span>
</div>
<div class="info">'----------' 正在初始化浏览器 '----------'</div>
<div class="info">'----------' 浏览器初始化完成 '----------'</div>
<div class="info">输入用户名:admin</div>
<div class="info">输入密码:Ubains@4321</div>
<div class="info">输入验证码:csba</div>
<div class="info">点击登录按钮</div>
</div>
</div>
</div>
<div class="suite_file" id="suite_file cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py">
<div>
<span class="label">进入文件</span>
<span>cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py</span>
</div>
<div class="case fail" id="case_00000001">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">会议申报测试015</span>
<span class="executetime">2025-06-25 09:50:10</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py::LanzhouSinopecProject</span>
<div class="test_steps" id="test_steps 会议申报测试015">
<span class="label">测试步骤</span>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //div[@id='CreateMeeting']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095013175010.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: id、元素定位值: create-meeting-name-input、元素类型: input、元素值: 会议申报测试015、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095015534652.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-start-time-datepicker']、元素类型: input、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095017828422.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //button[@class='el-button el-picker-panel__link-btn el-button--default el-button--mini is-plain']//span[contains(text(),'确定')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095020096921.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-location-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095022347717.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //span[contains(text(),'会议申报会议室015')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095024592779.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@placeholder='请选择主办单位']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095026836919.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: (//div[@class='el-tree-node__content'])[10]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095029090005.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: (//button[@id='tree-selector-confirm'])[3]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095031352340.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-compere-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095033615661.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //div[@x-placement='bottom-start']//span[contains(text(),'范公司主管领导')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095035889982.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-department-leader-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095038167141.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //span[contains(text(),'陈部门领导')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095040429005.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-company-leader-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095042673478.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: (//span[contains(text(),'范公司主管领导')])[3]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095044926003.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //span[contains(text(),'提交')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095047256265.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //p[@class='el-message__content']、元素类型: getTips、元素值: 、预期结果: 请选择会议开始时间</div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095047417632.png" width="50%">
</div>
<div class="info">获取到的提示信息为:会议预定成功</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>获取到的提示信息为:会议预定成功</span>
</div>
<div class="info error-info">
Traceback:
File &quot;E:\GithubData\自动化\ubains-module-test\预定系统\cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py&quot;, line 90, in teststeps
CHECK_POINT(f&quot;获取到的提示信息为:{notify_text}&quot;, expented_result in notify_text)</div>
</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\项目定制\兰州中石化项目25-05-24\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
<span class="executetime">2025-06-25 09:50:49</span>
</div>
<div class="folder_body"></div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\</span>
<span class="executetime">2025-06-25 09:50:51</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
</div>
</div>
</div>
<div id="float_menu">
<div class="menu-item" onclick="document.querySelector(&quot;body&quot;).scrollIntoView()">页首</div>
<div class="menu-item" onclick="window.open(&quot;http://www.byhy.net/tut/auto/hytest/01&quot;, &quot;_blank&quot;); ">帮助</div>
<div class="menu-item" id="display_mode" onclick="toggle_folder_all_cases()">Summary</div>
<div class="error_jumper" display="block">
<div class="menu-item" onclick="previous_error()" title="上一个错误"></div>
<div class="menu-item" onclick="next_error()" title="下一个错误"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>兰州中石化项目测试报告</title>
<meta charset="UTF-8">
<style>body {
font-family: consolas, Verdana, sans-serif;
font-size: 1.2em;
color: #696e71;
display: grid;
grid-template-columns: 1fr 5rem;
}
.main_section {
width: 90%;
margin: 0 auto;
}
#float_menu{
position:fixed;
top:0;
right:0;
text-align: center;
}
#float_menu .menu-item {
cursor: pointer;
padding: .5em;
margin: .5em 0;
color: #c08580;
background-color: #f8f0ef;
font-size: 1.2em;
}
.result{
display: flex;
}
.result_table{
border-collapse: collapse;
border: 1px solid #f0e0e5;
width: 30em;
text-align: center;
font-size: 1.0em;
}
.result_table td{
border: 1px solid #f0e0e5;
padding: .3em;
}
.result_barchart{
width: 30em;
margin: 0 5em 0 5em;
}
.barchar_item{
margin: 2.5rem 0;
}
.barchart_barbox {
margin: 0.5em 0;
width: 100%;
background-color: #fff;
border: 1px solid #86c2dd;
border-radius: .2em;
}
.barchart_bar {
text-align: right;
height: 1.2rem;
}
.h3_button {
margin: 1.5em;
cursor: pointer;
color: #03a9f4;
}
.info
{
white-space:pre-wrap;
margin: .8em 1.5em;
}
.error-info
{
color: #a64747
}
.suite_dir {
margin: 1em .2em;
padding: .3em;
/* background-color: #dfeff6; */
border: 1px solid #bcd8e4;
}
.suite_file {
margin: 1em .2em;
padding: .3em;
border: 1px solid #bcd8e4;
}
.case {
margin: 1em .2em;
/* padding: .3em; */
border: 1px solid #e7d4d4;
}
.case_class_path{
margin: 0em 1em;
}
.folder_header {
padding: .2em .7em;
background-color: #fffaf9;
cursor: pointer;
}
.setup{
margin: .2em;
/* padding: .3em; */
/* border: 1px solid #e7d4d4; */
}
.teardown{
margin: .2em;
/* padding: .3em;*/
/* border: 1px solid #e7d4d4; */
}
.test_steps{
margin: .2em;
padding: .3em;
/* border: 1px solid #e7d4d4; */
}
.label {
display: inline-block;
padding: .1em .5em;
font-size: .88em;
letter-spacing: 1px;
white-space: nowrap;
color: #0d6ebc;
border-radius: .2em;
min-width: 5em;
margin-right: 2em;
font-family: consolas;
}
/* .suite_setup .label{
color: #219e26 ;
}
.suite_teardown .label{
color: #219e26;
} */
/* .case.pass .casename{
color: #329132 ;
} */
.case.pass .caselabel{
color: white;
background-color: #3b9e3f;
}
/* .case.fail .casename{
color: #a64747;
} */
.case.fail .caselabel{
color: white;
background-color: #a64747;
}
/* .case.abort .casename{
color: #953ab7;
} */
.case.abort .caselabel{
color: white;
background-color: #9c27b0;
}
.case_step {
margin: .8em;
}
.checkpoint_pass {
margin: .8em;
}
.checkpoint_fail {
margin: .8em;
}
.case_step .tag{
color: #2196f3;;
margin: .3em 1em .3em 0;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_pass .tag{
color: #009806;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_fail .tag{
color: #9c2020;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.screenshot {
border: 1px solid #86c2dd;
}
.executetime {
float: right;
}
/* 模态框内容 */
.modal-content {
margin: auto;
display: block;
width: 95%;
max-width: 700px;
max-height: 80vh; /* 设置最大高度为视口高度的80% */
object-fit: contain; /* 保持图片的宽高比 */
zoom: 3;
}
/* 模态框 */
.modal {
display: none; /* 隐藏 */
position: fixed; /* 固定位置 */
z-index: 1; /* 坐在顶部 */
padding-top: 40px; /* 在图片上方添加一些内边距 */
left: 0;
top: 0;
width: 100%; /* 宽度 */
height: 100%; /* 高度 */
overflow: auto; /* 启用滚动 */
background-color: rgb(0,0,0); /* 背景颜色 */
background-color: rgba(0,0,0,0.9); /* 黑色背景半透明 */
}
/* 关闭按钮 */
.close {
position: absolute; /* 定义元素的定位方式为绝对定位 */
top: 10px; /* 距离最近的已定位祖先元素顶部15像素 */
right: 30px; /* 距离最近的已定位祖先元素右侧35像素 */
color: #f1f1f1; /* 文本颜色为浅灰色 */
font-size: 15px; /* 字体大小为40像素 */
font-weight: bold; /* 字体加粗 */
transition: 0.3s; /* 过渡效果,0.3秒内完成 */
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
</style>
<script type="text/javascript">var FOLDER_ALL_CASES = false; // 是否为精简模式的标记
var ERROR_INFOS = []; // 错误信息列表
var current_error_idx = -1;
// 页面加载后执行的函数
window.addEventListener("load", function(){
// 所有 .folder_header 添加点击事件处理
let folderHeaderEles = document.querySelectorAll(".folder_header");
folderHeaderEles.forEach(function(ele) {
ele.addEventListener("click", function(event) {
let fb = event.target.closest('.folder_header').nextElementSibling;
fb.style.display = fb.style.display === 'none' ? 'block' : 'none';
});
});
// 找到所有的错误信息对象
ERROR_INFOS = document.querySelectorAll(".error-info");
// 获取所有图片元素
let images = document.querySelectorAll('.modal-image');
// 获取模态框元素
let modal = document.getElementById("imageModal");
// 获取模态框中的图片元素
let modalImg = document.getElementById("img01");
// 获取关闭按钮元素
let span = document.getElementsByClassName("close")[0];
// 为每个图片添加点击事件监听器
images.forEach(function(img) {
img.addEventListener("click", function() {
modal.style.display = "block"; // 显示模态框
modalImg.src = this.src; // 设置模态框中的图片为点击的图片
});
});
// 当点击关闭按钮时,隐藏模态框
span.onclick = function() {
modal.style.display = "none";
};
// 当点击模态框外区域时,隐藏模态框
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
});
function toggle_folder_all_cases(){
let eles = document.querySelectorAll(".folder_body");
FOLDER_ALL_CASES = !FOLDER_ALL_CASES;
document.getElementById('display_mode').innerHTML = FOLDER_ALL_CASES ? "Detail" : "Summary";
for (const ele of eles){
ele.style.display = FOLDER_ALL_CASES ? "none" : "block";
}
}
function previous_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx -= 1;
if (current_error_idx < 0)
current_error_idx = 0;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
function next_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx += 1;
if (current_error_idx > ERROR_INFOS.length - 1)
current_error_idx = ERROR_INFOS.length - 1;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
</script>
</head>
<body>
<div class="modal" id="imageModal">
<div>
<img class="modal-content" id="img01">
<span class="close">关闭</span>
</div>
</div>
<div class="main_section">
<h1 style="font-family: auto">兰州中石化项目测试报告</h1>
<h3>统计结果</h3>
<div class="result">
<table class="result_table">
<tbody>
<tr>
<td>hytest 版本</td>
<td>0.8.12</td>
</tr>
<tr>
<td>开始时间</td>
<td>2025/06/25 09:55:19</td>
</tr>
<tr>
<td>结束时间</td>
<td>2025/06/25 09:55:58</td>
</tr>
<tr>
<td>耗时</td>
<td>39.650 秒</td>
</tr>
<tr>
<td>预备执行用例数量</td>
<td>1</td>
</tr>
<tr>
<td>实际执用例行数量</td>
<td>1</td>
</tr>
<tr>
<td>通过</td>
<td>0</td>
</tr>
<tr>
<td>失败</td>
<td style="color:red">1</td>
</tr>
<tr>
<td>异常</td>
<td style="">0</td>
</tr>
<tr>
<td>阻塞</td>
<td style="">0</td>
</tr>
<tr>
<td>套件初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>套件清除 失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例清除 失败</td>
<td style="">0</td>
</tr>
</tbody>
</table>
<div class="result_barchart">
<div class="barchar_item">
<span>用例通过 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #04AA6D;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例失败 100% : 1 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 100.0%; background-color: #bb4069;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例异常 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #9c27b0;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例阻塞 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #dcbdbd;"></div>
</div>
</div>
</div>
</div>
<div style="margin-top:2em">
<h3 style="display:inline">执行日志</h3>
</div>
<div class="exec_log">
<div class="suite_dir" id="suite_dir cases\">
<div>
<span class="label">进入目录</span>
<span>cases\</span>
</div>
</div>
<div class="suite_dir" id="suite_dir cases\项目定制\兰州中石化项目25-05-24\">
<div>
<span class="label">进入目录</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
</div>
<div class="suite_setup setup" id="suite_setup setup cases\项目定制\兰州中石化项目25-05-24\">
<div class="folder_header">
<span class="label">套件初始化</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
<span class="executetime">2025-06-25 09:55:19</span>
</div>
<div class="folder_body">
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>初始化浏览器</span>
</div>
<div class="info">'----------' 正在初始化浏览器 '----------'</div>
<div class="info">'----------' 浏览器初始化完成 '----------'</div>
<div class="info">输入用户名:admin</div>
<div class="info">输入密码:Ubains@4321</div>
<div class="info">输入验证码:csba</div>
<div class="info">点击登录按钮</div>
</div>
</div>
</div>
<div class="suite_file" id="suite_file cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py">
<div>
<span class="label">进入文件</span>
<span>cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py</span>
</div>
<div class="case fail" id="case_00000001">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">会议申报测试015</span>
<span class="executetime">2025-06-25 09:55:26</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py::LanzhouSinopecProject</span>
<div class="test_steps" id="test_steps 会议申报测试015">
<span class="label">测试步骤</span>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //div[@id='CreateMeeting']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095528577792.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: id、元素定位值: create-meeting-name-input、元素类型: input、元素值: 会议申报测试015、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095530955095.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-start-time-datepicker']、元素类型: input、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095533292956.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //button[@class='el-button el-picker-panel__link-btn el-button--default el-button--mini is-plain']//span[contains(text(),'确定')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095535589981.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //span[contains(text(),'提交')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095537819491.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //p[@class='el-message__content']、元素类型: getTips、元素值: 、预期结果: 请选择会议开始时间</div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095538033439.png" width="50%">
</div>
<div class="info">获取到的提示信息为:请选择会议地点</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>获取到的提示信息为:请选择会议地点</span>
</div>
<div class="info error-info">
Traceback:
File &quot;E:\GithubData\自动化\ubains-module-test\预定系统\cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py&quot;, line 90, in teststeps
CHECK_POINT(f&quot;获取到的提示信息为:{notify_text}&quot;, expented_result in notify_text)</div>
</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\项目定制\兰州中石化项目25-05-24\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
<span class="executetime">2025-06-25 09:55:40</span>
</div>
<div class="folder_body"></div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\</span>
<span class="executetime">2025-06-25 09:55:42</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
</div>
</div>
</div>
<div id="float_menu">
<div class="menu-item" onclick="document.querySelector(&quot;body&quot;).scrollIntoView()">页首</div>
<div class="menu-item" onclick="window.open(&quot;http://www.byhy.net/tut/auto/hytest/01&quot;, &quot;_blank&quot;); ">帮助</div>
<div class="menu-item" id="display_mode" onclick="toggle_folder_all_cases()">Summary</div>
<div class="error_jumper" display="block">
<div class="menu-item" onclick="previous_error()" title="上一个错误"></div>
<div class="menu-item" onclick="next_error()" title="下一个错误"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>兰州中石化项目测试报告</title>
<meta charset="UTF-8">
<style>body {
font-family: consolas, Verdana, sans-serif;
font-size: 1.2em;
color: #696e71;
display: grid;
grid-template-columns: 1fr 5rem;
}
.main_section {
width: 90%;
margin: 0 auto;
}
#float_menu{
position:fixed;
top:0;
right:0;
text-align: center;
}
#float_menu .menu-item {
cursor: pointer;
padding: .5em;
margin: .5em 0;
color: #c08580;
background-color: #f8f0ef;
font-size: 1.2em;
}
.result{
display: flex;
}
.result_table{
border-collapse: collapse;
border: 1px solid #f0e0e5;
width: 30em;
text-align: center;
font-size: 1.0em;
}
.result_table td{
border: 1px solid #f0e0e5;
padding: .3em;
}
.result_barchart{
width: 30em;
margin: 0 5em 0 5em;
}
.barchar_item{
margin: 2.5rem 0;
}
.barchart_barbox {
margin: 0.5em 0;
width: 100%;
background-color: #fff;
border: 1px solid #86c2dd;
border-radius: .2em;
}
.barchart_bar {
text-align: right;
height: 1.2rem;
}
.h3_button {
margin: 1.5em;
cursor: pointer;
color: #03a9f4;
}
.info
{
white-space:pre-wrap;
margin: .8em 1.5em;
}
.error-info
{
color: #a64747
}
.suite_dir {
margin: 1em .2em;
padding: .3em;
/* background-color: #dfeff6; */
border: 1px solid #bcd8e4;
}
.suite_file {
margin: 1em .2em;
padding: .3em;
border: 1px solid #bcd8e4;
}
.case {
margin: 1em .2em;
/* padding: .3em; */
border: 1px solid #e7d4d4;
}
.case_class_path{
margin: 0em 1em;
}
.folder_header {
padding: .2em .7em;
background-color: #fffaf9;
cursor: pointer;
}
.setup{
margin: .2em;
/* padding: .3em; */
/* border: 1px solid #e7d4d4; */
}
.teardown{
margin: .2em;
/* padding: .3em;*/
/* border: 1px solid #e7d4d4; */
}
.test_steps{
margin: .2em;
padding: .3em;
/* border: 1px solid #e7d4d4; */
}
.label {
display: inline-block;
padding: .1em .5em;
font-size: .88em;
letter-spacing: 1px;
white-space: nowrap;
color: #0d6ebc;
border-radius: .2em;
min-width: 5em;
margin-right: 2em;
font-family: consolas;
}
/* .suite_setup .label{
color: #219e26 ;
}
.suite_teardown .label{
color: #219e26;
} */
/* .case.pass .casename{
color: #329132 ;
} */
.case.pass .caselabel{
color: white;
background-color: #3b9e3f;
}
/* .case.fail .casename{
color: #a64747;
} */
.case.fail .caselabel{
color: white;
background-color: #a64747;
}
/* .case.abort .casename{
color: #953ab7;
} */
.case.abort .caselabel{
color: white;
background-color: #9c27b0;
}
.case_step {
margin: .8em;
}
.checkpoint_pass {
margin: .8em;
}
.checkpoint_fail {
margin: .8em;
}
.case_step .tag{
color: #2196f3;;
margin: .3em 1em .3em 0;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_pass .tag{
color: #009806;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_fail .tag{
color: #9c2020;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.screenshot {
border: 1px solid #86c2dd;
}
.executetime {
float: right;
}
/* 模态框内容 */
.modal-content {
margin: auto;
display: block;
width: 95%;
max-width: 700px;
max-height: 80vh; /* 设置最大高度为视口高度的80% */
object-fit: contain; /* 保持图片的宽高比 */
zoom: 3;
}
/* 模态框 */
.modal {
display: none; /* 隐藏 */
position: fixed; /* 固定位置 */
z-index: 1; /* 坐在顶部 */
padding-top: 40px; /* 在图片上方添加一些内边距 */
left: 0;
top: 0;
width: 100%; /* 宽度 */
height: 100%; /* 高度 */
overflow: auto; /* 启用滚动 */
background-color: rgb(0,0,0); /* 背景颜色 */
background-color: rgba(0,0,0,0.9); /* 黑色背景半透明 */
}
/* 关闭按钮 */
.close {
position: absolute; /* 定义元素的定位方式为绝对定位 */
top: 10px; /* 距离最近的已定位祖先元素顶部15像素 */
right: 30px; /* 距离最近的已定位祖先元素右侧35像素 */
color: #f1f1f1; /* 文本颜色为浅灰色 */
font-size: 15px; /* 字体大小为40像素 */
font-weight: bold; /* 字体加粗 */
transition: 0.3s; /* 过渡效果,0.3秒内完成 */
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
</style>
<script type="text/javascript">var FOLDER_ALL_CASES = false; // 是否为精简模式的标记
var ERROR_INFOS = []; // 错误信息列表
var current_error_idx = -1;
// 页面加载后执行的函数
window.addEventListener("load", function(){
// 所有 .folder_header 添加点击事件处理
let folderHeaderEles = document.querySelectorAll(".folder_header");
folderHeaderEles.forEach(function(ele) {
ele.addEventListener("click", function(event) {
let fb = event.target.closest('.folder_header').nextElementSibling;
fb.style.display = fb.style.display === 'none' ? 'block' : 'none';
});
});
// 找到所有的错误信息对象
ERROR_INFOS = document.querySelectorAll(".error-info");
// 获取所有图片元素
let images = document.querySelectorAll('.modal-image');
// 获取模态框元素
let modal = document.getElementById("imageModal");
// 获取模态框中的图片元素
let modalImg = document.getElementById("img01");
// 获取关闭按钮元素
let span = document.getElementsByClassName("close")[0];
// 为每个图片添加点击事件监听器
images.forEach(function(img) {
img.addEventListener("click", function() {
modal.style.display = "block"; // 显示模态框
modalImg.src = this.src; // 设置模态框中的图片为点击的图片
});
});
// 当点击关闭按钮时,隐藏模态框
span.onclick = function() {
modal.style.display = "none";
};
// 当点击模态框外区域时,隐藏模态框
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
});
function toggle_folder_all_cases(){
let eles = document.querySelectorAll(".folder_body");
FOLDER_ALL_CASES = !FOLDER_ALL_CASES;
document.getElementById('display_mode').innerHTML = FOLDER_ALL_CASES ? "Detail" : "Summary";
for (const ele of eles){
ele.style.display = FOLDER_ALL_CASES ? "none" : "block";
}
}
function previous_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx -= 1;
if (current_error_idx < 0)
current_error_idx = 0;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
function next_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx += 1;
if (current_error_idx > ERROR_INFOS.length - 1)
current_error_idx = ERROR_INFOS.length - 1;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
</script>
</head>
<body>
<div class="modal" id="imageModal">
<div>
<img class="modal-content" id="img01">
<span class="close">关闭</span>
</div>
</div>
<div class="main_section">
<h1 style="font-family: auto">兰州中石化项目测试报告</h1>
<h3>统计结果</h3>
<div class="result">
<table class="result_table">
<tbody>
<tr>
<td>hytest 版本</td>
<td>0.8.12</td>
</tr>
<tr>
<td>开始时间</td>
<td>2025/06/25 09:57:31</td>
</tr>
<tr>
<td>结束时间</td>
<td>2025/06/25 09:58:43</td>
</tr>
<tr>
<td>耗时</td>
<td>71.965 秒</td>
</tr>
<tr>
<td>预备执行用例数量</td>
<td>1</td>
</tr>
<tr>
<td>实际执用例行数量</td>
<td>1</td>
</tr>
<tr>
<td>通过</td>
<td>0</td>
</tr>
<tr>
<td>失败</td>
<td style="color:red">1</td>
</tr>
<tr>
<td>异常</td>
<td style="">0</td>
</tr>
<tr>
<td>阻塞</td>
<td style="">0</td>
</tr>
<tr>
<td>套件初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>套件清除 失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例清除 失败</td>
<td style="">0</td>
</tr>
</tbody>
</table>
<div class="result_barchart">
<div class="barchar_item">
<span>用例通过 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #04AA6D;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例失败 100% : 1 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 100.0%; background-color: #bb4069;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例异常 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #9c27b0;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例阻塞 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #dcbdbd;"></div>
</div>
</div>
</div>
</div>
<div style="margin-top:2em">
<h3 style="display:inline">执行日志</h3>
</div>
<div class="exec_log">
<div class="suite_dir" id="suite_dir cases\">
<div>
<span class="label">进入目录</span>
<span>cases\</span>
</div>
</div>
<div class="suite_dir" id="suite_dir cases\项目定制\兰州中石化项目25-05-24\">
<div>
<span class="label">进入目录</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
</div>
<div class="suite_setup setup" id="suite_setup setup cases\项目定制\兰州中石化项目25-05-24\">
<div class="folder_header">
<span class="label">套件初始化</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
<span class="executetime">2025-06-25 09:57:31</span>
</div>
<div class="folder_body">
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>初始化浏览器</span>
</div>
<div class="info">'----------' 正在初始化浏览器 '----------'</div>
<div class="info">'----------' 浏览器初始化完成 '----------'</div>
<div class="info">输入用户名:admin</div>
<div class="info">输入密码:Ubains@4321</div>
<div class="info">输入验证码:csba</div>
<div class="info">点击登录按钮</div>
</div>
</div>
</div>
<div class="suite_file" id="suite_file cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py">
<div>
<span class="label">进入文件</span>
<span>cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py</span>
</div>
<div class="case fail" id="case_00000001">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">会议申报测试028</span>
<span class="executetime">2025-06-25 09:57:39</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py::LanzhouSinopecProject</span>
<div class="test_steps" id="test_steps 会议申报测试028">
<span class="label">测试步骤</span>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //div[@id='CreateMeeting']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095741720958.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: id、元素定位值: create-meeting-name-input、元素类型: input、元素值: 会议申报测试028、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095744043545.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-start-time-datepicker']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095746359900.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@placeholder='选择时间']、元素类型: input、元素值: 12:00、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095748703711.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //button[@class='el-button el-picker-panel__link-btn el-button--default el-button--mini is-plain']//span[contains(text(),'确定')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095751016332.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-location-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095753296287.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //span[contains(text(),'会议申报会议室018')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095755578755.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-type-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095757841768.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //span[contains(text(),'综合会议')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095800107234.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@placeholder='请选择主办单位']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095802360157.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: (//div[@class='el-tree-node__content'])[10]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095804656121.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: (//button[@id='tree-selector-confirm'])[3]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095806903383.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-compere-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095809200963.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //div[@x-placement='bottom-start']//span[contains(text(),'范公司主管领导')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095811455822.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-department-leader-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095813728931.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //span[contains(text(),'陈部门领导')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095815976218.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //input[@id='create-meeting-company-leader-select']、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095818244091.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: (//span[contains(text(),'范公司主管领导')])[3]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095820508810.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //span[contains(text(),'提交')]、元素类型: click、元素值: 、预期结果: </div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095822774919.png" width="75">
</div>
<div class="info">页面: ConferenceDeclaration、元素定位类型: xpath、元素定位值: //p[@class='el-message__content']、元素类型: getTips、元素值: 、预期结果: 会议预定成功</div>
<div>
<img class="modal-image screenshot" src="imgs/20250625095822975355.png" width="50%">
</div>
<div class="info">获取到的提示信息为:该时间段已有会议,请重新选择</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>获取到的提示信息为:该时间段已有会议,请重新选择</span>
</div>
<div class="info error-info">
Traceback:
File &quot;E:\GithubData\自动化\ubains-module-test\预定系统\cases\项目定制\兰州中石化项目25-05-24\兰州中石化测试.py&quot;, line 90, in teststeps
CHECK_POINT(f&quot;获取到的提示信息为:{notify_text}&quot;, expented_result in notify_text)</div>
</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\项目定制\兰州中石化项目25-05-24\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\项目定制\兰州中石化项目25-05-24\</span>
<span class="executetime">2025-06-25 09:58:25</span>
</div>
<div class="folder_body"></div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\</span>
<span class="executetime">2025-06-25 09:58:27</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
</div>
</div>
</div>
<div id="float_menu">
<div class="menu-item" onclick="document.querySelector(&quot;body&quot;).scrollIntoView()">页首</div>
<div class="menu-item" onclick="window.open(&quot;http://www.byhy.net/tut/auto/hytest/01&quot;, &quot;_blank&quot;); ">帮助</div>
<div class="menu-item" id="display_mode" onclick="toggle_folder_all_cases()">Summary</div>
<div class="error_jumper" display="block">
<div class="menu-item" onclick="previous_error()" title="上一个错误"></div>
<div class="menu-item" onclick="next_error()" title="下一个错误"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>桌牌系统测试报告</title>
<meta charset="UTF-8">
<style>body {
font-family: consolas, Verdana, sans-serif;
font-size: 1.2em;
color: #696e71;
display: grid;
grid-template-columns: 1fr 5rem;
}
.main_section {
width: 90%;
margin: 0 auto;
}
#float_menu{
position:fixed;
top:0;
right:0;
text-align: center;
}
#float_menu .menu-item {
cursor: pointer;
padding: .5em;
margin: .5em 0;
color: #c08580;
background-color: #f8f0ef;
font-size: 1.2em;
}
.result{
display: flex;
}
.result_table{
border-collapse: collapse;
border: 1px solid #f0e0e5;
width: 30em;
text-align: center;
font-size: 1.0em;
}
.result_table td{
border: 1px solid #f0e0e5;
padding: .3em;
}
.result_barchart{
width: 30em;
margin: 0 5em 0 5em;
}
.barchar_item{
margin: 2.5rem 0;
}
.barchart_barbox {
margin: 0.5em 0;
width: 100%;
background-color: #fff;
border: 1px solid #86c2dd;
border-radius: .2em;
}
.barchart_bar {
text-align: right;
height: 1.2rem;
}
.h3_button {
margin: 1.5em;
cursor: pointer;
color: #03a9f4;
}
.info
{
white-space:pre-wrap;
margin: .8em 1.5em;
}
.error-info
{
color: #a64747
}
.suite_dir {
margin: 1em .2em;
padding: .3em;
/* background-color: #dfeff6; */
border: 1px solid #bcd8e4;
}
.suite_file {
margin: 1em .2em;
padding: .3em;
border: 1px solid #bcd8e4;
}
.case {
margin: 1em .2em;
/* padding: .3em; */
border: 1px solid #e7d4d4;
}
.case_class_path{
margin: 0em 1em;
}
.folder_header {
padding: .2em .7em;
background-color: #fffaf9;
cursor: pointer;
}
.setup{
margin: .2em;
/* padding: .3em; */
/* border: 1px solid #e7d4d4; */
}
.teardown{
margin: .2em;
/* padding: .3em;*/
/* border: 1px solid #e7d4d4; */
}
.test_steps{
margin: .2em;
padding: .3em;
/* border: 1px solid #e7d4d4; */
}
.label {
display: inline-block;
padding: .1em .5em;
font-size: .88em;
letter-spacing: 1px;
white-space: nowrap;
color: #0d6ebc;
border-radius: .2em;
min-width: 5em;
margin-right: 2em;
font-family: consolas;
}
/* .suite_setup .label{
color: #219e26 ;
}
.suite_teardown .label{
color: #219e26;
} */
/* .case.pass .casename{
color: #329132 ;
} */
.case.pass .caselabel{
color: white;
background-color: #3b9e3f;
}
/* .case.fail .casename{
color: #a64747;
} */
.case.fail .caselabel{
color: white;
background-color: #a64747;
}
/* .case.abort .casename{
color: #953ab7;
} */
.case.abort .caselabel{
color: white;
background-color: #9c27b0;
}
.case_step {
margin: .8em;
}
.checkpoint_pass {
margin: .8em;
}
.checkpoint_fail {
margin: .8em;
}
.case_step .tag{
color: #2196f3;;
margin: .3em 1em .3em 0;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_pass .tag{
color: #009806;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_fail .tag{
color: #9c2020;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.screenshot {
border: 1px solid #86c2dd;
}
.executetime {
float: right;
}
/* 模态框内容 */
.modal-content {
margin: auto;
display: block;
width: 95%;
max-width: 700px;
max-height: 80vh; /* 设置最大高度为视口高度的80% */
object-fit: contain; /* 保持图片的宽高比 */
zoom: 3;
}
/* 模态框 */
.modal {
display: none; /* 隐藏 */
position: fixed; /* 固定位置 */
z-index: 1; /* 坐在顶部 */
padding-top: 40px; /* 在图片上方添加一些内边距 */
left: 0;
top: 0;
width: 100%; /* 宽度 */
height: 100%; /* 高度 */
overflow: auto; /* 启用滚动 */
background-color: rgb(0,0,0); /* 背景颜色 */
background-color: rgba(0,0,0,0.9); /* 黑色背景半透明 */
}
/* 关闭按钮 */
.close {
position: absolute; /* 定义元素的定位方式为绝对定位 */
top: 10px; /* 距离最近的已定位祖先元素顶部15像素 */
right: 30px; /* 距离最近的已定位祖先元素右侧35像素 */
color: #f1f1f1; /* 文本颜色为浅灰色 */
font-size: 15px; /* 字体大小为40像素 */
font-weight: bold; /* 字体加粗 */
transition: 0.3s; /* 过渡效果,0.3秒内完成 */
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
</style>
<script type="text/javascript">var FOLDER_ALL_CASES = false; // 是否为精简模式的标记
var ERROR_INFOS = []; // 错误信息列表
var current_error_idx = -1;
// 页面加载后执行的函数
window.addEventListener("load", function(){
// 所有 .folder_header 添加点击事件处理
let folderHeaderEles = document.querySelectorAll(".folder_header");
folderHeaderEles.forEach(function(ele) {
ele.addEventListener("click", function(event) {
let fb = event.target.closest('.folder_header').nextElementSibling;
fb.style.display = fb.style.display === 'none' ? 'block' : 'none';
});
});
// 找到所有的错误信息对象
ERROR_INFOS = document.querySelectorAll(".error-info");
// 获取所有图片元素
let images = document.querySelectorAll('.modal-image');
// 获取模态框元素
let modal = document.getElementById("imageModal");
// 获取模态框中的图片元素
let modalImg = document.getElementById("img01");
// 获取关闭按钮元素
let span = document.getElementsByClassName("close")[0];
// 为每个图片添加点击事件监听器
images.forEach(function(img) {
img.addEventListener("click", function() {
modal.style.display = "block"; // 显示模态框
modalImg.src = this.src; // 设置模态框中的图片为点击的图片
});
});
// 当点击关闭按钮时,隐藏模态框
span.onclick = function() {
modal.style.display = "none";
};
// 当点击模态框外区域时,隐藏模态框
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
});
function toggle_folder_all_cases(){
let eles = document.querySelectorAll(".folder_body");
FOLDER_ALL_CASES = !FOLDER_ALL_CASES;
document.getElementById('display_mode').innerHTML = FOLDER_ALL_CASES ? "Detail" : "Summary";
for (const ele of eles){
ele.style.display = FOLDER_ALL_CASES ? "none" : "block";
}
}
function previous_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx -= 1;
if (current_error_idx < 0)
current_error_idx = 0;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
function next_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx += 1;
if (current_error_idx > ERROR_INFOS.length - 1)
current_error_idx = ERROR_INFOS.length - 1;
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
</script>
</head>
<body>
<div class="modal" id="imageModal">
<div>
<img class="modal-content" id="img01">
<span class="close">关闭</span>
</div>
</div>
<div class="main_section">
<h1 style="font-family: auto">桌牌系统测试报告</h1>
<h3>统计结果</h3>
<div class="result">
<table class="result_table">
<tbody>
<tr>
<td>hytest 版本</td>
<td>0.8.12</td>
</tr>
<tr>
<td>开始时间</td>
<td>2025/06/25 10:02:53</td>
</tr>
<tr>
<td>结束时间</td>
<td>2025/06/25 10:03:30</td>
</tr>
<tr>
<td>耗时</td>
<td>36.850 秒</td>
</tr>
<tr>
<td>预备执行用例数量</td>
<td>1</td>
</tr>
<tr>
<td>实际执用例行数量</td>
<td>1</td>
</tr>
<tr>
<td>通过</td>
<td>1</td>
</tr>
<tr>
<td>失败</td>
<td style="">0</td>
</tr>
<tr>
<td>异常</td>
<td style="">0</td>
</tr>
<tr>
<td>阻塞</td>
<td style="">0</td>
</tr>
<tr>
<td>套件初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>套件清除 失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例清除 失败</td>
<td style="">0</td>
</tr>
</tbody>
</table>
<div class="result_barchart">
<div class="barchar_item">
<span>用例通过 100% : 1 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 100.0%; background-color: #04AA6D;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例失败 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #bb4069;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例异常 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #9c27b0;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例阻塞 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #dcbdbd;"></div>
</div>
</div>
</div>
</div>
<div style="margin-top:2em">
<h3 style="display:inline">执行日志</h3>
</div>
<div class="exec_log">
<div class="suite_dir" id="suite_dir cases\">
<div>
<span class="label">进入目录</span>
<span>cases\</span>
</div>
</div>
<div class="suite_dir" id="suite_dir cases\展厅巡检\10桌牌系统\">
<div>
<span class="label">进入目录</span>
<span>cases\展厅巡检\10桌牌系统\</span>
</div>
<div class="suite_setup setup" id="suite_setup setup cases\展厅巡检\10桌牌系统\">
<div class="folder_header">
<span class="label">套件初始化</span>
<span>cases\展厅巡检\10桌牌系统\</span>
<span class="executetime">2025-06-25 10:02:53</span>
</div>
<div class="folder_body">
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>初始化浏览器</span>
</div>
<div class="info">'----------' 正在初始化浏览器 '----------'</div>
<div class="info">'----------' 浏览器初始化完成 '----------'</div>
<div class="info">输入用户名:Test02</div>
<div class="info">输入密码:ubains@123</div>
<div class="info">输入验证码:csba</div>
<div class="info">点击登录按钮</div>
</div>
</div>
</div>
<div class="suite_file" id="suite_file cases\展厅巡检\10桌牌系统\桌牌系统巡检.py">
<div>
<span class="label">进入文件</span>
<span>cases\展厅巡检\10桌牌系统\桌牌系统巡检.py</span>
</div>
<div class="case pass" id="case_00000001">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">MeetingTableCard</span>
<span class="executetime">2025-06-25 10:02:57</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\展厅巡检\10桌牌系统\桌牌系统巡检.py::MeetingTableCard</span>
<div class="test_steps" id="test_steps MeetingTableCard">
<span class="label">测试步骤</span>
<div class="info">进入桌牌系统</div>
<div>
<img class="modal-image screenshot" src="imgs/Exhibit_Inspect/Meeting_TableCard/进入桌牌系统.png" width="75%">
</div>
<div class="info">进入桌牌投图</div>
<div>
<img class="modal-image screenshot" src="imgs/Exhibit_Inspect/Meeting_TableCard/进入桌牌投图.png" width="75%">
</div>
</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\展厅巡检\10桌牌系统\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\展厅巡检\10桌牌系统\</span>
<span class="executetime">2025-06-25 10:03:11</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\</span>
<span class="executetime">2025-06-25 10:03:13</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
</div>
</div>
</div>
<div id="float_menu">
<div class="menu-item" onclick="document.querySelector(&quot;body&quot;).scrollIntoView()">页首</div>
<div class="menu-item" onclick="window.open(&quot;http://www.byhy.net/tut/auto/hytest/01&quot;, &quot;_blank&quot;); ">帮助</div>
<div class="menu-item" id="display_mode" onclick="toggle_folder_all_cases()">Summary</div>
<div class="error_jumper" display="none">
<div class="menu-item" onclick="previous_error()" title="上一个错误"></div>
<div class="menu-item" onclick="next_error()" title="下一个错误"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论